vuex_vue项目 - CSDN
精华内容
参与话题
  • 最详细的Vuex教程

    万次阅读 多人点赞 2017-07-19 14:59:27
    最详细的Vuex教程什么是Vuexvuex是一个专门为vue.js设计的集中式状态管理架构。状态?我把它理解为在data中的属性需要共享给其他vue组件使用的部分,就叫做状态。简单的说就是data中需要共用的属性。 引入Vuex...

    最详细的Vuex教程


    什么是Vuex?

    vuex是一个专门为vue.js设计的集中式状态管理架构。状态?我把它理解为在data中的属性需要共享给其他vue组件使用的部分,就叫做状态。简单的说就是data中需要共用的属性。

    引入Vuex(前提是已经用Vue脚手架工具构建好项目)

    1、利用npm包管理工具,进行安装 vuex。在控制命令行中输入下边的命令就可以了。

        npm install vuex --save

    要注意的是这里一定要加上 –save,因为你这个包我们在生产环境中是要使用的。

    2、新建一个store文件夹(这个不是必须的),并在文件夹下新建store.js文件,文件中引入我们的vue和vuex。

        import Vue from 'vue';
        import Vuex from 'vuex';

    3、使用我们vuex,引入之后用Vue.use进行引用。

        Vue.use(Vuex);

    通过这三步的操作,vuex就算引用成功了,接下来我们就可以尽情的玩耍了。

    4、在main.js 中引入新建的vuex文件

        import storeConfig from './vuex/store'

    5、再然后 , 在实例化 Vue对象时加入 store 对象 :

        new Vue({
          el: '#app',
          router,
          store,//使用store
          template: '<App/>',
          components: { App }
        })

    初出茅庐 来个Demo

    1、现在我们store.js文件里增加一个常量对象。store.js文件就是我们在引入vuex时的那个文件。

        const state = {
            count:1
        }

    2、用export default 封装代码,让外部可以引用。

        export default new Vuex.Store({
            state
        });

    3、新建一个vue的模板,位置在components文件夹下,名字叫count.vue。在模板中我们引入我们刚建的store.js文件,并在模板中用{{$store.state.count}}输出count 的值。

        <template>
            <div>
                <h2>{{msg}}</h2>
                <hr/>
                <h3>{{$store.state.count}}</h3>
            </div>
        </template>
        <script>
            import store from '@/vuex/store'
            export default{
                data(){
                    return{
                        msg:'Hello Vuex',
    
                    }
                },
                store
    
            }
        </script>

    4、在store.js文件中加入两个改变state的方法。

        const mutations={
            add(state){
                state.count+=1;
            },
            reduce(state){
                state.count-=1;
            }
        }

    这里的mutations是固定的写法,意思是改变的,所以你先不用着急,只知道我们要改变state的数值的方法,必须写在mutations里就可以了。

    5、在count.vue模板中加入两个按钮,并调用mutations中的方法。

        <div>
            <button @click="$store.commit('add')">+</button>
            <button @click="$store.commit('reduce')">-</button>
        </div>

    这样进行预览就可以实现对vuex中的count进行加减了。

    state访问状态对象

    const state ,这个就是我们说的访问状态对象,它就是我们SPA(单页应用程序)中的共享值。

    学习状态对象赋值给内部对象,也就是把stroe.js中的值,赋值给我们模板里data中的值。有三种赋值方式

    一、 通过computed的计算属性直接赋值

    computed属性可以在输出前,对data中的值进行改变,我们就利用这种特性把store.js中的state值赋值给我们模板中的data值。

        computed:{
            count(){
                return this.$store.state.count;
            }
        }

    这里需要注意的是return this.$store.state.count这一句,一定要写this,要不你会找不到$store的。这种写法很好理解,但是写起来是比较麻烦的,那我们来看看第二种写法。

    二、通过mapState的对象来赋值

    我们首先要用import引入mapState。

        import {mapState} from 'vuex';

    然后还在computed计算属性里写如下代码:

        computed:mapState({
                count:state=>state.count  //理解为传入state对象,修改state.count属性
         })

    这里我们使用ES6的箭头函数来给count赋值。

    三、通过mapState的数组来赋值

        computed:mapState(["count"])

    这个算是最简单的写法了,在实际项目开发当中也经常这样使用。

    Mutations修改状态($store.commit( ))

    Vuex提供了commit方法来修改状态,我们粘贴出Demo示例代码内容,简单回顾一下,我们在button上的修改方法。

        <button @click="$store.commit('add')">+</button>
        <button @click="$store.commit('reduce')">-</button>

    store.js文件:

        const mutations={
            add(state){
                state.count+=1;
            },
            reduce(state){
                state.count-=1;
            }
        }

    传值:这只是一个最简单的修改状态的操作,在实际项目中我们常常需要在修改状态时传值。比如上边的例子,是我们每次只加1,而现在我们要通过所传的值进行相加。其实我们只需要在Mutations里再加上一个参数,并在commit的时候传递就就可以了。我们来看具体代码:

    现在store.js文件里给add方法加上一个参数n。

        const mutations={
            add(state,n){
                state.count+=n;
            },
            reduce(state){
                state.count-=1;
            }
        }

    在Count.vue里修改按钮的commit( )方法传递的参数,我们传递10,意思就是每次加10.

        <p>
           <button @click="$store.commit('add',10)">+</button>
           <button @click="$store.commit('reduce')">-</button>
        </p>

    模板获取Mutations方法

    实际开发中我们也不喜欢看到$store.commit( )这样的方法出现,我们希望跟调用模板里的方法一样调用。
    例如:@click=”reduce” 就和没引用vuex插件一样。要达到这种写法,只需要简单的两部就可以了:

    1、在模板count.vue里用import 引入我们的mapMutations:

        import { mapState,mapMutations } from 'vuex';

    2、在模板的<\script>标签里添加methods属性,并加入mapMutations

         methods:mapMutations([
                'add','reduce'
        ]),

    通过上边两部,我们已经可以在模板中直接使用我们的reduce或者add方法了,就像下面这样。

        <button @click="reduce">-</button>

    getters计算过滤操作

    getters从表面是获得的意思,可以把他看作在获取数据之前进行的一种再编辑,相当于对数据的一个过滤和加工。你可以把它看作store.js的计算属性。

    getters基本用法:

    比如我们现在要对store.js文件中的count进行一个计算属性的操作,就是在它输出前,给它加上100.我们首先要在store.js里用const声明我们的getters属性。

        const getters = {
            count:function(state){
                return state.count +=100;
            }
        }

    写好了gettters之后,我们还需要在Vuex.Store()里引入,由于之前我们已经引入了state和mutations,所以引入里有三个引入属性。代码如下,

        export default new Vuex.Store({
            state,mutations,getters
        })

    在store.js里的配置算是完成了,我们需要到模板页对computed进行配置。在vue 的构造器里边只能有一个computed属性,如果你写多个,只有最后一个computed属性可用,所以要对上节课写的computed属性进行一个改造。改造时我们使用ES6中的展开运算符”…”。

        computed:{
            ...mapState(["count"]),
            count(){
                return this.$store.getters.count;
            }
        },

    需要注意的是,你写了这个配置后,在每次count 的值发生变化的时候,都会进行加100的操作。

    用mapGetters简化模板写法

    我们都知道state和mutations都有map的引用方法把我们模板中的编码进行简化,我们的getters也是有的,我们来看一下代码。

    首先用import引入我们的mapGetters

        import { mapState,mapMutations,mapGetters } from 'vuex';

    在computed属性中加入mapGetters

        ...mapGetters(["count"])

    actions异步修改状态

    actions和之前讲的Mutations功能基本一样,不同点是,actions是异步的改变state状态,而Mutations是同步改变状态。至于什么是异步什么是同步这里我就不做太多解释了,如果你不懂自己去百度查一下吧。

    在store.js中声明actions

    actions是可以调用Mutations里的方法的,我们还是继续在上节课的代码基础上进行学习,在actions里调用add和reduce两个方法。

        const actions ={
            addAction(context){
                context.commit('add',10)
            },
            reduceAction({commit}){
                commit('reduce')
            }
        }

    在actions里写了两个方法addAction和reduceAction,在方法体里,我们都用commit调用了Mutations里边的方法。细心的小伙伴会发现这两个方法传递的参数也不一样。

    • ontext:上下文对象,这里你可以理解称store本身。
    • {commit}:直接把commit对象传递过来,可以让方法体逻辑和代码更清晰明了。

    模板中的使用

    我们需要在count.vue模板中编写代码,让actions生效。我们先复制两个以前有的按钮,并改成我们的actions里的方法名,分别是:addAction和reduceAction。

        <p>
          <button @click="addAction">+</button>
          <button @click="reduceAction">-</button>
        </p>

    改造一下我们的methods方法,首先还是用扩展运算符把mapMutations和mapActions加入。

        methods:{
            ...mapMutations([  
                'add','reduce'
            ]),
            ...mapActions(['addAction','reduceAction'])
        },

    你还要记得用import把我们的mapActions引入才可以使用。

    增加异步检验

    我们现在看的效果和我们用Mutations作的一模一样,肯定有的小伙伴会好奇,那actions有什么用,我们为了演示actions的异步功能,我们增加一个计时器(setTimeOut)延迟执行。在addAction里使用setTimeOut进行延迟执行。

        setTimeOut(()=>{context.commit(reduce)},3000);
        console.log('我比reduce提前执行');

    我们可以看到在控制台先打印出了‘我比reduce提前执行’这句话。

    module模块组

    随着项目的复杂性增加,我们共享的状态越来越多,这时候我们就需要把我们状态的各种操作进行一个分组,分组后再进行按组编写。那今天我们就学习一下module:状态管理器的模块组操作。

    声明模块组:

    在vuex/store.js中声明模块组,我们还是用我们的const常量的方法声明模块组。代码如下:

        const moduleA={
            state,mutations,getters,actions
        }

    声明好后,我们需要修改原来 Vuex.Stroe里的值:

        export default new Vuex.Store({
            modules:{a:moduleA}
        })
    在模板中使用

    现在我们要在模板中使用count状态,要用插值的形式写入。

        <h3>{{$store.state.a.count}}</h3>

    如果想用简单的方法引入,还是要在我们的计算属性中rutrun我们的状态。写法如下:

        computed:{
            count(){
                return this.$store.state.a.count;
            }
        },
    
    展开全文
  • Vuex的全面用法总结

    千次阅读 多人点赞 2019-08-15 14:29:42
    1. vuex简介 vuex是专门用来管理vue.js应用程序中状态的一个插件。他的作用是将应用中的所有状态都放在一起,集中式来管理。需要声明的是,这里所说的状态指的是vue组件中data里面的属性。了解vue的同学应该是明白...

     

    1. vuex简介

    vuex是专门用来管理vue.js应用程序中状态的一个插件。他的作用是将应用中的所有状态都放在一起,集中式来管理。需要声明的是,这里所说的状态指的是vue组件中data里面的属性。了解vue的同学应该是明白data是怎么回事的吧,如果不懂的话,建议先学完vue的基础知识再看vuex。

     

     

    2. vuex的组成结构示意图

    vuex的特点是把数据单独隔离,形成一棵树状图。单独隔离就意味着它有自己的生态系统。输入和输出,其中action作为数据的输入,state作为数据的输出。如下图:

    vuex里有这么一个规则:

    只能在mutaions里修改state,actions不能直接修改state

     

    mutations即变化,修改state的数据,而且只能是同步的,不能存在异步的操作。如果需要异步怎么办呢?把异步操作放在actions里,拿到数据再通过mutations同步处理。vuex做的其实是把职权明确了,责任细分了。所以它文档里也说,小系统可以不用。状态数据少,没有细分的必要。

    3. vuex 的核心概念

     

    3.1 store

    vuex 中最关键的是store对象,这是vuex的核心。可以说,vuex这个插件其实就是一个store对象,每个vue应用仅且仅有一个store对象。

    3.1.1 创建store

    const store = new Vuex.Store({...});

    可见,store是Vuex.Store这个构造函数new出来的实例。在构造函数中可以传一个对象参数。这个参数中可以包含5个对象:

    • 1.state – 存放状态

    • 2.getters – state的计算属性

    • 3.mutations – 更改状态的逻辑,同步操作

    • 4.actions – 提交mutation,异步操作

    • 5.mudules – 将store模块化

    关于store,需要先记住两点:

    • 1. store 中存储的状态是响应式的,当组件从store中读取状态时,如果store中的状态发生了改变,那么相应的组件也会得到更新;

    • 2. 不能直接改变store中的状态。改变store中的状态的唯一途径是提交(commit)mutations。这样使得我们可以方便地跟踪每一个状态的变化。

    3.1.2 一个完整的store的结构是这样的

    const store = new Vuex.Store({
      state: {
        // 存放状态
      },
      getters: {
        // state的计算属性
      },
      mutations: {
        // 更改state中状态的逻辑,同步操作
      },
      actions: {
        // 提交mutation,异步操作
      },
      // 如果将store分成一个个的模块的话,则需要用到modules。
       //然后在每一个module中写state, getters, mutations, actions等。
      modules: {
        a: moduleA,
        b: moduleB,
        // ...
      }
    });

    3.2 state

    state上存放的,说的简单一些就是变量,也就是所谓的状态。没有使用 state 的时候,我们都是直接在 data 中进行初始化的,但是有了 state 之后,我们就把 data 上的数据转移到 state 上去了。另外有些状态是组件私有的状态,称为组件的局部状态,我们不需要把这部分状态放在store中去。

     

    3.2.1 如何在组件中获取vuex状态

    由于vuex的状态是响应式的,所以从store中读取状态的的方法是在组件的计算属性中返回某个状态。

     

    import store from 'store';
    const Counter = {
      template: `<div>{{ count }}</div>`,
      computed: {
        count () {
          // 获取store中的状态
          return store.state.count;
        }
      }
    }

    这样,组件中的状态就与store中的状态关联起来了。每当store.state.count发生变化时,都会重新求取计算属性,从而更新DOM。

    然而,每个组件中都需要反复倒入store。可以将store注入到vue实例对象中去,这样每一个子组件中都可以直接获取store中的状态,而不需要反复的倒入store了。

    const app = new Vue({
      el: '#app',
      // 把 store 对象注入到了
      store,
      components: { Counter },
      template: `
            <div>
                <counter></counter>
            </div>
        `
    });

    这样可以在子组件中使用this.$store.state.count访问到state里面的count这个状态

     

    const Counter = {
      template: `<div>{{ count }}</div>`,
      computed: {
        count () {
          // 获取store中的状态
          return this.$store.state.count;
        }
      }
    }

    3.2.2 mapState

    当一个组件获取多种状态的时候,则在计算属性中要写多个函数。为了方便,可以使用mapState辅助函数来帮我们生成计算属性。

     

    import { mapState } from  'vuex';
    export default {
      // ...
      data (){
        localState: 1
      }
      computed: mapState({
        // 此处的state即为store里面的state
        count: state => state.count,
        // 当计算属性的名称与state的状态名称一样时,可以省写
        // 映射 this.count1 为 store.state.count1
        count1,
        //'count'等同于 ‘state => state.count’
        countAlias: 'count',
        countPlus (state){
        // 使用普通函数是为了保证this指向组件对象
          return state.count + this.localState;
        }
      })
    }
    //上面是通过mapState的对象来赋值的,还可以通过mapState的数组来赋值
    computed: mapState(['count']);
    //这种方式很简洁,但是组件中的state的名称就跟store中映射过来的同名

    对象扩展运算符

    mapState 函数返回的是一个对象,为了将它里面的计算属性与组件本身的局部计算属性组合起来,需要用到对象扩展运算符。

    computed: {
      localState () { 
      ... mapState ({
          
        })
      }

    这样,mapState中的计算属性就与localState计算属性混合一起了。

     

    3.3 getters

    有时候我们需要从 store 中的 state 中派生出一些状态,例如对列表进行过滤并计数。此时可以用到getters,getters可以看作是store的计算属性,其参数为state。

     

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

    3.3.1 获取getters里面的状态,方法一

     

    store.getters.doneTodos //  [{ id: 1, text: 'reading', done: true }]
    //在组件中,则要写在计算属性中,
    computed: {
      doneTodos () {
        return this.$store.getters.doneTodos;
      }
    }

    3.3.2 使用mapGetters获取getters里面的状态:方法二

    import {mapState, mapGetters} from 'vuex';
    computed: {
    ...mapState(['increment']),
    ...mapGetters(['doneTodos'])
    }

    3.4 mutations

    mutations里面是如何更改state中状态的逻辑。更改Vuex中的state的唯一方法是,提交mutation,即store.commit(‘increment’)。

    3.4.1 提交载荷(payload)

    可以向commit传入额外的参数,即mutation的载荷。

     

    mutations: {
      increment(state, n){
        state.count += n;
      }
    }
    store.commit('increment', 10);

    payload还可以是一个对象。

     

    mutations: {
      increment(state, payload)
      state.count += payload.amount;
    }
    }
    store.commit('increment', {amount: 10});

    还可以使用type属性来提交mutation。

     

    store.commit({
      type: 'increment',
      amount: 10
    });
    // mutations保持不变
    mutations: {
      increment(state, payload){
        state.count += payload.amount;
      }
    }

    注意:mutation必须是同步函数,不能是异步的,这是为了调试的方便。

     

     

    3.4.2 在组件中提交mutations

    那么mutation应该在哪里提交呢? 因为js是基于事件驱动的,所以改变状态的逻辑肯定是由事件来驱动的,所以store.commit(‘increment’)是在组件的methods中来执行的。

    方法1: 在组件的methods中提交

     

    methods: {
      increment(){
        this.$store.commit('increment');
      }
    }

     

    方法2: 使用mapMutaions

    用 mapMutations 辅助函数将组件中的 methods 映射为 store.commit 调用。

    import { mapMutaions } from 'vuex';
    export default {
      // ...
      methods: {
        ...mapMutaions([
        'increment' // 映射 this.increment() 为 this.$store.commit('increment')
      ]),
      ...mapMutaions([
          add: 'increment' // 映射 this.add() 为 this.$store.commit('increment')
        ])
        }
    }
    
    // 因为mutation相当于一个method,所以在组件中,可以这样来使用
    <button @click="increment">+</button>

    3.5 actions

    因为mutations中只能是同步操作,但是在实际的项目中,会有异步操作,那么actions就是为了异步操作而设置的。这样,就变成了在action中去提交mutation,然后在组件的methods中去提交action。只是提交actions的时候使用的是dispatch函数,而mutations则是用commit函数。

    3.5.1 一个简单的action

    const store = new Vuex.Store({
      state: {
        count: 0
      },
      mutations: {
        increment(state){
          state.count++;
        }
      },
      actions: {
        increment(context){
          context.commit('increment');
        }
        /* 可以用参数结构的方法来写action
         increment({commit}){
         commit('increment');
         }
         */
      }
    });
    
    // action函数接受一个context参数,这个context具有与store实例相同的方法和属性。
    
    // 分发action
    store.dispatch('increment');

    action同样支持payload和对象方式来分发,格式跟commit是一样的,不再赘述。

     

    4.5.2 在组件中分发action

    方法1: 在组件的methods中,使用this.$store.dispatch(‘increment’)。

    方法2: 使用mapActions,跟mapMutations是类似的。

    import { mapActions } from 'vuex'
    export default {
      // ...
      methods: {
        ...mapActions([
        'increment' // 映射 this.increment() 为 this.$store.dispatch('increment')
      ]),
      ...mapActions({
      add: 'increment' // 映射 this.add() 为 this.$store.dispatch('increment')
    })
    }
    }
    
    // 同样在组件中,可以这样来使用
    <button @click="increment">+</button>

     

    3.5.3 组合actions

    因为action是异步的,那么我们需要知道这个异步函数什么时候结束,以及等到其执行后,会利用某个action的结果。这个可以使用promise来实现。在一个action中返回一个promise,然后使用then()回调函数来处理这个action返回的结果。

    actions:{
      actionA({commit}){
        return new Promise((resolve, reject) => {
          setTimeout(() => {
            commit('someMutation');
            resolve();
          },1000);
        })
      }
    }
    
    // 这样就可以操作actionA返回的结果了
    store.dispatch('actionA').then(() => {
      // dosomething ...
    });
    
    // 也可以在另一个action中使用actionA的结果
    actions: {
      // ...
      actionB({ dispatch, commit }){
        return dispatch('actionA').then(() => {
          commit('someOtherMutation');
        })
      }
    }

    4 mudules

    module是为了将store拆分后的一个个小模块,这么做的目的是因为当store很大的时候,分成模块的话,方便管理。

    4.1 每个module拥有自己的state, getters, mutation, action

    const moduleA = {
        state: {...},
        getters: {...},
        mutations: {....},
      actions: {...}
    }
    
    const moduleB = {
        state: {...},
        getters: {...},
        mutations: {....},
      actions: {...}
    }
    
    const store = new Vuex.Store({
      modules: {
        a: moduleA,
        b: moduleB
      }
    });
    
    store.state.a // 获取moduleA的状态
    store.state.b // 获取moduleB的状态

    4.2 模块内部的状态

    对于模块内部的mutation和getter,接受的第一个参数是模块的局部状态state。顺便说一下,根结点的状态为rootState。

     

    const moduleA = {
      state: { count: 0},
      getters: {
        doubleCount(state){
          return state.count * 2;
        }
      },
      mutations: {
        increment(state){
          state.count ++ ;
        }
      },
      actions: {...}
    }

     

    4.3 模块的动态注册

    在模块创建之后,可以使用store.registerModule方法来注册模块。

     

    store.registerModule('myModule', {
      // ...
    });

    依然的,可以通过store.state.myModule来获取模块的状态。

    可以使用store.unregisterModule(moduleName)来动态的卸载模块,但是这种方法对于静态模块是无效的(即在创建store时声明的模块)。

    5 含有vuex的项目的结构

    5.1 应该遵循的规则

    • 1. 应用层级的状态都应该集中在store中

    • 2. 提交 mutation 是更改状态state的唯一方式,并且这个过程是同步的。

    • 3. 异步的操作应该都放在action里面

    展开全文
  • vue中使用vuex(超详细)

    万次阅读 多人点赞 2019-07-15 14:23:08
    vuex是使用vue中必不可少的一部分,基于父子、兄弟组件,我们传值可能会很方便,但是如果是没有关联的组件之间要使用同一组数据,就显得很无能为力,那么vuex就很好的解决了我们这种问题,它相当于一个公共仓库,...

    vuex是使用vue中必不可少的一部分,基于父子、兄弟组件,我们传值可能会很方便,但是如果是没有关联的组件之间要使用同一组数据,就显得很无能为力,那么vuex就很好的解决了我们这种问题,它相当于一个公共仓库,保存着所有组件都能共用的数据。

    那么,我们一起来看看vue项目怎么使用它吧。(如果你对vuex有一定了解,不是刚接触的小白,请忽略第一步,直接查看第二步)

    一、适合初学者使用,保存数据以及获取数据

    1、在store文件夹,新建个index.js文件(命名看个人习惯,如果没有该文件夹,可以新建一个,当然也可以不建文件夹,直接新建个js文件也是可以的)

    在新建的js文件中写入如下代码:

    import Vue from "vue"
    import Vuex from "vuex"
    
    Vue.use(Vuex);
    
    export default new Vuex.Store({
        state:{
            pathName: "",
            currDbSource: {},
            currJobData: {},
            DbSource: []
        },
        mutations:{
            // 保存当前菜单栏的路径
            savePath(state,pathName){
                state.pathName = pathName;
            },
            // 保存当前点击的数据源
            saveCurrDbSource(state,currDbSource){
                state.currDbSource = currDbSource;
            },
            // 保存当前点击的元数据
            saveCurrJobData(state,currJobData){
                state.currJobData = currJobData;
            },
            // 保存所有数据源
            saveDbSource(state,DbSource){
                state.DbSource = DbSource;
            }
        }
    })
    

    这里解释一下各个代码段的作用:state是自定义的一些变量,需要用来保存数据,mutations是用来触发事件,相当于方法,用户需要通过触发这个方法,借此来保存数据,参数的话,第二个参数就是用户传入的值,然后在方法中赋值给state中的变量

    2、main.js引用:(注意路径即可)

    // 引入vuex-store
    import store from './store/index';
    
    new Vue({
      el: '#app',
      router,
      store,
      render: h => h(App)
    });

    3、保存数据:(场景举例:当我点击按钮后,我需要把当前的数据保存到vuex中,然后跳转到别的路由,然后使用这些数据)

    methods:{
        click(){
            // 点击按钮进行一些操作,然后保存数据
            this.$store.commit('saveCurrDbSource',this.db)
        }
    }

    这里的第一个参数是要触发的方法,也就是上面mutations中的方法,第二个参数是你要传递的数据

    4、获取变量:(当数据初始获取不到时,可以使用计算属性用来获取)

    this.$store.state.变量名
    
    // 例如
    this.store.state.currDbSource

    这样其他组件就可以共用这个保存起来的数据了,也能进行相应的修改

    二、模块化(适合有部分基础的人)

    当然,上述方法中我们把所有东西都写在一个文件中了,这样数据多的时候,耦合度太高,也不便于维护,而且mutations也不能解决异步问题,这里就介绍另一种方式以及actions

    actions:看过官网介绍的人都知道,这是间接触发mutations方法的一种 " 中间商 ",而且它可以执行异步操作,避免用户去直接操作state

    1、state.js :保存所有数据,以对象的方式导出

    export default {
      pathName: '', // 路由
      currDbSource: {}, // 当前数据源
      currJobData: {}, // 当前元数据
      DbSource: [], // 所有数据源,供元数据界面下拉列表使用
      selectJobMeta: {}, // 当前选择的元数据(搜索后点击的单条数据)
      specialSubject: [], // 专题数据(多条)
      duplicateJobMeta: {}, // 复制的数据
    };
    

    2、mutations.js :保存所有方法,用来改变state的数据

    // 保存当前菜单栏的路径
    export const savePath = (state, pathName) => {
      state.pathName = pathName;
    };
    
    // 保存当前点击的数据源
    export const saveCurrDbSource = (state, currDbSource) => {
      state.currDbSource = currDbSource;
    };
    
    // 保存当前点击的元数据
    export const saveCurrJobData = (state, currJobData) => {
      state.currJobData = null;
      state.currJobData = currJobData;
    };
    
    // 保存所有数据源
    export const saveDbSource = (state, DbSource) => {
      state.DbSource = DbSource;
    };
    
    // 保存搜索后选择的那一条元数据
    export const saveSelectJobMeta = (state, selectJobMeta) => {
      state.selectJobMeta = selectJobMeta;
    };
    
    // 保存搜索的那一类专题
    export const saveSpecialSubject = (state, specialSubject) => {
      state.specialSubject = specialSubject;
      state.selectJobMeta = {};
    };
    
    // 保存复制的元数据(名称为空)
    export const saveDuplicateJobMeta = (state, duplicateJobMeta) => {
      state.duplicateJobMeta = duplicateJobMeta;
    };
    

    3、actions.js :暴露给用户使用,借此触发mutations中的方法,保存数据(可执行异步操作)

    // 触发保存菜单栏的路径方法
    export const savePath = ({ commit }, payload) => {
      commit('savePath', payload);
    };
    
    // 触发获取当前点击的数据源方法
    export const saveCurrDbSource = ({ commit }, payload) => {
      commit('saveCurrDbSource', payload);
    };
    
    // 触发获取当前点击的元数据方法
    export const saveCurrJobData = ({ commit }, payload) => {
      commit('saveCurrJobData', payload);
    };
    
    // 触发获取所有数据源方法
    export const saveDbSource = ({ commit }, payload) => {
      commit('saveDbSource', payload);
    };
    
    // 触发保存搜索后选择单条元数据方法
    export const saveSelectJobMeta = ({ commit }, payload) => {
      commit('saveSelectJobMeta', payload);
    };
    
    // 触发保存搜索专题数据方法
    export const saveSpecialSubject = ({ commit }, payload) => {
      commit('saveSpecialSubject', payload);
    };
    
    // 触发保存复制元数据方法
    export const saveDuplicateJobMeta = ({ commit }, payload) => {
      commit('saveDuplicateJobMeta', payload);
    };
    

    这里有2种方式:

    // 方法一:
    export const saveDbSource = (context, payload) => {
       context.commit('saveDbSource', payload);
    };
    
    // 方法二:
    export const saveDbSource = ({ commit }, payload) => {
      commit('saveDbSource', payload);
    };

    第一种是通过 context上下文用来触发事件,一种是直接通过commit,为了保存数据,都需要加第二个参数payload,不然保存到vuex的数据就是空值

    4、index.js:引入相应模块,暴露出store,供vue注册后全局使用

    import Vue from 'vue';
    import Vuex from 'vuex';
    import state from './state';
    import * as actions from './actions';
    import * as mutations from './mutations';
    
    Vue.use(Vuex);
    
    export default new Vuex.Store({
      state,
      actions,
      mutations
    });
    

    5、main.js中引入index.js

    // 引入vuex-store
    import store from './store/index';
    
    new Vue({
      el: '#app',
      router,
      store,
      render: h => h(App)
    });

    6、保存数据

    import { mapActions } from 'vuex';
    
    // 2种方式
    
    // 方法一(dispatch)
    this.$store.dispatch('saveDbSource', this.DbSource);
    
    // 方法二(映射)
    // 1、通过methods方法添加映射关系 
    methods: {
        ...mapActions(['saveDbSource'])
      }
     // 2、使用
    this.saveDbSource
    

    这里也有2种保存数据的方法,第一种就是直接操作方法,通过disptach派发给actions,让actions去触发

    第二种就是通过在methods中添加映射关系,数组方式,意味着我们可以在数组中写多个方法(这里数组中的每一个方法名是actions.js文件中所定义的方法名),然后在需要使用的地方直接this.方法名即可。当然,也可以直接绑定给html中的某个事件。

    值的注意的是,避免和methods中自己定义的其他方法的名字冲突

    7、获取数据

    import { mapState } from 'vuex';
    
    computed: {
        ...mapState(['DbSource']),
    },
    watch: {
        DbSource(currVal) {
            // 监听mapState中的变量,当数据变化(有值、值改变等),
            // 保证能拿到完整的数据,不至于存在初始化没有数据的问题,然后可以赋给本组件data中的变量
          this.currVal = currVal;
        }
    }

    通过计算属性,当数据发生改变,我们可以保证拿到的是响应过后的数据,也是数组形式,意味着我们可以拿到多组数据,这里数组中的数据也是state.js中定义的变量(当然,更推荐使用我注释的那段代码,那种写法可以应对当state中存在多模块的情况,比如state.a.xxx,state.b.xxx,其中a和b都是两个模块,各自有对应的数据要存储,也可以自定义我们前面的名字来避免和data中数据重名的情况)

    使用的时候,可以直接通过this.变量名拿到,例如本例中的 this.DbSource,我们可以把它赋给我们自定义的变量,也可以直接使用

    值的注意的是,避免和data中自己定义的其他变量的名字冲突

    至此,我们就完成了vuex的保存以及获取数据,希望对你有所帮助。

    当然,我们需要把一vuex中的一组数据过滤,其他组件都共用过滤后的数据,这种情况大家可能会用到getters,这里我就不多赘述了,有兴趣的小伙伴可以自己了解一下。

    附上vuex的运行过程,官网的图片:组件派发任务到actions,actions触发mutations中的方法,然后mutations来改变state中的数据,数据变更后响应推送给组件,组件重新渲染

    如有问题,请指出,接受批评。

    个人微信公众号:

    展开全文
  • VUEX基本介绍?

    千次阅读 多人点赞 2018-06-18 21:22:34
    一、什么是Vuex?Vuex是一个专为vue.js应用程序开发的状态管理模式。当我们构建一个中大型的单页面应用程序时,Vuex可以更好的帮助我们在组件外部统一管理状态。二、Vuex的五个核心概念...

    一、什么是Vuex?

    Vuex是一个专为vue.js应用程序开发的状态管理模式。

    当我们构建一个中大型的单页面应用程序时,Vuex可以更好的帮助我们在组件外部统一管理状态。

    二、Vuex的五个核心概念

    State

    Getters

    Mutations

    Actions

    Modules

    其中State和Mutations在任何项目都会接触到的核心概念。为什么说这两个是最核心的呢?

    第一、首先State是我们唯一的数据源,也就是说我们需要把组件里面的一些状态提取出来放到State里面去,State是我们唯一的载体,我们必须要去定义我们的State,这是至关重要的。

    第二、怎么去改变State里面的值呢?比如说如何去修改购物车里面的商品数量,我们在商品列表里面+1,在购物车列表里面把他删掉,它就要-1,那么从哪去操作这个State,就通过Mutations,Mutations是唯一可以提交和改变状态的。

    因此这两个状态是我们必须要掌握的。

    Getters、Actions、Modules,如果我们的项目不是太过于复杂,那么仅仅使用State和Mutations这两就可以满足业务需求了。

    接来下我们来分别来看看这几个状态。


    首先第一个: State

    1、什么是State,我也提到过,我们每一个组件里面的data里面的变量我们都称之为State,State也是我们整个Vue整个核心的概念,这也就是告诉我们的开发者,Vue是一个渐进式的框架,我们的使用状态去管理和操作我们的DOM,改变我们的UI,不是使用过去的那种直接操作DOM的方式。所以说State是我们VUEX里面的一个核心的概念,他在VUEX里面也是一个核心的概念。

    State是唯一的数据源,也就是它是唯一的载体,我们需要把任何一个需要抽取出来的变量,都要放到我们的State里面去来进行管理,那么我们在任何一个页面都可以取到它。

    单一的状态树,什么是单一的状态树,也是说我们通过定义一个store的实例,那么这个store实例里面只有一个State,单一的状态树,它不像我们的Vue组件里面还可以嵌套另一个组件,另一个组件里面还可以嵌套N的组件,这样它是一个很有层级的关系的东西;

    但是我们这个VUEX,其实很单一,它就是一棵树,这棵树这个store对象只要注册到我们的main.js里面,只要被我们的vue注册之后,vue里面所有层级关系的组件都可以使用,它是比较单一的一颗状态树。

    我们看下列组件,这是一个定时器的组件,他里面包括一个模板,我们可以看到模板里面用到count这么一个属性,我们可以看到它里面有个computed的计算属性,这个computed计算属性也就是说,当我们里面的变量发生变化了以后,它都会时时的进行计算,最后来渲染我们的视图。

    我们可以看到它里面定义了count这么一个函数,computed里面必须都是函数,在计算属性里面它每个字段对应的都是函数,我们模板里面的count对应就是computed里面的count方法;当模板里面的count发生变化的时候,computed里面的count就会时时计算,计算完了就渲染到模板对应的位置。

    // 创建一个 Counter 组件
    const Counter = {
      template: `<div>{{ count }}</div>`,
      computed: { // 计算属性
        count () {
          return this.$store.state.count // this就是当前vue的实例,组件的实例;
          //.$store表示vuex注册到vue里面,那么全局任何一个组件都可以拿到这个vuex;
          //this.$store就是vuex的对象;
          //只要通过import导入vuex;
          // 然后通过vue.use我们的vuex,
          // 我们就是可以通过this.store拿到我们的vuex的对象
          // .state就是我们vuex里面定义的属性,它唯一的数据源
          // 我们任何的状态都必须定义到我们的stort里面去
          // count就是我们状态下挂的一个属性
          // 我们就是使用这种方式去使用vuex里面的状态
        }
      }
    }

    State是唯一的数据源,也就是说唯一的载体,只要通过import导入vuex;然后通过vue.use我们的vuex,我们就是可以通过this.store拿到我们的vuex的对象,.state就是我们vuex里面定义的属性,它唯一的数据源,我们任何的状态都必须定义到我们的stort里面去,count就是我们状态下挂的一个属性,我们就是使用这种方式去使用vuex里面的状态.

    接下来,我们看看第二个,Getters

    通过Getters可以派生出一些新的状态;我们看下面的例子:

    我们new一个vuex的实例,这种方式就是定义vuex的实例,

    const store = new Vuex.Store({ // 我们这样创建了一个vuex的对象,这个对象里面包括state,我们可以把任何的状态抽取出来都放到state里面去,
      // state是我们唯一的数据源,我们可以看到里面定义的数组,叫todos,加入这个todos是每个页面都要用到的数组
      // 接下来还定义了getters,getters和state是平级的关系;
      // 比如说现在又五个页面都使用到了这个数组,但是恰巧有一个页面它并不像完全应用这个数组,
      // 它只想用done是true的数组列表;
      // 我们可以通过getters对数组进行操作;
      // 我们直接 return state.todos.filter(todo => todo.done);通过它的filter过滤器返回todo.done为true的数据
      // getters是state的延伸,可以通过getters派生出一些新的状态
      // getters是基于todos来操作的
      state: {
        todos: [
          { id: 1, text: '...', done: true },
          { id: 2, text: '...', done: false }
        ]
      },
      getters: {
        doneTodos: state => {
          return state.todos.filter(todo => todo.done)
        }
      }
    })
    我们再举一个例子,例如购物车的数量,大于99的时候,我们需要变成"99+";这时候你仅仅定义一个state肯定是满足不了的;我们需要重新去延伸一个getters去做我们这样的一个操作;


    接下来我们来看一下Mutations

    更改Vuex的store中的状态的唯一方法是提交mutation

    我们看一下下列例子

    const store = new Vuex.Store({ 
      state: { // 我们在Store里面定义一个state这么一个属性
        count: 1 // 它里面有个count这样的字段,值是1
      },
      mutations: { // 那么我们如何将count改成其他值呢,我们没有其他方法,必须通过mutations这个值
      // 怎么提交,比方说,我们定义一个mutations这么一个属性,它里面一个increment的函数,这个函数可以随便起
      // increment函数首先默认接收了一个状态;第一个参数就是state;这个state就是上面的state
      // 它可以通过state。count去拿到我们的状态值;来去给它++;来改变它的状态
      // 注意:只能在mutations里面去定义函数去提交改变state里面的值
      // 这种方式有什么好处,它就相当于我们管理我们的日志;管理我们的记录,在哪里怎么提交的,每一步都可以把它加到我们记录里面去;方便vuex的调试
        increment (state) {
          // 变更状态
          state.count++
        }
      }
    })

    接下来我们再来看一下怎么去调用这个函数

    mutations里面只定义了函数,函数内部给值加1;但是需要有些地方去触发它

    //那就是通过
    store.commit('increment') //去提交这个函数,这样我们的值才能去加1;

    比防说在我们的购物车列表页面,当我们加入购物车以后我们只需要调一下store.commit去提交increment;那我们的increment

    就会把购物车的数量++;每个页面里面购物车数量都会++;这就是我们mutations的功能;


    接下来我们来看下Actions

    Action提交的是mutation,而不是直接变更状态

    也就是说我们的状态值需要通过mutation来提交;那么mutation它可以通过Action来提交;

    Action可以包含冉义异步操作

    我们来看看下面的例子:

    const store = new Vuex.Store({ // 我们new了一个vuex的实例
      state: { // 我们定义了一个状态
        count: 0
      },
      mutations: { // mutations是唯一用来提交count值的
        increment (state) {
          state.count++
        }
      },
      actions: { // actions也定义了increment;它默认接收一个context;context它可以直接去调用commit方法
      // 这都是vuex全局注册进来的
      // 通过context这个对象可以调用我们的commit来提交一个increment;这句话执行之后就会去调用mutation里面的increment方法,就会把count的值++;
      // 
        increment (context) {
          context.commit('increment')
        }
      }
    })

    所以说第一种就是在methods里面直接调用store.commit('increment') 方法;第二种就是定义一个actions,通过这个actions来提交increment;

    好像显得有点多余,确实有点多余;但是有一种场景它是不多余的;就是mutation的函数必须是同步的;而Action可以做任意异步的操作;


    最后我们来了解一下Modules

    面对复杂的应用程序,当管理的状态比较多时;我们需要将vuex的store对象分割成模块(modules)。

    下面我们来看一个例子:

    const moduleA = { // 通过const来定义一个moduleA,再定义一个moduleB;每个模块都包括
     // stste,mutation,action,getters等一系列概念;
     // 只是说这些状态都是在A模块里面运用的;B模块里面也会应用到;但是如果我们的项目并不需要太多的状态管理;那么我们完全可以把它定义到vuex里面去;不需要进行拆分;
     // 只有在我们的页面里面概念比较多,而又不想和别的页面进行混淆的时候;
     // 大家可以把它拆分成每个模块
      state: { ... },
      mutations: { ... },
      actions: { ... },
      getters: { ... }
    }
    
    const moduleB = {
      state: { ... },
      mutations: { ... },
      actions: { ... }
    }
    
    const store = new Vuex.Store({
      modules: {
        a: moduleA,
        b: moduleB
      }
    })
    
    store.state.a // -> moduleA 的状态
    store.state.b // -> moduleB 的状态

    下面我们看一下Vuex的状态管理图;这里还是需要给大家解释一下;解释完之后,大家可能会对这个概念理解起来稍微更清晰一点;


    https://vuex.vuejs.org/vuex.png

    下面我们再来看看我们的项目结构

    ├── index.html
    ├── main.js
    ├── api
    │   └── ... # 抽取出API请求
    ├── components
    │   ├── App.vue
    │   └── ...
    └── store
        ├── index.js          # 我们组装模块并导出 store 的地方
        ├── actions.js        # 根级别的 action
        ├── mutations.js      # 根级别的 mutation
        └── modules
            ├── cart.js       # 购物车模块
            └── products.js   # 产品模块

    展开全文
  • vuex详解

    万次阅读 多人点赞 2018-06-12 17:15:18
    简而言之,Vuex采用类似全局对象的形式来管理所有组件的公用数据,如果想修改这个全局对象的数据,得按照Vuex提供的方式来修改(不能自己随意用自己的方式来修改)。 二、优点 Vu...
  • Vuex的基本原理与使用

    千次阅读 2019-05-14 09:23:19
    VueX的使用学习 参考文章添加链接描述 参考文章添加链接描述 我们需要知道 vue 是单向数据流的方式驱动的 什么是vuex? 为什么要使用vuex ? - 多个视图依赖于同一状态。 - 来自不同视图的行为需要变更同一状态。 ...
  • Vue中 Vuex 的详解

    千次阅读 多人点赞 2019-04-26 12:09:41
        Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式。它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化。 安装 HTML 中使用 script 标签引入 <...
  • 真正掌握vuex的使用方法(一)

    千次阅读 2018-05-17 14:54:26
    导语:vuex是什么?我的理解就是vuex是一个管理者,管理的方式是集中式管理,管理的对象即是vue.js应用程序中的众多组件的共享部分。学习的过程当中,希望按照我的步骤一步一步来进行练习! 咱们知道,vue项目当中...
  • Vue之Vuex详解与实例

    万次阅读 2018-12-27 17:28:38
    ① 在组件(页面)中,通过dispatch()或mapActions()这个函数分发给actions的函数去处理。 ② actions的函数可以与后台交互,也可以通过 commit() 提交给mutations去处理。 ③ mutations 可以直接与devtool(如...
  • Vuex是什么?

    万次阅读 多人点赞 2019-06-04 11:54:34
    记得去年公司招聘前端工程师的时候,我要负责准备面试题去考验面试者,让我记忆深刻的有一件事,我看大多数面试者简历上都写了熟练掌握Vuex,然而当我问起的时候,大部分回答都支支吾吾,解释不清,而当我提起与Vuex...
  • vuex

    2019-12-26 20:20:46
    Vuex是什么? Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式。Vuex背后的基本思想,就是前面所说的单向数据流。下图就是Vuex实现单向数据流的示意图。 Vuex状态管理跟使用传统全局变量的不同之处 1.Vuex的...
  • Vuex

    千次阅读 2017-05-23 12:08:22
    Vuex有两种写法:  一.直接在main.js里面写:   import axios from 'axios' import Vuex from 'vuex' Vue.use(Vuex); const store = new Vuex.Store({ state: { count: 0 }, mutations: { increment (state) {...
  • VUEX

    2019-10-10 11:44:35
    在src目录下创建store模块,分别维护3 在store/index.js文件中新建vuex的store实例,并注册上面引入的各大模块4 在main.js中导入并使用store实例4.vuex取值:5.vuex存值6.调用ajax 1.vue中各个组件之间传值 1.父子...
  • 上一章大概说明了vuex的设计初衷和基本用法,从这一章开始详解一下vuex的几个关键配置. 1.state state是什么? 定义:state(vuex) ≈ data (vue) vuex的state和vue的data有很多相似之处,都是用于存储一些数据,...
  • 手把手教你使用vuex

    千次阅读 多人点赞 2019-11-21 00:07:49
    vuex 什么是vuex Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式。 可以理解为我们项目中需要共享的一些数据,我们把它集中管理起来的容器。把这些数据称为状态。比如一个用户的用户名,性别,权限级别等等。 ...
  • this.$set(this.form,'img',res.data.file_name);
  • Vuex传值

    2019-09-04 20:22:03
    vue中各个组件之间传值比较 1.父子组件 父组件–>子组件,通过子组件的自定义属性:props 子组件–>父组件,通过自定义事件:this.$emit(‘事件名’,参数1,参数2,…); 缺点:用组件之间通讯。...
  • 5分钟学会Vuex

    万次阅读 多人点赞 2019-08-06 13:56:52
    Vuex是什么? Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式。 它采用集中式存储管理应用的所有组件的状态, 并以相应的规则保证状态以一种可预测的方式发生变化 这是vuex的官网,对vuex的解释,乍一看挺...
  • vuex 使用详解

    千次阅读 2017-10-23 18:56:37
    Vuex 使用详解 说明 Vuex 是一个专门为 Vue 应用程序开发的状态管理模式,适合开发大型单页应用, 它能够更好的在组件外部管理状态 重要文件版本 “vue”: “^2.5.2”, “vuex”: “^3.0.0” 特点 ...
1 2 3 4 5 ... 20
收藏数 54,867
精华内容 21,946
关键字:

vuex