这里写目录标题
- 一、props:父组件向子组件传递数据(常用)
- 二、$emit:子组件向父组件传递数据(常用)
- 三、vuex:状态管理,实现多个组件进行数据共享(常用,重点)
- 四、eventBus:常用于多层嵌套组件场景下兄弟组件或任意两个组件之间通讯(事件总线)
- 五、ref:通过$refs可以拿到子组件的实例,从而调用实例里的方法来实现父子组件通信
- 六、provide / inject:通过依赖注入(inject / provide)的方式,向其所有子孙后代传递数据
- 七、attrs/listeners
- 八、$children / $parent
一、props:父组件向子组件传递数据(常用)
缺点:若组件嵌套层次多,传递数据比较麻烦
- 父组件
<template><child :message="message"></child></template><script>import Child from './Child.vue'export default {components: {Child},data() {return {message: '父组件'}}}</script>
- 子组件Child
<template><div><span>{{message}}</span></div></template><script>export default {props: {message: {type: String,default: '子组件'}}}</script>
二、$emit:子组件向父组件传递数据(常用)
- 父组件
<template><child :num="num" @addCount="addCount"></child>
</template>
<script>
import Child from "./Child.vue";
export default {components: {Child},data() {return {num: 100};},methods: {addCount(res) {//将子组件传来的参数复制给numthis.num = res;}}
};
</script>
- 子组件Child
<template><div><el-button type="primary" @click="addCount">{{ count++ }}</el-button></div>
</template>
<script>
export default {props: {num: {type: Number,default: 0}},data() {return {num: 100};},methods: {addCount() {//将num传给父组件this.$emit("addCount", this.num + 1);}}
};
</script>
三、vuex:状态管理,实现多个组件进行数据共享(常用,重点)
- store.js
import Vuex from "vuex";
import createPersistedState from 'vuex-persistedstate'
Vue.use(Vuex);
const store = new Vuex.Store({state: {//基本数据,用来存储变量。count: 0,list: [{ id: 1, is: false },{ id: 2, is: true }]},getter: {//Getter类似于Vue的computed对象。是根据业务逻辑来处理State,使得生成业务所需的属性。listFilter: (state, getters) => {return state.list.filter(res => res.is);}},mutations: {//更改vuex的store中的状态的唯一方法,只能是同步操作。increment(state, payload) {state.count += payload;}},actions: {//Action 提交的是 mutation,而不是直接变更状态;//Action 可以包含任意异步操作。addCount({ commit }) {// context ({ dispatch, commit })是一个与 store 实例具有相同方法和属性的 context 对象setTimeout(() => {commit("increment");}, 1000);}//Action处理异步的正确使用方式// async actionA({ commit }) {// commit('gotData', await a())// },// async actionB({ dispatch, commit }) {// await dispatch('actionA') // 等待 actionA 完成// commit('gotOtherData', await b())// }},module: {//模块化,module可以将store 分割成模块,每个模块中拥有自己的 state、mutation、action 和 getter},//持久化plugins: [createPersistedState()],
});
- 将store注入到根实例
// 注入到根实例-入口文件
new Vue({el: '#app',store,template: '<App/>',components: { App }
})
- 组件A
<template><div><el-button type="primary" @click="addCount"></el-button></div>
</template>
<script>
import { mapMutations, mapActions } from "vuex";
export default {// 原始写法// methods: {// //改变状态count// addCount() {// this.$store.commit("increment", 5);// this.$store.dispatch({// type: "incrementAsync"// });// }// }// };//mapMutations 辅助函数 获取
//mapActions 辅助函数 获取methods: {//方式1// ...mapMutations(["increment"]),//方式2...mapMutations({// userInfo 是一个重新定义的别名,本组件可以直接调用这个方法名字使用increment1: "increment",}),//mapActions写法同mapMutation...mapActions(["incrementAsync"]),//改变状态countaddCount() {this.increment1(5);// 以对象形式分发Actionthis.incrementAsync(5);},},
};
</script>
- 组件B
<template><div>{{ count }}{{ listFilter }}</div>
</template>
<script>
import { mapState, mapGetters } from "vuex";
export default {// 原始写法// computed: {// count() {// // 获取vuex里的count// return this.$store.state.count;// },// listFilter() {// // 获取vuex里的listFilter// return this.$store.getters.listFilter;// },// }//mapState 辅助函数 获取//mapGetters 辅助函数 获取computed: {// 注意:这种写法用mapstate等这种辅助函数的时候,前面的方法名和获取的属性名是一致的...mapState(["count"]),...mapGetters(["listFilter"]),},
};
</script>
- 模块化:将 store 分割为模块(module),每个模块拥有自己的 state 、 getters 、mutations 、actions 。(开发常用)
四、eventBus:常用于多层嵌套组件场景下兄弟组件或任意两个组件之间通讯(事件总线)
缺点:不支持响应式, $on事件不会自动清楚销毁的,需要手动来销毁,可在beforeDestroy中解绑监听,避免重复触发。
- 入口文件添加事件总线
import Vue from 'vue';
// 添加事件总线
Vue.prototype.$eventBus = new Vue();
- 组件A
<template><div>{{ a }}</div>
</template><script>
export default {data() {return {a: "",};},create() {this.$eventBus.$on("message", (res) => {//组件b传过来的参数this.a = res;console.log("收到消息!");});},// 组件销毁时需要解绑监听beforeDestroy() {eventBus.$off("message");},
};
</script>
- 组件B
<template><div><span>{{a}}<span></div></template><script>export default {data() {return {a: '兄弟组件'};},create() {this.eventBus.$emit('message',a)}};</script>
五、ref:通过$refs可以拿到子组件的实例,从而调用实例里的方法来实现父子组件通信
- 父组件
<template><el-button type="primary" @click="get">通过ref获取子组件实例</el-button>哦那个子组件获取的: {{ num }}<child ref="child"></child>
</template>
<script>
import Child from "./Child.vue";
export default {components: {Child},data() {return {num: 100};},methods: {get() {this.num = this.$refs.child.num;}}
};
</script>
- 子组件Child
<template><div><el-button type="primary" @click="addCount">{{ num }}</el-button></div>
</template>
<script>
export default {data() {return {num: 100};},methods: {addCount() {this.num++;}}
};
</script>
待补充
六、provide / inject:通过依赖注入(inject / provide)的方式,向其所有子孙后代传递数据
缺点:无法监听数据修改的来源,不支持响应式。
- 父组件
<template><el-button type="primary" @click="get">通过ref获取子组件实例</el-button>哦那个子组件获取的: {{ num }}<child ref="child"></child>
</template>
<script>
import Child from "./Child.vue";
export default {components: {Child},// 提示:provide 和 inject 绑定不支持响应式。provide() {return {// 传过去的必须是可监听的对象,注意,是对象,其他类型都不行user: this.userInfo};},data() {return {userInfo: {id: "1"}};},methods: {get() {this.userInfo.name= "小明";}}
};
</script>
- 子组件Child
<template><div>{{ user.name}}</div>
</template>
<script>
export default {inject: ["foo"]
};
</script>
七、attrs/listeners
自行查阅资料
八、$children / $parent
自行查阅资料