组件是 vue.js 最强大的功能之一,而组件实例的作用域是相互独立的,这就意味着不同组件之间的数据无法相互引用。一般来说,组件可以有以下几种关系:
如上图所示:
(1)父子关系:A 和 B、B 和 C、B 和 D
(2)兄弟关系:C 和 D
(3)隔代关系(可能隔多代):A 和 C 是
方法一:
1. 父组件向子组件传值props
通过 Prop 向子组件传递数据
2. 子组件向父组件传值(自定义事件$emit/v-on
)
父级组件可以像处理 native DOM 事件一样通过 v-on 监听子组件实例的任意事件:
父组件:
<blog-post
...
v-on:enlarge-text="postFontSize += 0.1"
></blog-post>
子组件
<button v-on:click="$emit('enlarge-text')">
Enlarge text
</button>
使用事件抛出一个值
可以使用 $emit 的第二个参数来提供这个值
<button v-on:click="$emit('enlarge-text', 0.1)">
Enlarge text
</button>
我们可以通过 $event 访问到被抛出的这个值:
<blog-post
...
v-on:enlarge-text="postFontSize += $event"
></blog-post>
或者,如果这个事件处理函数是一个方法:
<blog-post
...
v-on:enlarge-text="onEnlargeText"
></blog-post>
那么这个值将会作为第一个参数传入这个方法:
methods: {
onEnlargeText: function (enlargeAmount) {
this.postFontSize += enlargeAmount
}
}
相关
有时也需要在内联语句处理器中访问原始的 DOM 事件。可以用特殊变量 $event 把它传入方法:
<button v-on:click="warn('Form cannot be submitted yet.', $event)">
Submit
</button>
methods: {
warn: function (message, event) {
// 现在我们可以访问原生事件对象
if (event) {
event.preventDefault()
}
alert(message)
}
}
方法二、$emit
/$on(中间件)
这种方法通过一个空的Vue实例作为中央事件总线(事件中心),用它来触发事件和监听事件,巧妙而轻量地实现了任何组件间的通信,包括父子、兄弟、跨级。当我们的项目比较大时,可以选择更好的状态管理解决方案vuex。
var Event=new Vue();
Event.$emit(事件名,数据);
Event.$on(事件名,data => {});
<div id="itany">
<my-a></my-a>
<my-b></my-b>
<my-c></my-c>
</div>
<template id="a">
<div>
<h3>A组件:{{name}}</h3>
<button @click="send">将数据发送给C组件</button>
</div>
</template>
<template id="b">
<div>
<h3>B组件:{{age}}</h3>
<button @click="send">将数组发送给C组件</button>
</div>
</template>
<template id="c">
<div>
<h3>C组件:{{name}},{{age}}</h3>
</div>
</template>
<script>
var Event = new Vue();//定义一个空的Vue实例
var A = {
template: '#a',
data() {
return {
name: 'tom'
}
},
methods: {
send() {
Event.$emit('data-a', this.name);
}
}
}
var B = {
template: '#b',
data() {
return {
age: 20
}
},
methods: {
send() {
Event.$emit('data-b', this.age);
}
}
}
var C = {
template: '#c',
data() {
return {
name: '',
age: ""
}
},
mounted() {//在模板编译完成后执行
Event.$on('data-a',name => {
this.name = name;//箭头函数内部不会产生新的this,这边如果不用=>,this指代Event
})
Event.$on('data-b',age => {
this.age = age;
})
}
}
var vm = new Vue({
el: '#itany',
components: {
'my-a': A,
'my-b': B,
'my-c': C
}
});
</script>
$on
监听了自定义事件 data-a和data-b,因为有时不确定何时会触发事件,一般会在 mounted 或 created 钩子中来监听。
(1)引入单独文件
util.js
import Vue from 'vue'
export default new Vue()
(2)import Util from '@/untils/util.js'
@click="enterpage()"
enterpage1 () {
Util.$emit('navMessage', 2, '2-2', '店铺管理', {pathname: 'Popstore', title: '店铺运营管理'})
},
Util.$on('navMessage', function (index, ind, value, item) {
that.goshare(index, ind, value, item)
})
方法三:vuex
方法四、provide/inject
方法五:ref(写在父组件中)
获取子组件中的数据和方法