Vue学习:给组件绑定原生事件与非父子组件间的传值
一、组件绑定原生事件
1.1 点击无效,属于组件间定义的事件为自定义事件
<body>
<div id="app">
<!--这里绑定的是自定义事件,点击无效-->
<child @click="handleClick"></child>
</div>
</body>
<script>
Vue.component('child',{
//在div上添加原生事件,点击生效
template:'<div @click="handleChildClick">Child</div>',
methods:{
handleChildClick:function(){
alert('child click')
}
}
})
var vm = new Vue({
el:"#app",
methods:{
handleClick:function(){
alert('click')
}
}
})
</script>
1.2 使用emit向外触发
Vue.component('child',{
//在div上添加原生事件,点击生效
template:'<div @click="handleChildClick">Child</div>',
methods:{
handleChildClick:function(){
alert('child click'),
//触发自定义事件
this.$emit('click')
}
}
})
1.3 改进代码,添加事件修饰符
<body>
<div id="app">
<!--说明这是原生的点击事件-->
<child @click.native="handleClick"></child>
</div>
</body>
<script>
Vue.component('child',{
template:'<div>Child</div>',
})
var vm = new Vue({
el:"#app",
methods:{
handleClick:function(){
alert('click')
}
}
})
</script>
二、非父子组件间的传值
2.1 功能与问题
需要实现点击Derrick的时候显示Jessica,点击Jessica的时候显示Derrick,这时候便需要两个非父子组件之间传递值
<body>
<div id="app">
<child content="Derrick"></child>
<child content="Jessica"></child>
</div>
</body>
<script>
Vue.component('child',{
props:{
content:String
},
template:'<div>{{content}}</div>',
})
var vm = new Vue({
el:"#app",
})
</script>
2.2 总线机制解决非父子组件间传值
在生成vue实例前,给Vue的原型上添加一个bus属性,这个属性是vue的实例,之后创建的vue实例都具有bus这个属性
Vue.prototype.bus = new Vue()
实例上挂载的bus,每个实例都有bus属性,bus又是vue的实例,所以支持$emit,通过这个方法向外触发事件
this.bus.$emit('change',this.selfContent)
利用钩子函数绑定监听事件,因为this的指向发生了变化,不用箭头函数的话就要先把this保存起来,监听bus触发的事件,会触发两次,因为上面两个组件都会进行监听
mounted:function(){
//function里面作用域变化
var this_= this
//监听bus触发的事件,会触发两次,因为上面两个组件都会进行监听
this.bus.$on('change',function(msg){
this_.selfContent = msg
})
}
整体代码如下:
<body>
<div id="app">
<child content="Derrick"></child>
<child content="Jessica"></child>
</div>
</body>
<script>
//把prototype挂载的bus属性指向Vue的实例
Vue.prototype.bus = new Vue()
Vue.component('child',{
data:function(){
return {
//单项传值,避免下面修改父组件的传值
selfContent:this.content
}
},
props:{
content:String
},
template:'<div @click="handleClick">{{selfContent}}</div>',
methods:{
handleClick:function(){
//实例上挂载的bus,每个实例都有bus属性,bus又是vue的实例,所以支持$emit
//通过这个方法向外触发事件
this.bus.$emit('change',this.selfContent)
}
},
//钩子
mounted:function(){
//function里面作用域变化
var this_= this
//监听bus触发的事件,会触发两次,因为上面两个组件都会进行监听
this.bus.$on('change',function(msg){
this_.selfContent = msg
})
}
})
var vm = new Vue({
el:"#app",
})
</script>