组件之间数据共享
数据共享(只要执行了emit(‘事件名称’)这行代码就表示触发了$emit里面自定义的事件)
1. 父组件向子组件共享数据
a) 在子组件中props属性下的定义自定义属性,
b) 在父组件中调用子组件,用标签的形式进行调用
c) 通过在父组件中给调用的子组件标签添加自定义属性,通过绑定v-bind进行动态赋值
d) 这个自定义属性是在子组件中定义的,父组件中只管数据
e) 这样就可以父组件向子组件进行数据共享
f) 如果数据共享中有对象的话,就是把对象进行引用,并不是直接赋值,子组件中的属性和父组件中的是对象指向的都是同一个地址
g) 如果传递的是简单类型的数据如字符串、数字等,就是直接复制一份直接赋值,子组件和父组件之间的数据相互独立
<template>
<!-- 父组件Father -->
<div>
<h3>这是父组件</h3>
<Son :name="name" :age="age"></Son>
</div>
</template>
<script>
import Son from '@/components/Son.vue'
export default {
name: 'Father',
data() {
return {
name: '张三',
age: 20
}
},
components: {
Son
}
}
</script>
<style></style>
<template>
<!-- 这是子组件Son -->
<div>
<h3>这是子组件</h3>
<h3>这是父组件传递过来的值{{ name }}-{{ age }}</h3>
</div>
</template>
<script>
export default {
name: 'Son',
props: ['name', 'age']
}
</script>
<style></style>
2. 子组件向父组件共享数据
a) 在子组件的事件回调函数中调用this.$emit()方法定义自定义方法,有两个参数,第一个参数是事件名,第二个参数是需要传递的数据,
b) 在父组件中为调用的子组件绑定事件,使用@绑定事件,这个事件就是在子组件中调用this.$emit()创建的事件,
c) 只要触发了这个事件,就会调用回调函数,这个回调函数接收一个参数,这个参数就是调用this.$emit()时传递过来的第二个参数
d) 可以通过this.$off('事件名')解绑自定义事件,这样自定义事件就不会再被触发
<template>
<!-- 父组件Father -->
<div>
<h3>这是父组件</h3>
<Son @Father="addD"></Son>
<h3>这是子组件传递过来的数据{{ a }}</h3>
</div>
</template>
<script>
import Son from '@/components/Son.vue'
export default {
name: 'Father',
data() {
return {
a: ''
}
},
methods: {
addD(val) {
this.a = val
console.log(val)
}
},
components: {
Son
}
}
</script>
<style></style>
<template>
<!-- 这是子组件Son -->
<div>
<h3>这是子组件</h3>
<button @click="add">向父组件传递数据</button>
</div>
</template>
<script>
export default {
name: 'Son',
data() {
return {
a: 11
}
},
methods: {
add() {
//触发Father这个事件,传递过去一个参数a
this.$emit('Father', this.a)
// console.log(11)
}
}
}
</script>
<style></style>
3.兄弟组件之间共享数据
a) 使用eventBus进行兄弟组件之间的数据共享
i. 使用步骤
1. 创建一个eventBus.js的模块,在这个模块中导入vue ,并向外共享一个vue的实例对象
2. 在数据发送方导入eventBus这个模块并使用bus这个常量接收,调用bus.$emit(‘事件名称‘,’要发送的数据‘)方法,触发自定义事件
3. 数据接收方,在created函数方法中调用bus.$on(‘事件名称’,‘事件处理函数‘)方法,注册一个自定义事件,
4. ref引用
a) 在vue中强烈不推荐使用jquery来操作DOM元素
b) 在vue中很少有操作dom的时候,如果遇到了,直接使用ref对DOM元素进行引用
i. 使用this.$refs如果要在mouend()中使用,必须要在this.$nextTick(()=>{ } ) 这里面实现,要不是找不到ref,原因是mouned()之后,BOM节点还没有完全挂载上,于是找不到定义的ref。
ii. 可以直接在updata()的生命周期函数中使用,不用写this.$nextTick(()=>{ } )
iii. 在methods:{ } 方法中使用,也需要使用this.$nextTick(()=>{ } ) 等到页面完全渲染完毕之后在调用即可
iv. 在需要操作的DOM元素标签上,加上一个ref的属性,属性值自取,然后通过调用this.$refs这个方法,就可以选中带有ref属性的DOM标签元素,如果想选中具体的标签,就调用this.$refs.ref属性值就可以选中指定DOM标签元素
c) 使用ref也可以引用子组件
i. 给调用的子组件添加ref属性,属性值自取,添加了ref属性之后,就可以通过this.$refs.属性值 得到该子组件的实例对象,然后就可以调用该子组件中的任何数据
5. This.$newTick(cb)方法
a) 这个方法可以延迟执行cb这个回调函数,延迟到下一个DOM更新完成之后,好处:可以保证cb这个回调函数可以操作到最新的DOM元素,这里的this就是vue实例对象