组件 - components
- 定义: 组件的出现,就是为了拆分vue实例的代码量的,能够让我们以不同的组件,来划分不同的功能模块,将来我们需要什么样的功能,就可以去调用对应的组件即可;
- 组件化和模块化的区别
- 模块化:是从代码逻辑的角度进行划分的,方便代码分层开发,保证每个功能模块的只能单一。
- 组件化:是从UI界面的角度进行划分的,前端的组件化,方便UI组件的重用。
创建组件的方式
第一种
1.1
1
2
3let com1 = Vue.extend({
template:"<h3>这是使用Vue.extend创建出来的组件</h3>"
})1.2
Vue.component(“mycom1”,com1) 引入的时候,使用标签进行渲染
可以合并成一步:1
2
3Vue.component('mycom1',Vue.extend({
template:"<h3>这是使用Vue.extend创建出来的组件</h3>"
}))
第二种
1 | 注意:无论是哪种方式创建出来的组件,组件的template属性指向的内容, |
第三种
Vue.component('mycom2',{template:'#temp1'})
- 在APP控制的区域外,定义一个ID为temp1的template标签,在标签元素节点可以写你想要的代码
- 组件中的data
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21注意:data必须是一个函数,而且函数必须返回一个对象,
模板中的元素行内指令可以调用,这里返回对象的意义,
当调用多次同一个组件的时候,虽然返回对象内容相同,
但是是引用数据类型,空间地址不一样,
组件之间的数据完全独立,不会因为其他组件数据的变化而变化
let vm2 = new Vue({
el:'#app2',
data:{
},
components:{
login:{
template:'#temp1',
data:function(){
return{
msg:''
}
}
}
}
})
Vue提供的4个标签属性
transition
transition-group
template
component
子父组件 如何相互传值
1 | <son :parentmsg = "msg" @parentfuc123 = "fn"></son> |
父传子
父组件通过绑定自定义属性,向子组件内传入数据
子组件通过props:[‘自定义属性名’],接收父组件传进的数据
具体实现方式 =>
:parentmsg = "msg"
(parentmsg
为自定义属性名,msg
为父组件内的数据)
使用过程中注意:1.传入的数据可以是基本数据类型,也可以是引用数据类型;
2.可以是父组件中的data数据,也可以是methods中的方法(但是我们需记住:VUE不希望我们以自定义属性的方式,传入methods中的方法);
3.不能直接修改props中父组件传进来的数据,虽然子组件可以渲染出修改后的数据,但是只要父组件视图发生变化,就会重新覆盖子组件的内容;
4.但是,当我们传入一个引用数据类型,在原地址修改数据时不会引起报错,能成功修改父组件的数据;
5.子组件使用父组件的数据是一个单向的数据流;
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">
<son :parentname = 'val' :myname ="name" :arr = ary v-for = "val in ary"
:key = "val">
</son>
</div>
<template id="son">
<div>
<h2>{{parentname}}</h2>
<h3 v-for = "i in arr"></h3>
<button @click="fn">这个按钮点击{{n}}次</button>
</div>
</template>
let son ={
template:'#son',
props:['parentname','myname','arr'],
data(){return{n:0}},
methods:{
fn(){
this.n++
this.arr.push('node')
}
}
let vm = new Vue({
el:'#app',
data:{
name:'hello',
ary:['css','js','vue']
},
components:{
son
}
子传父
父组件通过绑定自定义事件,向子组件内传入methods方法
子组件通过调用this.$emit(‘自定义事件名’,第一参数,第二参数…)方法,接收父组件方法,并通过第一参数,第二参数…,同时向父组件内传值
具体实现方式 =>
@parentfuc123 = "fn"
(parentfuc123
为自定义属性名,fn
为父组件内的methods
方法)
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 <div id="app">
<h2>{{name}}</h2>
<son @qqq = "change"></son>
</div>
<template id="son">
<div>
<input type="text" v-model="n">
<button @click = "fn">通过自定义事件改变父组件的name</button>
</div>
</template>
let son = {
template:'#son',
data(){return{n:''}},
props:['aaa'],
methods:{
fn(){this.$emit('qqq',this.n)}
}
}
let vm = new Vue({
el:'#app',
data:{name:'hello'},
components:{
son
},
methods:{
change(val){
this.name = val
}
}
})
其它传值方式
- 父组件可使用
this.$children[0]
this.$refs.son
- 子组件可使用
自定义组件
为什么要使用自定义组件:有时候,当我们对原生提供的样式不满意时,可以使用自定义组件,组件的样式我们可以自行设置1
2
3
4
5
6
7
8
9
10
11
12
13
14
15<div id = "app">
<my-input v-model = 'name'></my-input>
<!-- 等价于
<my-input :value = 'name' @input></my-input>
-->
</div>
<template id = "son">
<input :value = 'value' @input = '$emit('input')'></input>
</template>
<script>
let son = {
template:'#son',
props:['value']//value 是规定死的,不能改写
}
</script>
插槽
用法: 将slot
标签放置在组件的模板中,那么在以组件名生成标签内部的所有内容,会替换slot
标签的位置
注意:1.slot 的name属性是控制 要去显示哪一部分的一个功能,写时默认default;
2.name 对应的是 模板中slot=xxx 的 xxx;
3.模板中若有与name值对应的元素;则 slot标签包含的代码不会显示出来;
4.否则,可以显示slot标签包含的内容
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<div id = "app">
<son>
<div slot='qqq'>hahaha</div>
<h2>hehehe</h2>
<div>24324</div>
<div slot='www'>111</div>
<div slot='www'>222</div>
</son>
</div>
<template id = "son">
<!-- slot 相当于把组件标签包含的所有内容 放到slot标签的位置 -->
<div>
<slot name = "qqq"></slot>
//显示:hahaha
<h1>这是个子组件</h1>
<slot></slot>
//显示:hehehe 只能显示没有slot属性的标签元素
// 24324
<slot name='www'>
<div name='2342342'>777</div>
</slot>
//显示: 111 222
<slot name='eee'>
<div name='2342342'>666</div>
<slot name='www'></slot>
</slot>
//显示:666 111 222
//原因:上面标签内部中,并没有slot = "eee"属性的元素,所以会显示<slot></slot>标签内部的默认值
</div>
</template>
component 动态组件
component
是一个内置动态组件; is
属性用控制显示哪个子组件keep-alive
包裹动态组件时,会缓存不活动的组件实例,而不是销毁它们。和transition
相似,keep-alive
是一个抽象组件:它自身不会渲染一个 DOM 元素,也不会出现在父组件链中。主要用于保留组件状态或避免重新渲染1
2
3
4
5
6
7<div id="app">
<button @click='son="son1"'>son1</button>
<button @click='son="son2"'>son2</button>
<keep-alive>
<component :is='son'></component>
</keep-alive>
</div>