【问题标题】:Make computed property available to all components使计算属性可用于所有组件
【发布时间】:2020-05-06 18:01:40
【问题描述】:

有没有办法让计算属性全局可用?

例如:假设 Vuex 商店中有一个“isAdmin”属性,我们可以使用 getter 访问它。并且这个属性在很多组件中用于条件渲染。如何使其可用于所有组件,而不是在每个组件计算属性中声明它?

【问题讨论】:

  • 按照文档中的建议使用事件中心:vuejs.org/v2/guide/…
  • 创建一个mixin并全局注册
  • this.$store.getters.isAdmin 怎么样?或查看mapState 助手。
  • @YomS。问题不是如何访问 store 属性,而是如何让这个属性在所有组件模板中直接可用,而不必在每个计算的组件中添加 getter。 Nguyen You的上述建议是经过深思熟虑的
  • @mohsen 我同意,Nguyen You 的建议很好,而且this.$store.getters.isAdmin 也可以直接跨所有组件访问,无需注册。

标签: javascript vue.js vuex


【解决方案1】:

已经有人建议您可以使用全局 mixin 来执行此操作。这会起作用,但这不是唯一的方法。

虽然不太可能对性能产生重大影响,但为此使用计算属性似乎有点浪费。每个组件都有自己的计算属性,并且每个组件都会保留该值的缓存副本。但值都是一样的。

此外,store getter 已经在那个阶段缓存了值,所以在计算属性级别缓存并不能真正为我们节省任何东西。

相反,我们可以向 Vue 原型添加一个 JavaScript 属性 getter,通过代理来存储属性。从技术上讲,它不是一个计算属性,但它的工作原理大致相同:

// These 5 lines are the important bit, the rest is just for demonstration purposes
Object.defineProperty(Vue.prototype, '$isAdmin', {
  get () {
    return this.$store.getters.isAdmin
  }
})

const store = new Vuex.Store({
  state: {
    isAdmin: false
  },
  
  mutations: {
    toggle (state) {
      state.isAdmin = !state.isAdmin
    }
  },
  
  getters: {
    isAdmin (state) {
      return state.isAdmin
    }
  }
})

new Vue({
  el: '#app',
  store,
  
  methods: {
    onClick () {
      this.$store.commit('toggle')
    }
  },
  
  watch: {
    $isAdmin () {
      console.log('$isAdmin watcher triggered')
    }
  }
})
<script src="https://unpkg.com/vue@2.6.11/dist/vue.js"></script>
<script src="https://unpkg.com/vuex@3.1.1/dist/vuex.js"></script>

<div id="app">
  <p>{{ $isAdmin }}</p>
  <button @click="onClick">Change</button>
</div>

有一个潜在的主要障碍。由于 Vuex 在内部使用 Vue 实例,因此在原型上定义的 isAdmin 属性将与 Vuex 在幕后用于 isAdmin getter 的自动生成的计算属性发生冲突。在上面的示例中,我通过调用组件属性 $isAdmin 来避开了这个问题。理论上,这个问题也可以通过在商店创建后定义原型属性来避免。

【讨论】:

    猜你喜欢
    • 2013-03-19
    • 1970-01-01
    • 2018-01-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-08-11
    • 2018-07-05
    • 2020-02-05
    相关资源
    最近更新 更多