一、简述
1、组件Component是自定义封装代码的功能。在前端开发过程中,经常出现多个网页的功能是重复的,而且很多不同的页面之间,也存在同样的功能。
2、而在网页中实现一个功能,需要使用html定义功能的内容结构,使用css声明功能的外观样式,还要使用js来定义功能的特效,因此就产生了把一个功能相关的html、css和js代码封装在一起组成一个整体的代码块的模式,就称之为“组件”。
3、组件就是一个html网页中的功能,一般就是一个标签,标签中有自己的html内容结构,css样式和js特效。这样,前端人员就可以在组件化开发时,只需要书写一次代码,随处引入即可使用。
二、普通组件
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <script src="vue.min.js"></script> </head> <body> <div id="id1"> <demo1></demo1> <demo1></demo1> <!-- 可重复使用 --> </div> <!------------------------------------> <script> // 新建组件对象,第一个参数为组件名,后续以该命名的标签引用组件 Vue.component('demo1', { // 组件的html代码 template: `<div> <button @click="num--">-</button> <input type="text" v-model="num"> <button @click="num++">+</button> </div>`, // 组件中用到的数据如下书写 data: function () { return { num: 0 } }, // 组件中其他属性跟vue对象书写方式一致 watch: { num: function () { if (this.num < 0) { this.num = 0 } } } }) let vueObj = new Vue({ el: '#id1', data: {} }) </script> </body> </html>
三、vue-cli安装
1、要使用单文件组件需要提前安装准备一些组件开发工具,一般情况下,单文件组件运行在自动化工具vue-cli中,它可以帮我们把单文件组件编译成普通的js代码。所以我们需要在电脑先安装搭建vue-CLI工具。
2、官网:https://cli.vuejs.org/zh/。
3、node.js:要使用vue-cli,需要先安装node.js,node.js是一个新的后端语言,它的语法和js类似,所以可以说它是属于前端的后端语言。
4、node.js的版本有两大分支,待node.js安装成功,用 node -v 查看当前node.js的版本号。
①官方发布的版本:0.xx.xx。
②社区发布的版本:xx.xx.x。
5、后端语言和前端语言的区别:
①运行环境:后端语言一般运行在服务器端,前端语言运行在客户端浏览器上。
②功能:后端语言可以操作文件,可以读写数据库,前端语言不能操作文件,不能读写数据库。
6、nvm/nvm-windows:用于管理同一台电脑中多个node.js的版本。
7、nvm与node.js的介绍与安装:
①
四、通过vue-cli生成项目目录
1、简介:使用vue-cli自动化工具可以快速搭建单页应用项目目录,该工具为现代化的前端开发工作流提供了开箱即用的构建配置。只需几分钟即可创建并启动一个带热重载、保存时静态检查以及可用于生产环境的构建配置的项目。
2、创建启动流程:
①vue init webpack 项目目录名:生成一个基于webpack模板的新项目。
②cd 项目目录路径:切换到项目目录下。
③npm run dev:启动node提供的测试http服务器。
④ctrl+c:停止服务。
3、项目目录结构:
①src:主开发目录,要开发的单文件组件全部在这个目录下的components目录下。
②static:静态资源目录,所有的css,js,图片等资源文件放在这个文件夹。
③dist:项目打包发布文件夹,最后要上线单文件项目文件都在这个文件夹中,初始并未创建,后面打包项目,让项目中的vue组件经过编译变成js代码以后,dist文件夹就会出现了。
④node_modules:是node的依赖包目录。
⑤config:配置目录。
⑥build:项目打包时依赖的目录。
⑦src/router:路由,后面需要我们在使用router路由的时候再自己创建。
4、vue项目的执行流程:
①主文件index.html ===> 引入 ===>
②src文件夹中的main.js ===> 导入 ===>
③src文件夹中的顶级单文件组件App.vue ===> 组件嵌套/路由引用 ===>
④components文件夹中的其他单文件组件。
五、单文件组件的基本使用
1、普通组件与单文件组件:
①普通组件的缺点:
--- html代码是作为js的字符串进行编写,所以组装和开发的时候不易理解,而且没有高亮效果。
--- 普通组件用在小项目中非常合适,但是复杂的大项目中,如果把更多的组件放在html文件中,那么维护成本就会变得非常昂贵。
--- 普通组件只是整合了js和html,但是css代码被剥离出去了。使用的时候的时候不好处理。
②单文件组件:将一个组件相关的html结构,css样式,以及交互的js代码从html文件中剥离出来,合成一个文件,这种文件就是单文件组件,相当于一个组件具有了结构、表现和行为的完整功能,方便组件之间随意组合以及组件的重用,这种文件的扩展名为“.vue”,比如:"HelloWorld.vue"。
2、创建单文件组件:新建vue文件 ===> 在vue文件中编辑三个标签:编写视图、vm对象和css样式代码。
①<template></template>中:新建一个唯一外层div,html代码都在这个div中书写。
②<script></script>中的export default { name: 'Too', }中:编写vm对象代码,必须要有export default声明,才可以导出给外界使用。
③<style scoped></style>中:编写css样式代码,声明了scoped,才表示当前组件私有。
3、在App.vue中导入并引用单文件组件的步骤:
①<script></script>中:import HelloWorld from './components/Too'。
②vm对象的components属性中:添加Too。
③视图中以<Too></Too>引用该单文件组件。
六、单文件组件的嵌套
1、简述:有时候开发vue项目时,一个页面也可以算是一个大组件,这个大组件是由若干个小组件组成的,此时,大组件就是父组件,小组件就是子组件,父组件调用了子组件。
2、例如,在components目录下有一个大组件Father.vue,可以在同级建一个FatherSon目录用于存放Father.vue需要调用的子组件,随后,按照调用组件三步走即可在父组件中调用子组件了。
七、嵌套组件之间传递数据
1、父组件传给子组件:
①实例:
<!-- 这是父组件 --> <template> <div> <!-- 在子组件的标签属性内自定义属性用于传递数据 --> <!-- 传递变量需要加冒号,直接传递字符串则不需要加冒号 --> <Son :from_father="to_son" from_father_2="父传子的字符串"></Son> </div> </template> <script> import Son from "./FatherSon/Son"; export default { name: "Father", data: function () { return { to_son: '父传子的数据' } }, components: { Son } } </script> <style scoped> </style>
<!-- 这是子组件 --> <template> <div> <!-- 子组件接收到的父组件传递来的数据,可以如data属性中的变量一样使用 --> <p>子组件处:{{from_father}}</p> <p>子组件处:{{from_father_2}}</p> </div> </template> <script> export default { name: "Son", data: function () { return {} }, // 子组件用于接收父组件传递来数据的属性,填入父组件自定义的标签属性名,后续以该名字为变量名使用 props: [ 'from_father', 'from_father_2' ] } </script> <style scoped> </style>
②注意事项:
--- 传递数据是变量,这种数据称之为"动态数据传递",需要加冒号。
--- 传递数据不是变量,这种数据称之为"静态数据传递",不需要加冒号。
--- --- 父组件中修改了数据,在子组件中会被同步修改,但是,子组件中的数据修改了,是不是影响到父组件中的数据,这也被称为"单向数据流"。
2、子组件传给父组件:
①实例:
<!-- 这是父组件 --> <template> <div> <!-- 在子组件的标签属性内自定义属性用于传递数据 --> <!-- 传递变量需要加冒号,直接传递字符串则不需要加冒号 --> <!-- 在子组件的标签属性内用@子组件传来的事件名接收子组件传来的事件与数据,并传给自己的方法属性 --> <Son :from_father="to_son" from_father_2="父传子的字符串" @to_father_event="from_son_event" @to_father_event_2="from_son_event_2"></Son> <p>父组件处:{{from_son_data}}</p> <p>父组件处:{{from_son_str}}</p> <p>父组件处:{{from_son_data_2}}</p> <p>父组件处:{{from_son_str_2}}</p> </div> </template> <script> import Son from "./FatherSon/Son"; export default { name: "Father", data: function () { return { to_son: '父传子的数据', from_son_data: null, from_son_data_2: null, from_son_str: null, from_son_str_2: null, } }, components: { Son }, methods: { // 接收了子组件传来的事件与数据的方法属性可以自定义后续逻辑 from_son_event: function (v1, v2) { this.from_son_data = v1 this.from_son_str = v2 }, from_son_event_2: function (v1, v2) { this.from_son_data_2 = v1 this.from_son_str_2 = v2 } } } </script> <style scoped> </style>
<!-- 这是子组件 --> <template> <div> <!-- 子组件接收到的父组件传递来的数据,可以如data属性中的变量一样使用 --> <p>子组件处:{{from_father}}</p> <p>子组件处:{{from_father_2}}</p> <p>按下给父组件递的值会变化: <button @click="num_add">点击</button> </p> </div> </template> <script> export default { name: "Son", data: function () { return { to_father: '子传给父的数据', to_father_2: 0 } }, // 子组件用于接收父组件传递来数据的属性,填入父组件自定义的标签属性名,后续以该名字为变量名使用 props: [ 'from_father', 'from_father_2' ], created() { // 子组件通过该方法将事件与数据传给父组件 this.$emit('to_father_event', this.to_father, '子传父的字符串1') }, methods: { num_add: function () { this.to_father_2++ this.$emit('to_father_event_2', this.to_father_2, '子传父的字符串2') } } } </script> <style scoped> </style>
八、组件中使用axios
1、简述:默认情况下,vue项目中并没有对axios包的支持,所以需要先使用npm安装包:npm install axios。
2、实例:
// The Vue build version to load with the `import` command // (runtime-only or standalone) has been set in webpack.base.conf with an alias. import Vue from 'vue' import App from './App' Vue.config.productionTip = false // 导入axios import axios from 'axios' // 将导入的axios挂载到全局的vm对象中用自定义属性名接收,后续所有的vm对象都可以用该属性名调用axios Vue.prototype.$axios = axios /* eslint-disable no-new */ new Vue({ el: '#app', components: {App}, template: '<App/>' })
<template> <div> <p>{{weather_data}}{{error_msg}}</p> </div> </template> <script> export default { name: "Weather", data: function () { return { weather_data: null, error_msg: null } }, created() { this.$axios.get('http://wthrcdn.etouch.cn/weather_mini', { params: { city: '南京' } }).then( response => { this.weather_data = response.data } ).catch(error => { this.error_msg = error }) } } </script> <style scoped> </style>