我的项目中对于组件的应用常常会碰到这种状况:父子组件传和办法调用、兄弟组件的传值和办法调用、多个独立组件的数据共享和办法调用,例如:a、b
组件的的数据共享,该数据是由c
传出的,通过a、b
组件批改共享参数,调用c
办法实现a、b
组件的数据更新。本文总结了上述的几种状况并别离解说。
兄弟组件的传值和办法调用
框架:vue2
通过组件ref
调用组件内的办法
父组件
<template>
<div>
<MyA @save="save"></MyA>
<MyB ref="listNode"></MyB>
</div>
</template>
<--! js局部 -->
methods: {
save() {
// 通过ref调用兄弟组件的办法
this.$refs.listNode.submit();
}
}
组件一
// MyA
<el-button type="parimary" size="mini" @click="sure">确定</el-button>
// js
methods: {
sure() {
// 保留点击,数据通过$emit传出
this.$emit('save')
}
}
组件二
// MyB
<el-button type="parimary" size="mini" @click="submit">提交</el-button>
// js
methods: {
submit() {
console.log('办法被触发了')
}
}
A
组件通过emit
将办法回传,父组件触发A
组件回传的事件,在父组件中通过ref
在调用B
组件内的事件。
多个独立组件的数据共享和办法调用
多个组件内的办法和数据相互驱动:eventBus
框架:vue2
新建一个eventBus.js
,定义事件全局事件总线。
// eventBus.js
import Vue from 'vue'
export default new Vue();
// 该文件就两行
引入到main
文件,挂载到vue
原型上
// main.js
import Vue from 'vue'
import eventBus from '@/utils/eventBus.js'
// .....
Vue.prototype.$bus = eventBus // 挂载到原型
// ...
而后就能够在页面中应用了,应用的页面须要引入eventBus.js
// A组件
import bus from '@/utils/eventBus.js'
methods: {
// 分页
handleSizeChange(val) {
// 播送办法
bus.$emit('sizeChange',{page : val })
},
}
// B组件
import bus from '@/utils/eventBus.js'
created() {
// $off解绑
bus.$off( 'sizeChange' ); // 应用前先解绑,否则在某些状况下会触发两次
// $on监听触发
bus.$on('sizeChange', (val) => {
// 事件内的操作....
this.getTable(val);
})
},
methods: {
getTable(val) {
// 通过bus触发
console.log(val); // { page: val }
},
}
须要留神的是,
eventBus
的$on
事件须要在created
等生命周期中应用,如果写在methods
中使不会主动触发的。应用$on
事件的时候须要先解绑,否则页面刷新后监听事件没有解绑,后续再次播送事件会触发两次。解绑能够在beforeDestory
中操作也能够$off 后接 $on
解绑后监听
eventBus
相当于一个全局事件池,向全局事件池中增加和传入事件,事件池的事件能够作用于全局。
多个组件的数据共享以及数据批改:vuex
框架:vue3vuex
中能够存储全局数据以及事件,咱们能够在任何页面拜访vuex
中的事件和办法,随着我的项目继续保护,咱们不可能间接在store
中的index
中间接增加数据和办法,因而vuex
提供了module
性能,能够让咱们别离治理本人独立的module
模块。
官网上是这么说的:
因为应用繁多状态树,利用的所有状态会集中到一个比拟大的对象。当利用变得非常复杂时,store 对象就有可能变得相当臃肿。
为了解决以上问题,Vuex 容许咱们将 store 宰割成模块(module)。每个模块领有本人的 state、mutation、action、getter、甚至是嵌套子模块——从上至下进行同样形式的宰割。
npm install vuex@next --save
// sotre -> my_module
const my_module = {
state: () => ({
my_count : 0,
my_info : {
id : 1,
name : '我的模块'
}
}),
mutations: {
countChange(state,val) {
state.my_count += val
}
},
actions: {
// actions不间接批改数据
// context为store中的上下文,通过commit驱动mutations的办法来实现数据批改
countTen(context,num){
setTimeout(()=>{
context.commit('countChange',num.num)
},500)
}
},
getters: {
getMyName (state) {
return `这是${state.my_info.name}`
},
getMyCount (state) {
return `我的总数:${state.my_count}`
}
}
}
export default my_module;
// store -> index.js
import { createStore } from "vuex";
import my_module from "./my_module";
// 创立store实例
const store = createStore({
// 将my_module 挂载到modules中
modules: {
my_module
}
})
export default store;
// main.js
import { createApp } from 'vue'
import './style.css'
import App from './App.vue'
import store from './store/index' // 导入vuex
createApp(App)
.use(store) // 挂载vuex
.mount('#app')
// 页面中应用
<template>
<div>
<div>vuex——module</div>
<div>store中的值:{{ store.getters.getMyName }}</div>
<div>store中的值:{{ store.getters.getMyCount }}</div>
<button @click="addMyNum">count++</button>
<button @click="numMyTen">每次加10</button>
</div>
</template>
<script setup>
import { ref,computed} from "vue"
import { useStore} from 'vuex' // vue3中通过useStore应用store
const store = useStore();
// vuex-module
const addMyNum = () => {
store.commit('countChange',1)
}
const numMyTen = () => {
store.dispatch('countTen',{num:10})
}
</script>
vuex个别用来做全局状态治理,并不倡议向vuex中存储非全局的事件和办法,如果所有的跨组件事件和办法都向vuex中存储,随着我的项目的继续保护,store中的数据就会越来越多,会导致vuex保护老本变高。
vue3-setup组件传值 (👈点击中转)
微信小程序组件封装传值以及问题点躲避 (👈点击中转)
vue3 语法糖setup 兄弟组件传值(👈点击中转)
微信小程序wxs封装应用以及公共js组件封装 (👈点击中转)
微信小程序的全局弹窗以及全局实例(👈点击中转)
如果感觉这篇文章对你有帮忙,欢送点赞👍、珍藏💖、转发✨哦~
发表回复