Vuex:不同模板(module)之间分发 action 或提交 mutation

Vuex:不同模板(module)之间分发 action 或提交 mutation

场景:卖书的商城,在书籍商品显示详情页的时候需要去获取相关的作者信息,书籍表通过authorId字段关联作者表中的作者。所以考虑方案:在详情页先获取书籍信息,然后通过authorId去查找作者信息。

实现:创建两个状态管理的module:book.js 和 author.js ,然后在详情页:bookDetail.vue中去管理状态。

// author.js
export default {
  namespaced: true,
  state: {
    author: {}
  },
  getters: {},
  mutations: {
    setAuthor: function (state, author) {
      state.author = author
    }
  },
  actions: {
    getAuthorName: function ({ commit }, authorId) {
      Author.getAuthorById(authorId, author => {
        commit('setAuthor', author)
      })
    }
  }
}

// book.js
export default {
  namespaced: true,
  state: {
    // 正在查看的书本详情
    currentBook: {}
  },
  getters: {
  	// ...
    showBook (state) {
      return state.currentBook
    }
  },
  mutations: {
    // ...
    setCurrentBook (state, book) {
      state.currentBook = book
    }
  },
  actions: {
    // ...
    // 根据id获取书籍详情
    getBookDetailById ({ commit, dispatch }, id) {
      // Shop.getBookDetailById是api
      Shop.getBookDetailById (id, book=> {
        commit('setCurrentBook', book)
        // 获取作者详情
        // todo: {root:true} 很重要,如果没有添加的话,此处会报错
        dispatch('BookDetail/getAuthorName', book.authorId, { root: true })
      })
    }
  }
}

刚开始做的时候没有加{ root : true }导致报错,查找文档资料后发现以下描述:

在带命名空间的模块内访问全局内容(Global Assets)
如果你希望使用全局 state 和 getter,rootState 和 rootGetter 会作为第三和第四参数传入 getter,也会通过 context 对象的属性传入 action。
若需要在全局命名空间内分发 action 或提交 mutation,将 { root: true } 作为第三参数传给 dispatch 或 commit 即可。

所以需要分发其他模板的action或者提交其他模板的mutation的时候,需要加上{ root: true }

然后只需在bookDetail.vue页面去获取状态即可

// bookDetail.vue
export default {
  name: 'ProductDetail',
  state: {
    return () {
    	// ...
    	'bookId': '201903190001'
    }
  },
  computed: {
    // ...
    // 获取当前书籍信息 
    // 可直接通过 this.book 使用
    ...mapState('book', {
      book: 'currentBook'
    }),
    // 获取作者信息 
    // 可直接通过 this.author 使用
    ...mapState('author', {
      author: 'author'
    })
  },
  methods: {
  	// ...
    ...mapActions({
      getBookDetailById: 'book/getBookDetailById'
    })
  },
  created () {
    // 获取商品详情
    this.getBookDetailById(this.bookId)
  }
}
</script>
...
}

你可能感兴趣的:(Vue)