科学处理多个 Vue 项目中共用的组件的 Events 和 Vuex

发布时间:2019-05-07 发布网站:脚本宝典
脚本宝典收集整理的这篇文章主要介绍了科学处理多个 Vue 项目中共用的组件的 Events 和 Vuex脚本宝典觉得挺不错的,现在分享给大家,也给大家做个参考。
小宝典致力于为广大程序猿(媛)提供高品质的代码服务,请大家多多光顾小站,小宝典在此谢过。

我们在做项目的时候,应该会有这种情况:

"我写了一个组件,然后做成了 npm 包,然后给好几个项目一起用。"

Vue 组件也是可以这么干的,所以在公司内部可能会将组件封装成 npm 模块后分发给各个项目。

不过在 Vue 的项目中,有两个小地方可能需要精心处理下 (●’◡’●)

当公共组件使用 EventBus 时

EventBus 并不是什么独立的东西,而是 Vue 的事件系统的一个最佳实践,算是一种使用方式:

/**  * EventBus.  * src/event-bus.js  */ export default new Vue({})   /**  * 我的公用组件 my-component.  */ import EventBus From 'src/event-bus'  export default {   ...   methods: {     // 触发叫做 "SomeModule:SomeEvent" 的事件并传了值 "Yeah~" 过去~     triggerSomeEvent () {       EventBus.$emIT('SomeModule:SomeEvent', 'Yeah~')     },      // 为我的组件注册两个事件~     registerevents () {       EventBus.$on('MyComponent:Event-01', value => {         console.LOG('Event-01 in MyComponent: ', value)       }),        EventBus.$on('MyComponent:Event-02', value => {         console.log('Event-02 in MyComponent: ', value)       })     }   },    created () {     this.registerEvents()   } }

当我们的公用模块在使用 EventBus 的时候,会有一个微小的问题,看这句话:

import EventBus from 'src/event-bus'

我怎么保证在使用我当前模块的不同的项目中的 EventBus 的路径都是 src/event-bus 呢?

所以,我们需要抽象一层,让模块并不关心这个 EventBus 是从哪里引入的:

// 我们将 EventBus 做成插件,这样就可以在项目的任何组件内使用了. // 起名叫 $events. // 当检测到 $events 存在的时候就使用,不存在的时候使用其他方法.  /**  * 我们将 event-bus 封装为一个插件.  * plugin/event-bus.js  */ export default {   install (Vue) {     const EventBus = new Vue({})     Vue.PRototyPE.$events = EventBus     Vue.EventBus = EventBus   } }  /**  * 所以我的公用组件 my-component 要变为:  */ export default {   ...   methods: {     // 触发叫做 "SomeModule:SomeEvent" 的事件并传了值 "Yeah~" 过去~     triggerSomeEvent () {       if (this.$events) {         this.$events.$emit('SomeModule:SomeEvent', 'Yeah~')               } else {         // 其他方式...       }     },      // 为我的组件注册两个事件~     registerEvents () {       if (this.$events) {         this.$events.$on('MyComponent:Event-01', value => {           console.log('Event-01 in MyComponent: ', value)         }),          this.$events.$on('MyComponent:Event-02', value => {           console.log('Event-02 in MyComponent: ', value)         })       } else {         // 其他方式...       }     }   },    created () {     this.registerEvents()   } }  /**  * 项目入口.  * src/index.js  */ import Vue from 'vue' import EventBus from 'plugin/event-bus' import MyComponent from 'my-component'  Vue.use(EventBus)  const Root = new Vue({   components: {     MyComponent   },    methods: {     DOSomething () {       this.$events.$emit('MyComponent:Event-01', 'FA♂')     }   } })

OK,这样我们的组件就可以在不同项目中适应 EventBus 了!

这里有一个组件 cklmercer/vue-events 就是解决这种问题而存在的.

当公共组件使用 Vuex 时

这个问题仅仅存在于 Vue 1.0 的项目中,Vue 2.0 + Vuex 2.0 已经解决这个问题:

/**  * 我的公用组件 my-component.  */ import Store from 'src/vuex/store' import actions from 'src/vuex/actions' import getters from 'src/vuex/getters'  export default {   ...   store,    vuex: {     actions, getters   },    computed: {     userName () {       // "getUsername" 是 Vuex 中定义好的 getter.       return this.getUsername     }   },    methods: {     changeDatainvuexByUsingAction () {       // "setUserExperience" 是 Vuex 中定义好的 action.       this.setUserExperience(450)     }   } }

那么还是同样的问题,

我怎么保证在使用我当前模块的不同的项目中的 Vuex 的路径都是 src/vuex 呢?

所以方法一样啦,抽象出来引用路径,让模块并不关心是如何引入 Vuex 的:

// 我们将 Vuex 做成插件,这样就可以在项目的任何组件内使用了. // 起名叫 $vuexer. // 当检测到 $vuexer 存在的时候就使用 Vuex,不存在的时候就将数据写入组件自己内部的 state 中.  /**  * 我们将 event-bus 封装为一个插件.  * plugin/event-bus.js  */ export default {   install (Vue, { store, actions, getters }) {     const vuexer = new Vue({       store, actions, getters     })     Vue.prototype.$vuexer = vuexer     Vue.vuexer = vuexer   } }  /**  * 项目入口.  * src/index.js  */ import Vue from 'vue' import Vuexer from 'plugin/vuexer'  import store from 'src/vuex/store' import actions from 'src/vuex/actions' import getters from 'src/vuex/getters'  import MyComponent from 'my-component'  Vue.use(Vuexer, {   store, actions, getters })  const Root = new Vue({   components: {     MyComponent   },    computed: {     userExperience () {       // "getExperience" 是在 Vuex 中定义好的 getter.       return this.$vuexer.getExperience     }   },    methods: {     changeUsernameinVuex () {       // "setUsername" 是在 Vuex 中定义好的 setter.       this.$vuexer.setUsername('John Smith')     }   } })  /**  * 我的公用组件 my-component.  */ export default {   data () {     return {       _userName: '神秘用户',       _userExperience: 65535     }   },    computed: {     userName () {       // 如果有 Vuexer, 如果木有 Vuexer...       return this.$vuexer         ? this.$vuexer.getUsername         : this._userName     }   },    methods: {     // 如果有 vuexer, 如果木有 Vuexer...         changeDataInVuexByUsingAction () {       const userExperience = 450       if (this.$vuexer) {         this.$vuexer.setUserExperience(userExperience)       } else {         this._userExperience = userExperience       }     }   } }

妥!⁄(⁄ ⁄•⁄ω⁄•⁄ ⁄)⁄

至于为什么 Vue 2.0 + Vuex 2.0 木有这个问题:

// 在 Vue 2.0 中使用 Vuex 要这么写: // 创建一个组件. const Components = {   template: `<div>{{ count }}</div>`,   computed: {     count () {       return this.$store.getters.doneTodosCount  // 这是一个 getter.     }   } }

注意 computed 中的 return this.$store.getters.doneTodosCount,看看其中的 this.$store

是不是和 this.$vuexer 有点像? (°∀°)ノ

这里还有一个组件 lancercomet/vuexer 就是为 Vue 1.0 解决这个问题的!

完结撒花~

By LancerComet at 01:22, 2017.01.21.

觉得可用,就经常来吧! 脚本宝典 欢迎评论哦!&nbsp;vue,巧夺天工,精雕玉琢。小宝典献丑了!

脚本宝典总结

以上是脚本宝典为你收集整理的科学处理多个 Vue 项目中共用的组件的 Events 和 Vuex全部内容,希望文章能够帮你解决科学处理多个 Vue 项目中共用的组件的 Events 和 Vuex所遇到的问题。

如果觉得脚本宝典网站内容还不错,欢迎将脚本宝典推荐好友。

本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。