在实际开发中,我们运用脚手架搭建项目的时候都是单文件组件,几乎用不到非单文件组件,介绍非单文件组件就是为了给单文件组件作基础铺垫。一个组件包含css+html+js+其他资源(mp4、音乐等等),组件是实现局部功能代码的集合。
Vue中使用组件的三大步骤:
第一步:定义组件(创建组件)
使用Vue.extend(options)创建,其中options和new Vue(options)时传入的那个options几乎一样,但也有点区别;区别如下:
1、el不要写,最终所有的组件都要经过一个vm的管理,由vm中的el决定服务哪个容器。
2、data必须写成函数,避免组件被复用时,数据存在引用关系(如果你使用对象写法,当你在一个组件里面修改数据的时候,那么其他用到该数据的组件也会被修改)。
备注:使用template可以配置组件结构。
第二步:注册组件
局部注册:靠new Vue的时候传入components选项
全局注册:靠Vue.component('组件名',组件)
备注:无论是全局注册还是局部注册,定义组件(第一步)都要在注册之前完成。
第三步:使用组件(写组件标签)
基本使用
基本使用
关于组件名
+ 一个单词组成:
第一种写法(首字母小写):school
第二种写法(首字母大写):School
+ 多个单词组成:
第一种写法(kebab-case命名):my-school
第二种写法(CamelCase命名):MySchool (需要Vue脚手架支持)
+ 备注:
组件名尽可能回避HTML中已有的元素名称,例如:h2、H2都不行。
可以使用name配置项指定组件在开发者工具中呈现的名字。
关于组件标签:
第一种写法:
第二种写法:
备注:不用使用脚手架时,
会导致后续组件不能渲染。 一个简写方式:
const school = Vue.extend(options) 可简写为:const school = options
几个注意点 {{msg}}
几个注意点
1、school组件本质是一个名为VueComponent的构造函数,且不是程序员定义的,是Vue.extend生成的。
2、我们只需要写```
3、 特别注意:每次调用Vue.extend,返回的都是一个全新的VueComponent!!!!
4、关于this指向:
1、组件配置中:data函数、methods中的函数、watch中的函数、computed中的函数 它们 的this均是【VueComponent实例对象】。
2、new Vue(options)配置中:data函数、methods中的函数、watch中的函数、computed中 的函数 它们的this均是【Vue实例对象】。
5、VueComponent的实例对象,以后简称vc(也可称之为:组件实例对象)。
6、ViewModel的实例对象,以后简称vm,(也可称之为:Vue实例对象)。
7、一个组件对应一个vc,然后所有的vc都要听从vm的管理(比如上面的组件嵌套中,所有的组件都是App组件来管理,但是App组件又是vm来管理,由此可见vm才是老大)
VueComponent.prototype.__proto__ === Vue.prototype
为什么要有这个关系:让组件实例对象(vc)可以访问到 Vue原型上的属性、方法。
代码:
一个重要的内置关系
单文件组件都是以.vue结尾的文件格式,这种文件格式直接交给浏览器,目前浏览器是识别不出来的。想要单文件组件在浏览器中有效果,那么就需要把.vue结尾的文件转换成浏览器能够识别的文件格式(.html、.js、.css)。目前我所知道的转换方式有两种,一种是webpack打包,另一种就是脚手架(Vue CLI),其实脚手架就是利用webpack和其他库封装起来的,所以我们直接使用就行,后面篇章会介绍脚手架搭建项目。
注意:定义组件的时候不要写el配置项以及data要写成函数式(非单文件组件介绍的时候有提及)
vue组件中给我们提供了三个标签,分别是、、以及,template里面写的是模板(多个元素需要用一个根元素div来包裹,且template标签不参与编译),script里面写的是交互,style里面写的是样式。写好一些代码以后,由于vscode不能识别这些标签,所以此时代码是不显示高亮的,需要下载插件才能让代码显示高亮。这里我推荐安装Vetur插件,作者是Pine Wu。下载安装好之后代码就可以显示高亮了。
School.vue组件代码:
{{ schoolName }}
{{ address }}
我给大家引导一波,上面我们终究是定义了一个组件(就和非单文件组件中的定义组件一样),最终我们定义的组件都要被自己或者别人引入使用(非单文件组件中组件定义好了也是被拿去注册使用),现在我们定义好了一个单文件组件,我们在开发中组件与组件都是分开的,不像非单文件组件一样在同一个script标签里面去完成定义、注册和使用。如此,上面定义好的单文件组件School想要使用它就必须引入它就要使用import,所以School组件需要暴露出去别人才能引入它,随后使用School.vue。
模块化中暴露方式有三种:
第一种:分别暴露 (如下)
export const School = Vue.extend({ name: "School", data() { return { schoolName: "清华大学", address: "北京", }; }, methods: { showMsg() { alert(this.schoolName); }, }, })
分别暴露的引入方式有两种:
import {School,....} from '组件地址' //按需引入 import * as Demo from '组件地址' //统一引入
第二种:统一暴露(如下),它的引入方式和分别暴露一致
const School = Vue.extend({ name: "School", data() { return { schoolName: "清华大学", address: "北京", }; }, methods: { showMsg() { alert(this.schoolName); }, }, }) export {School,...} //如果还有其他需要暴露的继续在省略号处添加即可
第三种:默认暴露(如下),组件暴露推荐使用默认暴露
/* export default Vue.extend({ name: "School", data() { return { schoolName: "清华大学", address: "北京", }; }, methods: { showMsg() { alert(this.schoolName); }, }, }) */ //export default School //默认暴露的原始写法,但是可以将这里直接写到定义组件处将逻辑直接暴露出去 //由于const school = Vue.extend(options) 可简写为:const school = options //那么上面代码可以简写成: export default { name: "School", data() { return { schoolName: "清华大学", address: "北京", }; }, methods: { showMsg() { alert(this.schoolName); }, }, }
默认暴露的引入方式:
import School from '组件地址'
如此,School.vue组件的代码可以改成:
{{ schoolName }}
{{ address }}
Student.vue组件代码:
{{ studentName }}
{{ age }}
定义好School和Student两个子组件之后,我们需要再定义一个App组件来管理所有的子组件,App组件介于Vm实例之下,所有子组件之上。
App组件代码:
3.创建vm
至此,上面我们创建了两个子组件School和Student,也创建了子组件的老大App组件,但是所有的组件都得听从vm的,一般情况下,我们会创建一个main.js的文件来作为vm(也有的人习惯写成index.js),但是记住一点,能跟vm直接对话的只有App组件,其他子组件不能直接跟vm直接对话,只能跟App组件对话然后再传给vm。
main.js文件代码如下:
// 引入App组件
import App from './App.vue'
// 创建实例对象vm
new Vue({
el:'#root',
template:' ',
components:{App}
})
至此,vm实例也有了,但是指定的root容器还没有,一般创建一个index.html文件作为div容器
4.创建index.html文件作为div容器
由于模板可以配置在template的配置项中,所以使用App组件时把它放在vm的template配置中,由此容器里面可以什么都不用写。
练习一下单文件组件语法
最后,这些组件代码目前浏览器不能识别出来,下一篇我会给大家介绍用脚手架去搭建项目,然后使用上面的代码在浏览器中呈现页面效果。