Vue基础巩固(二)
1.认识组件化
组件化思想:将页面拆分成一个个小的、可复用的组件
2.注册组件
组件模板只包含一个根元素
组件不能直接访问Vue实例中的data
组件对象也有一个data属性,data属性必须是一个函数,这个函数返回一个对象,对象内部保存着数据
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 ><div id="app">
<!-- 3.使用组件 -->
<my-cpn></my-cpn>
></div>
><script src="https://cdn.jsdelivr.net/npm/vue@2.6.14/dist/vue.js"></script>
><script>
// 1.创建组件构造器
const myComponent = Vue.extend({
template:`
<div>
<h2>组件标题111</h2>
<p>组件内容</p>
</div>
`
})
// 2.注册组件,定义组件标签名
Vue.component('my-cpn',myComponent)
let app = new Vue({
el: '#app',
})
></script>为什么data在组件中必须是一个函数?
1.如果不是一个函数,Vue直接就会报错
2.Vue让每个组件对象都返回一个新的对象,因为如果是同一个对象的,组件在多次使用后会相互影响
3.父子组件间的通信
3.1 props用于父组件向子组件传递数据
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29 ><div id="app">
<my-cpn :msg="msg"></my-cpn>
></div>
><template id="myCpn">
<div>
<div>{{msg}}</div>
<div>{{msg1}}</div>
</div>
></template>
><script src="https://cdn.jsdelivr.net/npm/vue@2.6.14/dist/vue.js"></script>
><script>
let app = new Vue({
el: '#app',
data:{
msg:'我是vue实例数据或父组件里的数据'
},
components:{
'my-cpn':{
template: '#myCpn',
props:['msg'],
data(){
return{
msg1:'组件里的数据'
}
}
},
}
})
></script>3.2 通过自定义事件向父组件发送消息
自定义事件的流程:
1.在子组件中,通过$emit()来触发事件【this.emit方法不能使用驼峰命名的函数】
2.在父组件中,通过v-on来监听子组件事件
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45 ><div id="app">
<my-cpn @increment="handleChange" @decrement="handleChange"></my-cpn>
<h2 >点击次数:{{total}}</h2>
></div>
><template id="myCpn">
<div>
<button @click="Increment">+1</button>
<button @click="Decrement">-1</button>
</div>
></template>
><script src="https://cdn.jsdelivr.net/npm/vue@2.6.14/dist/vue.js"></script>
><script>
let app = new Vue({
el: '#app',
data:{
total:0
},
methods:{
handleChange(count){
this.total = count
}
},
components:{
'my-cpn':{
template: '#myCpn',
props:['msg'],
data(){
return{
count:0
}
},
methods:{
Increment(){
this.count++
this.$emit('increment',this.count)
},
Decrement(){
this.count--
this.$emit('decrement',this.count)
},
},
},
}
})
></script>
4.父子组件的访问方式: $children
4.1 父组件访问子组件:使用$children或$refs
$children: this.$children是一个数组类型,它包含所有子组件对象【缺陷:通过$children访问子组件时,是一个数组类型,访问其中的子组件必须通过索引值】
$refs: $refs和ref指令通常是一起使用的,通过ref给某一个子组件绑定一个特定的ID,通过this.$refs.ID访问到该组件this.$refs.child 【child为特定的ID,绑定在子组件上】 <my-cpn ref="child"></my-cpn>
4.2 子组件访问父组件:使用$parent
允许通过$parent来访问父组件,但是在真实开发中尽量不要这样做
子组件应该尽量避免直接访问父组件的数据,因为这样耦合度太高了
如果我们将子组件放在另外一个组件之内,很可能该父组件没有对应的属性,往往会引起问题
更不好做的是通过$parent直接修改父组件的状态,那么父组件中的状态将变得飘忽不定,很不利于我的调试和维护
5.非父子组件通信
1.在Vue1.x的时候,可以通过$dispatch和$broadcast完成
$dispatch用于向上级派发事件
$broadcast用于向下级广播事件
2.在Vue2.x中,有一种方案是通过中央事件总线,也就是一个中介来完成
3.Vuex的状态管理
6.slot插槽
使用:在子组件中,使用特殊的元素<slot>就可以为子组件开启一个插槽,该插槽插入什么内容取决于父组件如何使用
6.1 具名插槽slot【带有name属性】【父组件或实例可以对子组件里的插槽进行修改】<slot name='myslot'>我是插槽01</slot> <my-cpn><span slot="myslot">123</span></my-cpn>
6.2 作用域插槽: 父组件替换插槽的标签,但是内容由子组件来提供
使用:通过<template slot-scope="slotProps">获取到slotProps属性, 通过slotProps.data获取数据
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31 ><div id="app">
<my-cpn>
<template slot-scope="slotProps">
<ul>
<li v-for="info in slotProps.data">{{info}}</li>
</ul>
</template>
</my-cpn>
></div>
><template id="myCpn">
<div>
<slot :data="text"></slot>
</div>
></template>
><script src="https://cdn.jsdelivr.net/npm/vue@2.6.14/dist/vue.js"></script>
><script>
let app = new Vue({
el: '#app',
data:{},
components:{
'my-cpn':{
template: '#myCpn',
data(){
return{
text:['Html','Js']
}
},
},
}
})
></script>6.3 编译作用域
准则:父组件模板的所有东西都会在父级作用域内编译;子组件模板的所有东西都会在子级作用域内编译
my-cpn组件能否渲染出来?
