13-组件
1.前言
在没有使用VUE框架之前我们如果需要写一个页面,可能需要用到几个CSS文件和JS文件,且当HTML文件的结构有重复的结构时,我们只能重新的引用对应的CSS文件和JS文件和复制粘贴重复的结构代码,这就是传统的方式
学习了VUE框架后,就可以使用组件式的编写网页方式
需要理解几个概念:模块、组件、模块化、组件化
①.模块
1.理解:向外提供特定功能的js程序,一般就是一个js文件
2.为什么:js文件很多很复杂
3.作用:复用js,简化js的编写,提高js运行效率
②.组件
1.理解:用来实现局部(特定)功能效果的代码集合(html/css/js/image.)
2.为什么:一个界面的功能很复杂
3.作用:复用编码,简化项目编码,提高运行效率
③.模块化
当应用中的js都以模块来编写的,那这个应用就是一个模块化的应用。
④.组件化
当应用中的功能都是多组件的方式来编写的,那这个应用就是一个组件化的应用。
2.非单文件组件
1).基础使用
Vue中使用组件的三大步骤:
一、定义组件(创建组件)
如何定义一个组件?
使用Vue.extend(options)创建,其中options和new Vue(options)时传入的那个options几乎一样,但是有区别的
区别如下:
1.el不要写,为什么?——最终所有的组件都要经过一个vm的管理,vm中的el决定服务哪个容器
2.data必须写成函数,为什么?——避免组件被复用时,数据存在引用关系。
备注:使用template可以配置组件结构。
//第一步:创建school组件
const school=Vue.extend({
// 不要定义el
data(){
return{
schoolname:'滑浪学校',
schooladdress:'比奇堡',
}
},
template:`
<div>
<h2>学校名称:{{schoolname}}</h2>
<h2>学校地址:{{schooladdress}}</h2>
<button @click="show">点我显示学校名</button>
</div>
`,
methods: {
show(){
alert(this.schoolname)
}
},
})
//第一步:创建hello组件
const hello=Vue.extend({
template:`
<div>
<h2>你好,{{name}}</h2>
</div>
`,
data() {
return {
name:'Tom',
}
},
})
二、注册组件
如何注册组件?
1.局部注册:靠new Vue的时候传入components选项
2.全局注册:靠Vue.component(‘组件名’,组件)
// 第二步:注册组件(全局注册)
Vue.component('hello',hello)
//创建vm
const vm=new Vue({
el:'#root',
// 第二步:注册组件(局部注册)
components:{
// 最终的组件名:来自的变量名
xuexiao:school,
xuesheng:student,
// 直接将最终的组件名设置成跟来自的变量名一样的
school,
student,
}
})
三、使用组件(写组件标签)
编写组件标签:<school></school>
<div id="root">
<hello></hello>
<!-- 第3步:编写组件名称 -->
<xuexiao></xuexiao> / <school></school>
<hr>
<xuesheng></xuesheng> / <student></student>
</div>
2).使用的注意点
1.关于组件名:
一个单词组成:
第一种写法(首字母小写):school
第二种写法(首字母大写):School 多个单词组成:
第一种写法(kebab-case命名):my-school
第二种写法(CamelCase命名):MySchool(需要Vue脚手架支持)
//创建vm
new Vue({
el:'#root',
components:{
"my-school":school,
},
})
备注:
(1).组件名尽可能回避HTML中己有的元素名称,例如:h2、H2都不行。
(2).可以使用name配置项指定组件在开发者工具中呈现的名字。
const school=Vue.extend({
name:'schoolinfo', //VUE开发者工具默认的组件名词
data(){
return{
schoolname:'滑浪学校',
schooladdress:'比奇堡',
}
},
template:`
<div>
<h2>学校名称:{{schoolname}}</h2>
<h2>学校地址:{{schooladdress}}</h2>
</div>
`,
})
2.关于组件标签:
第一种写法:<school></school>
第二种写法:<school/>
备注:
不用使用脚手架时,<school/>会导致后续组件不能渲染。
<div id="root">
<my-school/>
<my-school/>
<my-school/>
</div>
3.一个简写方式:
const school=Vue.extend(options)可简写为:const school=options
const school={
// name:'schoolinfo', //VUE开发者工具默认的组件名词
// 不要定义el
data(){
return{
schoolname:'滑浪学校',
schooladdress:'比奇堡',
}
},
template:`
<div>
<h2>学校名称:{{schoolname}}</h2>
<h2>学校地址:{{schooladdress}}</h2>
</div>
`,
}
3).组件的嵌套
VUE的组件之间是可以相互嵌套的,被嵌套的就会成为子组件
//准备三个组件
const student=Vue.extend({
data(){
return{
studentname:'海绵宝宝',
studentage:'25',
}
},
template:`
<div>
<h2>学生姓名:{{studentname}}</h2>
<h2>学生年龄:{{studentage}}</h2>
</div>
`,
})
const school=Vue.extend({
data(){
return{
schoolname:'滑浪学校',
schooladdress:'比奇堡',
}
},
template:`
<div>
<h2>学校名称:{{schoolname}}</h2>
<h2>学校地址:{{schooladdress}}</h2>
<student></student>
</div>
`,
components:{
student
}
})
const hello=Vue.extend({
template:`
<div>
<h2>你好,{{name}}</h2>
</div>
`,
data() {
return {
name:'Tom',
}
},
})
//将student组件嵌套到school组件中
const school=Vue.extend({
data(){
return{
schoolname:'滑浪学校',
schooladdress:'比奇堡',
}
},
template:`
<div>
<h2>学校名称:{{schoolname}}</h2>
<h2>学校地址:{{schooladdress}}</h2>
<student></student>
</div>
`,
components:{
student
}
})
一般实际开发中Vue实例下只会有一个组件(app),我们可以将所有的组件都嵌套进app组件中,然后Vue实例中只设置一个组件
// 创建app组件
const app=Vue.extend({
template:`
<div>
<school></school>
<hello></hello>
</div>
`,
components:{
school,
hello,
}
})
//创建vm
new Vue({
el:'#root',
template:`<app></app>`,
// 第二步:注册组件(局部注册)
components:{app},
})
3.VueComponent构造函数
当我们在控制台输出组件时,我们会发现组件输出为一个构造函数,而VueComponent则是这个构造函数的名称
1).关于VueComponent:
1.school组件本质是一个名为VueComponent的构造函数,且不是程序员定义的,是Vue.extend生成的。
2.我们只需要写<school/>或<school></school>,Vue解析时会帮我们创建school组件的实例对象,
即Vue帮我们执行的:new VueComponent(options)。
3.特别注意:每次调用vue.extend,返回的都是一个全新的VueComponent!!!
//将school组件和hello组件进行比较
console.log('@',school);
console.log('#',hello);
console.log('!',school===hello);
school.a=99;
console.log('@',school.a);
console.log('#',hello.a);
4.关于this指向:
(1).组件配置中:data函数、methods中的函数、watch中的函数、computed中的函数它们的this均是【VueComponent:实例对象】
(2).new Vue()配置中:data函数、methods中的函数、watch中的函数、computed中的函数它们的this均是【Vue实例对象】。
<div id="root">
<button @click="showN">点我展示new Vue()配置中的this</button><br><br>
<school></school>
</div>
//创建school组件
const school=Vue.extend({
template:`
<div>
<button @click="showN">点我展示组件配置中的this</button>
</div>
`,
methods: {
showN(){
console.log("组件配置中的this",this);
}
},
})
// 创建vm
const vm= new Vue({
el:'#root',
components:{school},
methods: {
showN(){
console.log("new Vue()配置中的this",this);
}
},
})
2).Vue实例与组件实例的内置关系
**官方文档:**因为组件是可复用的Vue实例,所以它们与new Vue接收相同的选项,例如data、computed、watch、methods以及生命周期钩子等。仅有的例外是像el这样根实例特有的选项。
1.一个重要的内置关系:VueComponent.prototype.proto==Vue.prototype
Vue.prototype.x=99;
const school=Vue.extend({
template:`
<div>
<button @click="showX">点我显示X</button>
</div>
`,
methods: {
showX(){
console.log(this.x);
}
},
})
VueComponent构造函数的实例可以获取VUE的属性,也就说明VueComponent构造函数的实例的原型对象为Vue
2.为什么要有这个关系:让组件实例对象(vc)可以访问到Vue原型上的属性、方法。
4.非单文件组件
<div>
<button @click="showX">点我显示X</button>
</div>
`,
methods: {
showX(){
console.log(this.x);
}
},
})