vueX介绍

在使用单一状态树,应用的所有状态会集中到一个比较大的对象。当应用变得非常复杂时,store 对象就有可能变得相当臃肿。为了解决以上问题,Vuex 允许我们将 store 分割成模块(module)。每个模块拥有自己的state、mutation、action、getter、甚至是嵌套子模块——从上至下进行同样方式的分割:
注意:
//src根目录下的store.js不能删掉,但是可以注释掉不用

如何使用module

moduleA.js文件内容如下:

//在store文件夹下新建modules文件夹,并在下面建立moduleA.js和moduleB.js文件用来存放vuex的modules模块

const state = {
  stateA: 'A'
}
 
const mutations = {
  showA (state) {
    return state.stateA
  }
}
 
const actions = {
  showAAction (context) {
    context.commit('showA')
  }
}
 
const getters = {
  getA (state) {
    return state.stateA
  }
}
export default {namespaced: true,state, mutations, actions, getters}

moduleB.js文件内容如下:

const state = {
  stateB: 'B'
}
 
const mutations = {
  showA (state) {
    return state.stateB
  }
}
 
const actions = {
  showAAction (context) {
    context.commit('showB')
  }
}
 
const getters = {
  getA (state) {
    return state.stateB
  }
}
 
// namespaced 属性,限定命名空间
export default {namespaced: true,state, mutations, actions, getters}

或者
//方法2
export default {
  state:{
  moduleBstate: 'moduleBstate'
  },
  mutatons:{},
  actions:{},
  getters:{}
  // namespaced: true,//默认为false
}
//namespaced写成true,actions, mutations, getters, 可以限定在当前模块的命名空间中、意思就是可以用这个module名作为区分了(也就是module所在的文件夹名)
//比如import moduleA from './modules/moduleA/moduleA'//引进模块 moduleA文件夹名作为区分、作为当前模块的命名

store.js 文件内容如下:

//state mutations actions 可以分别独立j创建js文件,然后再引进store.js或者当前模块
import Vue from 'vue'
import Vuex from 'vuex'
import state from './state'
import mutations from './mutations' //引进独立创建的mutations .js
import getters from './getters'//引进独立创建的getters.js
import actions from './actions'//引进独立创建的actions.js
import moduleA from './modules/moduleA/moduleA'//引进模块
import moduleB from './modules/moduleB/moduleB'
 
Vue.use(Vuex)
 
const store = new Vuex.Store({
  state,//独立js文件
  mutations,//独立创建的mutations.js文件
  getters,
  actions,
  modules: {
    moduleA,
    moduleB
  }
 
export default store
//或者这样
export default new Vuex.Store({
  state: {
   a : true
  },
  mutations: {

  },
  actions: {

  },
  //vueX模块 
  modules:{
    moduleA,
    moduleB
  }
}) 
//一个js文件可以用两个或多个模块
const modules1 = {
    state: {
        a: '我是模块化1'
    },
    mutations: {},
    actions: {}
}
const modules2 = {
    state: {
        a: '我是模块化2'
    },
    mutations: {},
    actions: {}
}
export default {
    modules1,
    modules2
}

在组件中使用

<template>
  <div class="modules">
    <h1>{{moduleA}}  ---  {{moduleB}} --- {{getmoduleA}}</h1>

   //namespaced 属性,限定命名空间
   <h1 @click ="alertName">{{useName}}</h1>
   <button @click="changeName"> change to json</button>

  </div>
</template>
 
<script>
import {mapActions, mapState,mapGetters} from "vuex";
 
export default {
  data () {
    return {}
  },
  computed: {
    ...mapState({
      moduleA:  state => state.moduleA.stateA,
      moduleB:  state => state.moduleB.stateB
    })
    //命名空间写法
    ...mapState("moduleA",{//moduleA为命名空间,指定modules
      moduleA: state => state.moduleA.stateA,
    }),
   //指定imoduleA的getter
   getmoduleA() {
    return this.$store.getters["moduleA/getA "]
    }
   ...mapGetters("moduleA", ["getA "])
  },
  methods: {
    changeName() {
        this.$store.dispatch("moduleA/showAAction ", "moduleA")
   },
    ...mapActions('moduleA', ['showAAction '])
 }

}
</script>

store.js index.js,具体参考vue-DYNAMIC-ROUTING-DEMO

  modules: {
    moduleA,
    moduleB,
    moduleC,

  },
    // 获取指定模块state
    console.log(this.$store.state.moduleA.moduleAstate)
    console.log(this.$store.state.moduleB.modulesBstate);

    // 获取所有的state
    console.log(this.$store.state);
    // 获取所有的getters(包括模板的),不需要指定模块
    console.log(this.$store.getters);
    // 使用module中的getter
    // module中的getter,又分为namespaced(命名空间)为true和false的情况。
    // 默认为false, 则表示方位都是全局注册(this.$store.getters获取所有的getter)
    // 无法获取指定模板的getters,例如this.$store.getters["moduleA/moduleAstate2"]获取
    // 当为true时,可以获取指定模板getters,则使用如下方法:
    console.log(this.$store.getters["moduleA/moduleAstate2"]);

    // mutations 和 actions 也是分的模块
    // 使用module中的 actions和mutations,又分为namespaced(命名空间)为true和false的情况。
    // 默认为false, 则表示方位都是全局注册(this.$store.commit('mutationsAstate'))可以调用所有的mutations方法和action方法
    // 当为true时,可以调用指定模板mutations方法和action方法,则使用如下方法:
    this.$store.commit('moduleA/mutationsAstate');
    console.log("按钮权限-", this.$store.getters.buttonObj)

1、模块动态注册
在 store 创建之后,你可以使用 store.registerModule 方法注册模块:

// 注册模块 `myModule`
store.registerModule('myModule', {
  state:{},
  getters:{},
  mutations:{}
  actions{}
})
// 注册嵌套模块 `nested/myModule`
store.registerModule(['nested', 'myModule'], {

})

之后就可以通过 store.state.myModule 和 store.state.nested.myModule 访问模块的状态。模块动态注册功能使得其他 Vue 插件可以通过在 store 中附加新模块的方式来使用 Vuex 管理状态。例如,vuex-router-sync 插件就是通过动态注册模块将 vue-router 和 vuex 结合在一起,实现应用的路由状态管理。你也可以使用 store.unregisterModule(moduleName) 来动态卸载模块。注意,你不能使用此方法卸载静态模块(即创建 store 时声明的模块)。
2.卸载动态模块

this.$store.unregisterModule("myModule")

3.举个例子及实现demo


b1c29f3d57e94d4c2495d6d9ec8cee4.png

cb42203f0d0694a7bdfd54fab37ba0b.png

image.png

image.png

image.png

image.png

在 Vue 组件中获得 Vuex 状态:state

获取state的几种方法:
1

export default{
computed:{
        orderList(){
        return this.$store.state..;
    }
    }
}

2
mapState 辅助函数映射到当前组件:

import { mapState} from "vuex";
export default {
  // ...
  computed: mapState({
    // 箭头函数可使代码更简练
    count: state => state.count,

    // 传字符串参数 'count' 等同于 `state => state.count`
    countAlias: 'count',

    // 为了能够使用 `this` 获取局部状态,必须使用常规函数
    countPlusLocalState (state) {
      return state.count + this.localCount
    }
  })
}
//当映射的计算属性的名称与 state 的子节点名称相同时,我们也可以给 mapState 传一个字符串数组,意思就是直接使用this.count计算属性
computed: mapState([
  // 映射 this.count 为 store.state.count
  'count'
])

Getter

有时候我们需要从 store 中的 state 中派生出一些状态,处理一些数据、例如对列表进行过滤并计数:

computed: {
  doneTodosCount () {
    return this.$store.state.todos.filter(todo => todo.done).length
  }
}

如果有多个组件需要用到此属性,我们要么复制这个函数,或者抽取到一个共享函数然后在多处导入它——无论哪种方式都不是很理想。

Vuex 允许我们在 store 中定义“getter”(可以认为是 store 的计算属性)。就像计算属性一样,getter 的返回值会根据它的依赖被缓存起来,且只有当它的依赖值发生了改变才会被重新计算。

Getter 接受 state 作为其第一个参数:

const store = new Vuex.Store({
  state: {
    todos: [
      { id: 1, text: '...', done: true },
      { id: 2, text: '...', done: false }
    ]
  },
  getters: {
    doneTodos: state => {
      return state.todos.filter(todo => todo.done)
    }
  }
})

通过属性访问
Getter 会暴露为 store.getters 对象,你可以以属性的形式访问这些值:

store.getters.doneTodos // -> [{ id: 1, text: '...', done: true }]

Getter 也可以接受其他 getter 作为第二个参数:

getters: {
  // ...
  doneTodosCount: (state, getters) => {
    return getters.doneTodos.length
  }
}
store.getters.doneTodosCount // -> 1

我们可以很容易地在任何组件中使用它:

computed: {
  doneTodosCount () {
    return this.$store.getters.doneTodosCount
  }
}

通过方法访问
你也可以通过让 getter 返回一个函数,来实现给 getter 传参。在你对 store 里的数组进行查询时非常有用。

etters: {
  // ...
  getTodoById: (state) => (id) => {
    return state.todos.find(todo => todo.id === id)
  }
}
store.getters.getTodoById(2) // -> { id: 2, text: '...', done: false }
//注意,getter 在通过方法访问时,每次都会去进行调用,而不会缓存结果。

mapGetters 辅助函数
mapGetters 辅助函数仅仅是将 store 中的 getter 映射到局部计算属性:

import { mapGetters } from 'vuex'

export default {
  // ...
  computed: {
  // 使用对象展开运算符将 getter 混入 computed 对象中
    ...mapGetters([
      'doneTodosCount',
      // ...
    ])
  }
}
//如果你想将一个 getter 属性另取一个名字,使用对象形式:
...mapGetters({
  // 把 `this.doneCount` 映射为 `this.$store.getters.doneTodosCount`
  doneCount: 'doneTodosCount'
})

demo

//在这使用...mapGetters(['shoplist'])映射的数据
<tr v-for="n in shoplist"> 
    <td>{{n.id}}</td>
    <td>{{n.name}}</td>
    <td>{{n.price}}</td>
    <td><span @click="addtocart(n)">加入购物车</span></td>
</tr>
<script>
    import {mapState,mapGetters,mapActions } from 'vuex'  //导入辅助函数
    export default {
        computed:{
            //mapGetters辅助函数仅仅是将 store 中的 getter  ['shoplist']映射到局部计算属性
            //获取到getter的shoplist数据
            ...mapGetters(['shoplist'])//把store文件getter里面shoplist映射到组件里,拿到的是数据,不是函数
    }
}
</script>

store文件:

//向外输出数据的方法,然后怎么把这些数据弄到需要的组件上呢?
//在需要数据的组件import {mapState,mapGetters,mapActions } from 'vuex'  //导入辅助函数
//然后...mapGetters(['shoplist'])
const getters ={
    //商品列表数据
    shoplist:state=>{
        return state.shoplist
    }

Mutation

Mutation可以进行vuex的状态修改、并且它会接受 state 作为第一个参数:
在项目中,经常使用到VUEX状态管理,对于小项目中,直接使用下述述两种方法即可。

this.$store.commit('increment ','a') //increment事件类型,即mutation的方法名  a需要传的参数
或者  
this.$store.dispatch('increment ','a')//a需要传的参数
//对象风格的提交方式
//提交 mutation 的另一种方式是直接使用包含 type 属性的对象:
store.commit({
  type: 'increment',//事件类型
  amount: a //需要传的参数
})

//在store的mutations中注册一个名为increment的监听及监听触发后的函数体,
//当监听到名为'increment'的commit事件时,会触发store中mutations下increment函数
const store = new Vuex.Store({
  state: {
    count: 1
  },
//提交载荷(Payload)
//mutation的载荷payload是作为store.commit传入的额外参数存在的。
  mutations: {
    increment (state,payload) {//载荷payload接受commit或者dospatch传过的参数
      // 变更状态
      state.count++
    }
  }

  // 另一种写法
  mutations: {
    increment: {
        handler: () => {
        // 逻辑函数
        },
        // 事件类型
        type: 'increment'
    }
  }
})

但是,当项目中的 mutation 或者 action 过多的时候,这样一个个的写就显得比较麻烦。
你可以在组件中使用 this.$store.commit('xxx') 提交 mutation,或者使用 mapMutations 辅助函数将组件中的 "methods" 映射为 store.commit 调用(需要在根节点注入 store)。

import { mapMutations } from 'vuex'

export default {
  // ...
  methods: {
    ...mapMutations([
      'increment', // 将 `this.increment()` 映射为 `this.$store.commit('increment')`
      
      // `mapMutations` 也支持载荷
     //mutation的载荷payload是作为store.commit传入的额外参数存在的。
      'incrementBy' // 将 `this.incrementBy(amount)` 映射为 `this.$store.commit('incrementBy', amount)`
    ]),
    ...mapMutations({
      add: 'increment' // 将 `this.add()` 映射为 `this.$store.commit('increment')`
    })
    //add是我们自己定义的事件名称,increment是action的事件类型。当我们自己定义的事件名称与action的事件类型相同,可写成这样:
   ...mapMutations(["increment"])
  }
}

demo

页面文件:
 <tr>
     <td><span @click="add">加入购物车</span></td>
     <td><span @click="reduce">加入购物车</span></td>
 </tr>
<script>
import {mapActions } from 'vuex'  //导入辅助函数
    export default {
        methods:{
            ...mapMutations(['add' , 'reduce'])//通过点击事件add和reduce调用 提交到store.js的mutations
        }
}

</script>

样的写法可以让我们在组件中像写普通方法一样,直接调用mutations里的方法,把mutations里的方法名直接写在需要调用的地方就行
但是mutations对象中的方法是可以传参的(payload),那么在mapMutations中如何传参呢?

 <tr>
     <td><span @click="add(5)">加入购物车</span></td>
     <td><span @click="reduce">加入购物车</span></td>
  </tr>
<script>
import {mapMutations} from 'vuex'  //导入辅助函数
    export default {
        methods:{
            //add的参数会自动映射store文件的mapMutations
            ...mapMutations(['add' , 'reduce'])//通过点击事件add和reduce调用 提交到store.js的mutations
        }
}

在store.js里面

  mutations: {
    add(state,n) {//载荷n接受commit或者dospatch传过的参数
      // 变更状态
    },
    reduce(state) {//无传参
      // 变更状态
    },
  }

mapActions mapMutations 必须放在 methods中,因为 action 或者 mutation 都是方法.
所以,vue提供了 mapActions和mapMutations 。两者使用方法相似,下面以 mapActions为例。

Actions

Action 类似于 mutation,不同在于:
Action 提交的是 mutation,而不是直接变更状态,也就是在Action处理好异步,再提交到mutation修改。
Action 可以包含任意异步操作。

注册一个简单的 action:

const store = new Vuex.Store({
  state: {
    count: 0
  },
  mutations: {
    increment (state) {
      state.count++
    }
  },
  actions: {
    increment (context) {
      context.commit('increment')
    }
  }
})

Action 函数接受一个与 store 实例具有相同方法和属性的 context 对象,因此你可以调用 context.commit 提交一个 mutation,或者通过 context.state 和 context.getters 来获取 state 和 getters。
实践中,我们会经常用到 ES2015 的 参数解构 来简化代码(特别是我们需要调用 commit 很多次的时候):

actions: {
  increment ({ commit }) {
    commit('increment')
  }
}

分发 Action
Action 通过 store.dispatch 方法触发:

store.dispatch('increment')

乍一眼看上去感觉多此一举,我们直接分发 mutation 岂不更方便?实际上并非如此,还记得 mutation 必须同步执行这个限制么?Action 就不受约束!我们可以在 action 内部执行异步操作:

actions: {
  incrementAsync ({ commit }) {
    setTimeout(() => {
      commit('increment')
    }, 1000)
  }
}
//Actions 支持同样的载荷方式和对象方式进行分发:
// 以载荷形式分发
store.dispatch('incrementAsync', {
  amount: 10
})
// 以对象形式分发
store.dispatch({
  type: 'incrementAsync',
  amount: 10
})

demo

<template>
</template>
<script>
    export default{
        data(){         
            return {
            }
        },
        methods:{

        },
       created(){//created一般都是需要异步操作        
            //通过store的dispatch方法分发任务给action
            this.$store.dispatch("setPlayStatus",{
                playStatus:true  //这里的值还没改的,只是分发到action,在mutations才真正的改
            })
        }
    }
</script>

store.js

import Vue from 'vue'
import Vuex from 'vuex'
import state from '@/vuex/state.js'

Vue.use(Vuex)

export default new Vuex.Store({
state: {   //声明全局变量任何组件都可以拿到他
    token:false,   //修改token的值:例子在home页面提交数据给stores.js的mutations修改
    playStatus:false ,  //异步修改playStatus的值:
},
  mutations: {//改变state状态的唯一方法    commit发送过来,通过mutations才是改变的  、、不支持异步
   setToken(state,data){
    /*
     * 这个函数接收两个参数,
     * state:指的是vuex中的state属性
     * data:用户通过commit发送过来的数据
     */ 
    state.token=data.token  //改变state的token的值
    console.log(state,data);
   },

    //异步修改状态
   setPlayStatus(state,data){
    state.playStatus = data.playStatus;
        console.log("state",state)  //state是vuex的state属性
   }
  },
  
  actions:{
    //解决异步请求
    //再提交给mutations修改 {commit} 是对象解构赋值,因为action里面的方法默认接受一个参数context,
   setPlayStatus({commit},data){//context的实例化对象
   console.log("context",context)
   commit("setPlayStatus",data)
   }
  },
  getters:{//相当于实例中的计算属性,用法跟计算属性一样
    
  }
})

mapActions辅助函数分发actions

import { mapActions } from 'vuex'

export default {
  // ...
  methods: {
    ...mapActions([
      'increment', // 将 `this.increment()` 映射为 `this.$store.dispatch('increment')`

      // `mapActions` 也支持载荷:
      'incrementBy' // 将 `this.incrementBy(amount)` 映射为 `this.$store.dispatch('incrementBy', amount)`
    ]),
    ...mapActions({
      add: 'increment' // 将 `this.add()` 映射为 `this.$store.dispatch('increment')`
    })
    //add是我们自己定义的事件名称,increment是action的事件类型。当我们自己定义的事件名称与action的事件类型相同,可写成这样:
   ...mapActions(["increment"])
  }
}

mapActions 必须放在 methods中,因为 action 或者 mutation 都是方法.
demo2

 <button @click="add(5)">+1</button>
//组件分发
//简写
...mapActions({
    add: "increment"
})
 
//实际上的写法
methods:{
    increment(n){
        this.$store.dispatch("increment",n)
    }
}

add是我们自己定义的事件名称,increment是action的事件类型。当我们自己定义的事件名称与action的事件类型相同

 <button @click="increment(5)">+1</button>
...mapActions(["increment"])

store.js

  mutations: {//改变state状态的唯一方法    commit发送过来,通过mutations才是改变的  、、不支持异步
   INCREMENT(state,data){
    /*
     * 这个函数接收两个参数,
     * state:指的是vuex中的state属性
     * data:用户通过commit发送过来的数据
     */ 
    console.log(state,data);
   },
   actions: {
        //分发到mutation修改状态
        increment({commit},data){
            commit("INCREMENT",data)
        },
    }
//{commit} 是对象解构赋值,因为action里面的方法默认接受一个参数context,
//context是store的一个实例,这个实例是一个对象,改写法是表明使用context中的commit方法。es6的语法

辅助函数actions传参跟mutations一样
例子1:

页面文件:
    <tr v-for="n in shoplist">
        <td>{{n.id}}</td>
        <td>{{n.name}}</td>
        <td>{{n.price}}</td>
        <!--把点击的那一项作为参数传递过去-->
        <td><span @click="addtocart(n)">加入购物车</span></td>
    </tr>
<script>
import {mapState,mapGetters,mapActions } from 'vuex'  //导入辅助函数
    export default {
        methods:{
            ...mapActions(['addtocart'])//引进store文件actions定义的addtocart函数,通过点击事件addtocart调用
        }
        //这里的意思是通过模块名来获取到login,renewToken这个函数,(common就是模块名)
       ...mapActions("common", ["addtocart", 'renewToken']),//通过引进引进store文件actions定义的login函数
}
</script>

store文件

const mutations={
//添加到购物车的操作
    addtocart(state.data){
        //
    }
const actions={
       //添加到购物车的操作
    addtocart({commit},n){
       //console.log(n.name);
       //提交到mutations修改原数组
       commit('add',{
        id:n.id
       })
    }

例子2:

<script>
   ecport default{
       methods:{
        //这里的意思是通过模块名来获取到addtocart,renewToken这个函数,(config就是模块名)
   ...mapActions("common", ["addtocart", 'renewToken']),//通过引进引进store文件actions定义的addtocart、renewToken函数
     async handleLogin (){
     try {
       this.errorMessage = "";                                        
       const res = await this.login(this.loginForm);//this.loginForm是一个对象, 在这调用引进的login(this.loginForm)
          }catch(err){
                console.error(err);
          }
       }
   }
}
</script>

Vue项目中使用Vuex + axios发送请求 转自https://www.cnblogs.com/junwu/p/11195596.html

computed: {
  geneObj () {   // 获取store里的数据,放在computed中可以实时更新
    return this.$store.state.geneObj ;
  }
},
methods:{
   getGene(){
      this.$store.dispatch('getGeneAction');//触发actions里的saveForm函数,调动接口
      //getDatamingData().then(this.getGeneSucc);
      /*
      axios.get(urlApi.datamining)
           .then(this.getGeneSucc);
      */
    },

   //也可以通过actions发送请求,在当前组件处理数据:
   getGene() {
   var _vm = this;//避免this不是这些vue实力
   _vm.$store.dispatch('getGeneAction').then(function(res) {   // 回调函数是普通函数
    console.log(res);  
  })
 }
 //或:
 getGene() {
  this.$store.dispatch('getGeneAction').then(function(res) {   // 回调函数是普通函数
    console.log(res); 
  }.bind(this))
  }
}

*注释掉的是以前直接在方法中获取接口数据

在我的store.js

state:{
  geneObj :" "
},
action:{
  getGeneAction(context,item){
     console.log('getGeneAction');
     //调用axios
     getDatamingData().then((res) => {
      context.commit('GETGENEMUTATION',res);
    });
  }
},
//派发一个GETGENEMUTATION mutation
mutation:{
GETGENEMUTATION(state,item){
    //console.log(item.data.obj);
    state.geneObj = item.data.obj;
  }
}

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

————————————————
版权声明:本文为CSDN博主「不愿意透露姓名的攻城诗」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/github_35830425/article/details/88670982

场景:卖书的商城,在书籍商品显示详情页的时候需要去获取相关的作者信息,书籍表通过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).then(res=> {
        commit('setAuthor', res.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).then(res = >{
          //分发到mutation获取书籍详情
         commit('setCurrentBook', res.book)
         // 获取作者详情
         // todo: {root:true} 很重要,如果没有添加的话,此处会报错
        //分发到 author.js模板的mutations
         dispatch('BookDetail/getAuthorName', res.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({//book/getBookDetailById命名空间、调用指定名字为book的moduls的action
      getBookDetailById: 'book/getBookDetailById'
    })
  },
  created () {
    // 获取商品详情 就是mapActions定义的事件名getBookDetailById
    this.getBookDetailById(this.bookId)
  }
}
</script>
...
}
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,294评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,493评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,790评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,595评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,718评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,906评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,053评论 3 410
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,797评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,250评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,570评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,711评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,388评论 4 332
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,018评论 3 316
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,796评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,023评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,461评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,595评论 2 350

推荐阅读更多精彩内容

  • State 单一状态树 Vuex使用单一状态树——用一个对象就包含了全部的应用层级状态。至此它便作为一个“唯一数据...
    oWSQo阅读 1,087评论 0 0
  • vuex是一个状态管理模式,通过用户的actions触发事件,然后通过mutations去更改数据(你也可以说状态...
    Ming_Hu阅读 2,020评论 3 3
  • ### store 1. Vue 组件中获得 Vuex 状态 ```js //方式一 全局引入单例类 // 创建一...
    芸豆_6a86阅读 341评论 0 0
  • 安装 npm npm install vuex --save 在一个模块化的打包系统中,您必须显式地通过Vue.u...
    萧玄辞阅读 2,929评论 0 7
  • ### store 1. Vue 组件中获得 Vuex 状态 ```js //方式一 全局引入单例类 // 创建一...
    芸豆_6a86阅读 726评论 0 3