组件化开发
- 创建组件构造器
cpnConstructor = Vue.extend({
template:`html代码`
})
- 注册组件
- 全局组件
Vue.component('myCpn',cpnContructor)
- 局部组件
挂载到Vue实例下面,可以在挂载的实例中使用。
- 使用组件
<mycon></mycpn>
- 语法糖
<template id="cpn" ><div></div></template>
Vue.component({
template:"#cpn",
data(){},
methods:{}
})
父子组件
- 父子组件:父组件在注册时包含一个组件,该组件相对于父组件为子组件。
- 组件注册时为什么data一定要用函数?
- 思考:假如组件数据存储部分不使用函数,那么当多次复用同一个组件时,数据部分会发生冲突吗?
- 每个组件实例都有自己的实例状态。
#因为如果data仍然是一个对象的话,复用这个组件时,这多个组件实例指向同一个对象(同一个地址),那么就会出现更改其中一个组件的数据,所有组件的数据都会跟着改变。
Vue.component({
template:"#cpn",
data:{},
methods:{}
})
#等价写法
const data = {}
Vue.componet({
template:"#cpn",
data: data,
methods:{}
})
父子组件之间的通信
#父组件通过props向子组件传递数据。 在子组件中用props进行属性的定义
function Person (firstName,lastName) {
this.firstName = firatName
this.lastName = lastName
}
Vue.component('cpn',{
props: {
propA:Array,
propB: [String,Number]
propC:{
type:String,
required:true
}
propD:{
type:Number,
default:100
}
propE: {
type:Object,
deflaut() {
return {}
},
required:true
}
propF:{
type: Person,
default() {
return {}
}
}
}
- 当属性的类型(type)为数组(Array)或者对象(Object)时,默认值必须为函数类型且有返回值。
Vue.component('cpn',{
props: {
propB: {
type:Array,
deflaut() {
return [];
},
required:true
}
}
}
- 若props采用驼峰命名,在父组件传参时需要改变写法。如:
propA
->prop-a
- 子组件通过自定义事件
$emit Event
向父组件传递数据。
<template id="cpn">
<div v-for="item in categories">
<button @click="btnclick(item)">{{item.name}}</button>
</div>
</template>
const cpn = {
template: "#cpn",
data(){
return {
categories:[
{id:'111',name:'热门'},
{id:'222',name:'手机'},
{id:'333',name:'电脑'},
]
}
},
methods: {
btnclick() {
this.$emit("cpnclick",item);
}
}
}
<div id="app">
<cpn @cpnclick="fclick"></cpn>
</div>
const app = new Vue({
el: '#app',
components:{ cpn},
methods:{
fclick(item){
console.log(item);
}
}
})
对象的增强写法
const cpn = {}
components:{ cpn }
父子组件的访问
- 父组件访问子组件:$children/$refs
- 常用的是$refs,需要在使用子组件时绑定ref属性,相当于给子组件起个名字name,然后通过this.$refs.name获取到该子组件。 - 子组件访问父组件:$parent/$root
- $parent访问上一级父组件,一般返回VueComponent实例
- $root访问根组件,一般返回一个Vue实例
插槽
- 插槽的基本使用:
用<slot></slot>
在组件里面占位置,然后在使用组件时再具体的决定插槽的内容 - 不带默认值的基本使用:
组件内部:<slot></slot>
调用组件:<cpn><span>我将替换插槽</span></cpn>
- 带默认值的基本使用:
组件内部:<slot><span>我是默认值</span></slot>
调用组件:<cpn></cpn>
。使用时不用传slot替换的内容,如果传了那么将会覆盖默认插槽里的内容。 - 具名插槽的使用:
组件内部:<slot name="slot1"></slot>
调用组件:<span slot="slot1">我将替换插槽</span>
- 作用域插槽:父组件可以访问子组件的数据
//组件内部
<slot :data="languages">
<ul>
<li v-for="item in languages>{{item}}</li>
</ul>
</slot>
//调用组件
<template slot-scope="slot">
<span v-for="item in solt.data">{{item}}</span>
</template>