Vue学习笔记之深入理解Vue组件(二)
文章目录
父子组件间的数据传递
1.父向子组件传值:
1.1 子组件通过props接收
1.2 单向数据流:父组件可以随意向子组件传递参数,子组件不可以改父组件的参数。解决办法: 要想改变父组件的参数,子组件在data项中新赋值父组件的变量,操作新定义的变量即可
2.子向父组件传参数
使用触发事件:this.$emit(‘方法名’,参数),参数为传给父组件中监听事件
运行这个例子,父组件给子组件传递了count属性,子组件通过props接收这个属性,通过number:this.count保存这个属性,因为直接更改也许会影响其它也使用了这个属性的组件。点击子组件,emit一个change事件,根组件监听着这个组件,一旦触发,执行handleChange函数。
<div id="root">
<counter
@change='handleChange'
:count='1'
></counter>
<counter
@change='handleChange'
:count='2'
></counter>
<div>{{total}}</div>
</div>
<script type="text/javascript">
Vue.component('counter',{
template: "<div @click='handleClick'>{{number}}</div>",
props:['count'],
data () {
return {
number: this.count
}
},
methods: {
handleClick: function () {
this.number++;
this.$emit('change',1)
}
}
})
var vm =new Vue({
el: '#root',
data: {
total:3
},
methods: {
handleChange: function (num) {
this.total+=1
}
}
})
</script>
组件参数校验
如果父组件定义 content="" 属性,引号里表示的是一个字符串;只有 :content="" 的形式,引号里才表示一个 js 表达式。
组件参数校验:
子组件对父组件传递过来的参数,做一些约束,比如要求一定是字符串,props对象中的键:
type
required: 表示必须传,
default: 如果不传参数,会有默认值,
validator : 校验器,定义方法
props:{
content:{
type:
required:false,
default:d value,
validator:function(value){
}
}
}
非props特性:
父组件向子组件传递属性,子组件并没有通过props接收,子组件不能获取到父组件这个属性的值
特点:
属性会展示在子组件最外层的dom标签上
给组件绑定原生事件
1.传统方法绑定事件为:
1、在子组建上绑定事件
2、在子组件中的methods设置相应的事件函数,并在函数中设置自定义事件函数,将自定义事件传递给父组件
3、在父组件上绑定从子组件methods函数中传来的自定义事件
4、在父组件methods中设置对应的事件函数。
<div id="root">
<item @click='handleClick'></item>
</div>
<script type="text/javascript">
Vue.component('item',{
template: "<div @click='handleChild'>hello</div>",
methods: {
handleChild: function () {
this.$emit('click')
}
}
})
var vm = new Vue({
el: '#root',
methods: {
handleClick: function () {
alert(1);
}
}
})
</script>
2.组建上绑定原生事件:
1、在父组件绑定事件(如@click.native=“handle”)
2、在vue实例中的methods下定义事件函数。
给组件绑定原生事件的话,这个例子等于
<div id="root">
<item @click.native='handleClick'></item>
</div>
<script type="text/javascript">
Vue.component('item',{
template: "<div>hello</div>",
})
var vm = new Vue({
el: '#root',
methods: {
handleClick: function () {
alert(1);
}
}
})
</script>
非父子组件间的传递
例如1向3传值,3向3传值便是非父子组件间的传值。我们该如何实现呢?
一般来说我们有两种方式:
1.(Bus/总线/发布订阅模式/观察者模式)
Vue.prototype.bus = new Vue() 在vue的prototype上挂载bus属性,该属性指向vue实例,接下来的每一个vue实例乃至组件都有了bus属性
在子组件中定义方法,
在组件实例中:
在methods传递数据 : 通过this.bus.on(“函数名”,function(value){})
<div id="root">
<child content="hello"></child>
<child content="world"></child>
</div>
<script>
Vue.prototype.bus = new Vue()
Vue.component('child', {
data: function () {
return {
selfContent: this.content
}
},
template: "<div @click='handleClick'>{{selfContent}}</div>",
props: {
content: String
},
methods: {
handleClick: function () {
this.bus.$emit('change',this.selfContent)
}
},
mounted: function () {
var this_=this;
this.bus.$on('change',function (msg) {
this_.selfContent=msg;
})
}
})
var vm = new Vue ({
el: '#root'
})
</script>
实现效果,点击hello那个组件,world也会跟着变成hello,這就是一个简单的发布订阅,实现了子组件间的传值。
2.Vuex
这个内容又比较多了,以后单独写一章吧!
在Vue中使用插槽
插槽(slot):
作用:父组件可以优雅的向子组件传递dom,方便维护。
在父组件中直接写要插入的dom,在子组件的template中 用默认内容这个标签来替换父组件中的dom。
注意:可以在slot中定义默认值
具名插槽:
父组件传给子组件2个插槽,在父组件的标签上分别为slot=“a” slot=“b”
在子组件的template的slot标签中这样来使用:
<slot name="a"></slot>
<slot name="b"></slot>
举个简单的具名插槽的例子
<div id="root">
<item>
<div class="header" slot="header"><h1>header</h1></div>
<div class="footer" slot="footer">footer</div>
</item>
</div>
<script type="text/javascript">
Vue.component('item',{
template: `<div>
<slot name="header"></slot>
body
<slot name="footer"></slot>
</div>`
})
var vm = new Vue({
el: '#root',
})
</script>
这个的结果就是
作用域插槽:
使用场景:
子组件遍历展示,并且DOM是从父组件传入的时候,
或者说,同一个组件在不同地方使用,需要展现不同的样子。
作用域插槽在父组件中一定要用<template slot-scope="props"></template>
包裹且必须定义slot-scope="name"来接收子组件中的数据。
例如无序列表输出1234
<div id="root">
<child>
<template slot-scope="props">
<li>{{props.item}}</li>
</template>
</child>
</div>
<script type="text/javascript">
Vue.component('child',{
data: function () {
return {
list: [1,2,3,4]
}
},
template: `<div>
<ul>
<slot
v-for="item of list"
:item="item"
></slot>
</ul>
</div>`
})
var vm = new Vue({
el: '#root',
})
</script>
动态组件
动态组件:<component :is="name"></component>
注:Vue自带默认的动态组件。
它用:is 绑定data数据,动态的切换组件。data数据是子组件的名称。