vue——49-Vuex

原理文章

vuex

官网:Vuex

Vuex 是为了保存组件之间共享数据而诞生的,如果组件之间有要共享的数据,可以直接挂载到 Vuex 中,而不必通过父子组件之间传值了,如果组件之间的数据不需要,这些不需要共享的私有数据,没有必要放到 Vuex 中

注意:

  1. 只有共享的数据,才有权利放到 Vuex 中;
  2. 组件内部私有的数据,只要放到组件的 data 中即可;
  3. props 、 data 和 vuex 的区别:props 是父组件向子组件传值;data 是组件内部私有数据;vuex 相当于一个全局的共享数据存储区域,就是一个公共数据仓库

在这里插入图片描述

操作案例:

在这里插入图片描述

  • 安装:cnpm i vuex -S

操作:

main.js
// 入口文件
import Vue from 'vue';
// 配置 vuex 的步骤
// 2. 导入包
import Vuex from 'vuex';

// 3. 注册 vuex 到 vue 中
Vue.use(Vuex);

// 4. new Vue.Store() 实例,得到一个数据仓储对象
let store = new Vuex.Store({
    state: {
        count: 0

    },
    mutations: {
        increment(state) {
            state.count++;
        },
        subtract(state, obj) {
            state.count -= (obj.c + obj.d);
        }
    },
    getters: {
        // 注意:这里的 getters ,只负责对外提供数据,不负责
        // 修改数据,如果想要修改 state 中的数据,请去找 mutations
        optCount(state) {
            return '当前最新的 count 值是:' + state.count;
        }
    },
    actions: {
    	SUBTRACT({ commit }, obj) {
    		// 可以在这里对 obj 进行处理或异步操作
    		setTimeout(() => { // 一秒后减去
    			commit('subtract', obj)
			}, 1000)
    	}
	}
});

import App from './App.vue';

const vm = new Vue({
    el: '#app',
    render: c => c(App),
    // 5. 将 vuex 创建的 store 挂载到 VM 实例上,只要挂在到了 VM 上
    // 任何组件都能使用 store 来存储数据
    store
});
两个组件:

amount.vue

<template>
    <div>
        <!--<h3>{{ '当前数量为:'+$store.state.count }}</h3>-->
        <h3>{{ $store.getters.optCount }}</h3>
    </div>
</template>

counter.vue

<template>
    <div>
        <input type="button" value="减少" @click="remove">
        <input type="button" value="增加" @click="add">
        <br>
        <input type="text" v-model="$store.state.count">
    </div>
</template>
<script>
    export default {
        data() {
            return {
                // count: 0
            };
        },
        methods: {
            add() {
                // 虽然可以实现,但不要这么用,后期维护困难
                // this.$store.state.count++;
                this.$store.commit('increment');
            },
            remove() {
            	// mutations 方式
                this.$store.commit('subtract', {c: 3, d: 2});
                // actions 方式
                this.$store.dispatch('SUBTRACT', {c: 3, d: 2});
            }
        }
    };
</script>
总结:
  1. state 中的数据,不能直接修改,如果想要修改,必须通过 mutations
  2. 如果组件想要直接从 state 上获取数据:需要 this.$store.state.***
  3. 如果组件,想要修改数据,必须使用 mutations 提供的方法,需要通过 this.$store.commit(‘方法的名称’,唯一的一个参数)
  4. 如果 store 中 state 上的数据,在对外提供的时候,需要做一层包装,那么,推荐使用 getters,如果需要使用 getters,则用 this.$store.getters.***

附加:

  1. 应用场景:商城购物车的商品个数添加
  2. 映射:
   import { mapState, mapActions, mapGetters, mapMutations } from "vuex"

   // state
   computed: {
      // 使用对象展开运算符将 setter 混入 computed 对象中
      ...mapState('mark', [
        'markData',
        'pageData',
      ]),
   }
    
   // getter
   computed: {
   // 使用对象展开运算符将 getter 混入 computed 对象中
     ...mapGetters([
       'doneTodosCount',
       'anotherGetter',
       // ...
     ])
   }
  
   // mutation
   methods: {
    ...mapMutations([
      'increment', // 将 `this.increment()` 映射为 `this.$store.commit('increment')`

      // `mapMutations` 也支持载荷:
      'incrementBy' // 将 `this.incrementBy(amount)` 映射为 `this.$store.commit('incrementBy', amount)`
    ]),
    ...mapMutations({
      add: 'increment' // 将 `this.add()` 映射为 `this.$store.commit('increment')`
    })
   }
    
  // action
  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')`
    })
  }

以上面 state 为例

import mark from './mark'
export default new Vuex.Store({
  state,
  mutations,
  modules: { mark }
})

computed: {
  // 使用对象展开运算符将 setter 混入 computed 对象中
  ...mapState('mark', [
    'markData',
    'pageData',
  ]),
}

// 使用
const data = this.markData

Vuex 持久化插件(vuex-persistedstate)

页面刷新后,想保存页面未保存的数据。我们总是习惯于放在浏览器的sessionStorage和localStorage中。但是用了vue后,vuex便可以被应用了。

  • vuex优势:相比sessionStorage,存储数据更安全,sessionStorage可以在控制台被看到。
  • vuex劣势:在F5刷新页面后,vuex会重新更新state,所以,存储的数据会丢失。

解决方法:vuex-persistedstate

安装
npm install vuex-persistedstate  -S
用法
import createPersistedState from "vuex-persistedstate"
const store = new Vuex.Store({
  // ...
  plugins: [createPersistedState()]
})

想要存储到sessionStorage,配置如下(想使用 cookie 或 localStorage 同理 )

import createPersistedState from "vuex-persistedstate"
const store = new Vuex.Store({
  // ...
  plugins: [createPersistedState({
      storage: window.sessionStorage
  })]
})

vuex-persistedstate默认持久化所有state,指定需要持久化的state,配置如下:

import createPersistedState from "vuex-persistedstate"
const store = new Vuex.Store({
  // ...
  plugins: [createPersistedState({
      storage: window.sessionStorage,
      reducer(val) {
          return {
          // 只储存state中的user
          user: val.user
        }
     }
  })]
实例:
let store = new Vuex.Store({
    plugins: [
        createPersistedState({
            storage: window.localStorage,
            reducer(val) {
                return {
                    token: val.token,
                }
            }
        }),
        createPersistedState({
            storage: window.sessionStorage,
            reducer(val) {
                return {
                    footer: val.footer,
                }
            }
        }),
    ],
    state: {
        footer: 1,
        token: '',
    },
    mutations: {
        footer(state, str) {
            state.footer = str;
        },
        token(state, str) {
            state.token = str;
        }
    },
});

更多请看:vuex-persistedstate

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值