1.组件化开发的步骤
- 创建组件构造器
- 注册组件构造前
- 使用组件
2.全局组件和局部组件
<div id="app">
<cpn></cpn>
<cpn></cpn>
</div>
<div id="app2">
<cpn></cpn>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
// 1.创建组件构造器
const cpnC = Vue.extend({
template: `<div><h2>我是标题</h2><p>我是内容</p></div>`
})
//2.注册组件(全局组件,意味着可以在多个Vue实例上使用该组件)
// Vue.component('cpn',cpnC)
const app = new Vue({
el: '#app',
data: {
message: "hello"
},
//2.注册组件(局部组件,作用于单个实例)
components: {
cpn: cpnC
}
})
const app2 = new Vue({
el: '#app2',
data: {
message: "hello"
}
})
</script>
3.父组件和子组件
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
// 子组件
const cpnC1 = Vue.extend({
template: `
<div>
<h2>这是模板</h2>
<p>11111111111</p>
</div>`
})
// 父组件
const cpnC2 = Vue.extend({
template: `<div><h2>我是标题</h2><p>2222222222</p><cpn1></cpn1></div>`,
components: {
//父组件调用子组件
cpn1: cpnC1
}
})
//根组件
const app = new Vue({
el: '#app',
data: {
message: "hello"
},
components: {
cpn2: cpnC2
}
})
</script>
4.组件的语法糖
<script>
const cpn1 = Vue.extend({
template: `<div><h2>我是标题</h2><p>我是内容11</p></div>`
})
//全局注册
// Vue.component('cpnc1',cpn1);
// 语法糖式全局注册
// Vue.component('cpnc1',({
// template: `<div><h2>我是标题</h2><p>我是内容222</p></div>`
// }))
const app = new Vue({
el: '#app',
data: {
message: "hello"
},
//局部注册
// components: {
// cpnc1: cpn1
// }
//语法糖
components: {
cpnc1: ({
template: `<div><h2>我是标题</h2><p>我是内容222</p></div>`
})
}
})
</script>
5.组件模板的抽离
抽离的背景,HTML代码混杂在JS中,这样不规范
<div id="app">
<cpn></cpn>
<cpn></cpn>
<cpn></cpn>
<npc></npc>
<npc></npc>
<npc></npc>
</div>
<!--组件模板抽离-->
<!--方法1-->
<script type="text/x-template" id="cpn1">
<div>
<h2>我是标题</h2>
<p>111111</p>
</div>
</script>
<!--方法2-->
<template id="cpn2">
<div>
<h2>我是标题</h2>
<p>222222</p>
</div>
</template>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
Vue.component('cpn',{
template: "#cpn1"
})
Vue.component('npc',{
template: "#cpn2"
})
const app = new Vue({
el: '#app',
data: {
message: "hello"
}
})
</script>
6.组件与Vue实例中的数据
组件不能访问Vue实例中的数据
<script>
Vue.component('cpn',{
template: '#cpn2',
//使用一个函数来存放数据
data() {
return {
title: 'abc'
}
}
})
const app = new Vue({
el: '#app',
data: {
message: "hello"
}
})
</script>
7.组件中的data为什么为函数
因为函数每次会返回一个实例(即组件间使用不同的地址空间),保持组件间的数据独立,来保存组件自己的状态
8.父子组件间的通信
1.父组件往子组件传递数据
<div id="app">
<cpn2 :cMovie="movie" :cMessage="message"></cpn2>
</div>
<template id="tcpn">
<div>
<p>{{cmovie}}</p>
<p>{{cmessage}}</p>
</div>
</template>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
// 子组件
const cpnC2 = Vue.extend({
template: '#tcpn',
props: ['cmovie','cmessage'],
})
//根组件
const app = new Vue({
el: '#app',
data: {
message: "hello",
movie: ['123','321','222']
},
components: {
cpn2: cpnC2
}
})
</script>
对象写法:
props: {
cmessage: {
type: string,
default: 'aaaaa',
required: true
}
cmovie: {
type: Array,
default(){
return []
}
}
}
2.子组件往父组件传递数据
通过自定义事件的方式来让子组件向父组件传递数据
<div id="app">
<cpn2 @itemclick="cpnClick"></cpn2>
</div>
<template id="tcpn">
<div>
<button v-for="item in categories" @click="btnClick(item)">
{{item.name}}
</button>
</div>
</template>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
// 子组件
const cpnC2 = Vue.extend({
template: '#tcpn',
data(){
return{
categories: [
{id:'1',name:'热门推荐'},
{id:'2',name:'手机数码'},
{id:'3',name:'家用办公'},
{id:'4',name:'电脑办公'},
]
}
},
methods: {
btnClick(item){
//
this.$emit('itemclick',item)
}
}
})
//根组件
const app = new Vue({
el: '#app',
data: {
message: "hello",
movie: ['123','321','222']
},
components: {
cpn2: cpnC2
},
methods: {
cpnClick(item) {
console.log(item)
}
}
})
</script>