什么是组件?
以前我们写重复的代码时总是复制黏贴,一方面会增加代码量,降低执行和开发效率,另一方面也会增加维护的负担。现在好了,有了组件,我们可以将重复的代码进行封装以便于重复使用。
1. 创建组件
const compo1 = Vue.extend({
//组件的模板有且只能有一个根元素,否则会报错,因此最好将多个元素 放到div或其他容器中
template: ‘<p>my name is {{name}}</p>’,
//组件的data区域必须是个函数而不是对象否则会报错,vue是这么规定的,这样写的好处是确保每次返回的都是一个新的对象,使得同一组件的不同对象间不会相互影响
data: function() {
return {
name: ‘zygswo’
}
},
components: {
//组件里套组件,详见父子组件模块
}
})
2. Vue 全局组件注册和局部组件注册
什么是全局组件,全局组件就是不局限于注册的容器或vue实例中,而是可以在整个页面上使用的组件。
局部组件则是局限于挂载或注册的容器或vue实例中使用的组件。
- 全局组件注册
通过Vue.component(组件名,组件对象) 方式进行 - 局部组件注册
通过new 一个新的Vue实例,在components 属性中加以注册即可
例如:
const app1 = new Vue({
el: ‘#app1’,
data: {
name: ‘zygswo’
},
components: {
xxx: xxx // 组件名称:组件对象
}
})
或者直接mount(挂载)到一个dom元素上(前提是有id为app1的dom元素)
例如:
new compo1().$mount(‘#app1’) //以前面的例子为例
3. 父子组件
父子组件的关系顾名思义就是父亲和儿子的关系。
父子组件的使用例如:
//子组件
const cpnC1 = Vue.extend({
template: ‘<p>hello world, hello {{name}}!</p>’,
data: function() {
return {
name : ‘vue’
}
}
})
//父组件
const cpnC2 = Vue.extend({
template: ‘
<p>禁止套娃</p>
<p>我偏要套娃</p>
<cpn1><cpn1>
’,
data: function() {
return {
name : ‘vue’
}
},
component: {
cpn1: cpnC1 //子组件名称: 子组件对象
}
})
//组件注册到vue实例(也可以看成父组件)
const app1 = new Vue({
el: ‘#app1’,
data: {
name: ‘zygswo’
},
components: {
cpn2: cpnC2
}
})
cpnC1由于被嵌入了cpnC2这一组件中所以他是儿子,而cpnC2则是父亲,因为他可以管儿子。(注意和java的父子类进行区别,java父子类是子类继承父类,子类可以访问父类的属性,父类不能访问子类的属性和方法,而这里是父子组件互相调用数据则需要进行通信,详见父子组件通信)
4. 语法糖(没啥卵用)
const app1 = new Vue({
el: ‘#app1’,
data: {
name: ‘zygswo’
},
components: {
//将组件对象写进父组件的compnents属性里
cpn2: {
template: ‘<p>hello vue!</p>’,
data: function() {
}
}
}
})
5. 模板的分离写法,好处:看着舒爽!!
<template id=”xxx”>
<p>hello world,hello vue!</p>
</template>
<script>
//全局组件注册
Vue.component(‘cpn’, {
template: ‘#xxx’, //对应id为xxx的模板内容 即 ‘hello world,hello vue!’
data: function() {
return {
...
}
},
components: {
...
}
});
</script>
6. 父子组件通信【重点】
很多地方都会用到父子组件的通信,比如电商平台的商品列表,就是先调用后端接口然后通过v-for进行子组件的渲染和排列,之后将商品数据传递给子组件实现的。那么怎么传呢?
- 父传子:props
写在子类中,例子如下:
<div id="app">
<cpn v-bind:cmsg="msg"></cpn> //在父组件中进行v-bind动态绑定,将父组件中的msg的值传给子组件
</div>
<template id="cpn" v-cloak>
<div>
<span>{{cmsg}}</span> //注意:这里调用子组件的props中的某一属性
</div>
</template>
<script src="static/vue.js"></script>
<script>
const app = new Vue({
el: '#app',
data: {
msg:"hello world" //父类中的变量
},
components: {
cpn: {
template: '#cpn',//绑定模板
props:['cmsg'], //props—子组件中props的名称可任取
data() {
return {
...
}
}
}
}
})
</script>
多看几遍就能理解,整体的流程是:
- 先在子组件的props属性中创建一个变量用于存储父组件传递的值,
- 之后再在子组件的模板中调用这个属性,
- 最后就是创建绑定vue实例的dom元素(id选择器或class选择器)
- 然后通过v-bind:cmsg=”msg” 动态绑定属性值的方式将父组件中的数据传递给子组件(这里msg为父组件中的数据的名称,cmsg为子组件的属性名称)
注意: v-bind 动态绑定属性暂不支持驼峰规则,如果要用则在v-bind后用“-”进行连接,如“v-bind:myMessage” => “v-bind:my-message”
注意: props 也可以是对象,如
const cpnC1 = Vue.extend({
template: ‘‘,
data: function() {
return {
}
},
props: {
cmsg: {
type: String, //规定类型为字符串类型
default: ‘zygswo’ //规定默认值(即在父组件中没进行动态绑定(v-bind)时)
}
}
})
- 子传父:emit
<div id="app1">
<!--父传子 -->
<cpn v-bind:cmsg="msg"></cpn>
<!--子传父-->
<!-- 第二步给父组件中的元素绑定事件 -->
<cpn1 @v-click="clique"></cpn1>
</div>
<template id="cpn1">
<div>
<ul>
<!-- 第一步给子组件中的元素绑定事件 -->
<li v-for="(item,index) in categories" @click="onClick(item)">{{item.name}}</li>
</ul>
</div>
</template>
先写到这里吧,觉得有疑惑的小伙伴欢迎评论区留言
——————————有趣的分割线————————————————