关于前端:再也不用担心组件跨层级的数据共享和方法驱动了

31次阅读

共计 3326 个字符,预计需要花费 9 分钟才能阅读完成。

我的项目中对于组件的应用常常会碰到这种状况:父子组件传和办法调用、兄弟组件的传值和办法调用、多个独立组件的数据共享和办法调用,例如: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

框架:vue3
vuex中能够存储全局数据以及事件,咱们能够在任何页面拜访 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 组件封装(👈点击中转)
微信小程序的全局弹窗以及全局实例(👈点击中转)

如果感觉这篇文章对你有帮忙,欢送点赞👍、珍藏💖、转发✨哦~

正文完
 0