在讲Vue组件中常见的三种传值方式前,我们需要先知道用它们的好处,这样我们才会更有动力去学它。
好处:对于一些复用性很高的功能,我们可以将它封装起来调用,在js中我们是用函数来封装的,而在Vue组件中,我们就可以用组件来封装它们,这样会让页面看起来更加整洁,所以我们需要学会给组件之间传值来灵活运用它们
1、 父传子
简单概述:
父组件是通过props属性给子组件通信的
数据是单向流动 父—>子 (子组件中修改props数据,是无效的,会有一个红色警告)
实现步骤:
1.子组件在props中创建一个属性,用于接收父组件传过来的值;
2.父组件 引入子组件–>注册子组件–>引用子组件;
3.在子组件标签中添加子组件props中创建的属性;
4.将所要传递的值赋值给该属性。
父组件
<template>
<div class="fatherBox">
<son-box :item="list"></son-box>
</div>
</template>
<script>
import sonBox from "@/components/ChildView.vue";
export default {
props: {},
components: {
sonBox,
},
data() {
return {
list: ["a", "b", "c", "d"],
};
},
methods: {},
};
</script>
子组件接收有两种方式
- 以数组形式接收(只是简单的接收)
<template>
<div class="sonBox">父组件传过来的: {{ item }}</div>
</template>
<script>
export default {
components: {},
props: ['item'],
data() {
return {};
},
methods: {},
};
</script>
- 以对象形式接受(可以设置要传递的数据类型和默认值)
export default {
props: {
item:{
typeof: Array,
default:()=>[]
}
},
};
2、 子传父
简单概述:
父组件通过绑定自定义事件,接受子组件传递过来的参数
子组件通过$emit触发父组件上的自定义事件,发送参数
实现步骤:
- 子组件通过绑定事件触发函数,设置this.$emit('要派发的自定义事件',要传递的值)
- 父组件在
子组件标签
上@派发的自定义事件 - 绑定事件触发的methods中的方法接收的默认值,就是传递过来的默认值
父组件
<template>
<div class="fatherBox">
<son-box @list="list"></son-box>
<p>父组件接受到的内容{{ item }}</p>
</div>
</template>
<script>
import sonBox from "@/components/ChildView.vue";
export default {
components: {
sonBox,
},
data() {
return {
item:[]
};
},
methods: {
list(val){
console.log(val);
this.item=val
}
},
};
</script>
子组件
<template>
<div class="sonBox">
<button @click="changeFn">向父组件发送</button>
</div>
</template>
<script>
export default {
data() {
return {
list: ["a", "b", "c", "d"],
};
},
methods:{
changeFn(){
this.$emit('list', this.list)
}
}
};
</script>
点击向父组件发送的按钮,页面上就能得到传递过来的数据:
3、 兄弟之间传值
兄弟之间传值方式也有两种
1. 通过event.bus实现
实现步骤 :
1、创建一个空的vue并暴露出去,这个作为公共的bus,即当作两个组件的桥梁
import Vue from "vue"
export default new Vue()
2、在两个兄弟组件中分别引入刚才创建的bus,在组件A中通过bus.$emit
('自定义事件名',要发送的值)
<template>
<div class="pageA">
<button @click="changeFn"> A组件</button>
</div>
</template>
<script>
import bus from "@/utils/eventBus"
export default {
methods:{
changeFn(){
bus.$emit('message','hello world!')
}
}
}
</script>
3、在组件B中通过bus.$on
('自定义事件名',(val)=>{}) 接收数据 val就是要接收的值
<template>
<div class="pageB">
<h3>B组件接收的值: {{ name }}</h3>
</div>
</template>
<script>
import bus from "@/utils/eventBus"
export default {
data(){
return{
name:''
}
},created(){
bus.$on('message',(val)=>{
this.name=val
})
}
}
</script>
2. 通过vuex来实现
Vuex 的状态存储是响应式的。当 Vue 组件从 store 中读取状态的时候,若 store 中的状态发生变化,那么相应的组件也会相应地得到高效更新。
一般情况下只有组件之间的共享的数据,才有必要方法在vuex中,对于组件中的数据还是存放在组件自身的data中就可以
实现步骤 :
1、A组件 通过辅助函数mapMutations 进行vuex存储
<template>
<div class="pageA">
<button @click="changeFn"> A组件</button>
</div>
</template>
<script>
import { mapMutations} from "vuex"
export default {
data(){
return{
name:"大宝"
}
},
methods:{
...mapMutations(['setName']),
changeFn(){
this.setName(this.name)
}
}
}
</script>
2、B组件 通过辅助函数mapState 进行获取数据
<template>
<div class="pageB">
<h3>B组件接收的值: {{ name }}</h3>
</div>
</template>
<script>
import { mapState } from "vuex"
export default {
computed: {
...mapState(['name'])
},
}
</script>
安装 Vuex 之后,创建一个 store
import Vue from "vue";
import Vuex from "vuex";
import persist from "vuex-persistedstate";
Vue.use(Vuex);
export default new Vuex.Store({
state: {
name: '',
},
getters: {},
mutations: {
setName(state, values) {
state.name = values;
},
},
actions: {},
modules: {
},
plugins: [
persist({
storage: window.localStorage,
}),
],
});