vuex - 操作使用

安装vuex:npm install vuex -S

vuex中一共有五个状态:state,getter,mutation,action,module

在src新建 store 文件夹,并且新建 index.js

在 mian.js 全局挂载 vuex:

import { createApp } from 'vue'
import vuex from './store'
import App from './App.vue'

createApp(App).use(vuex).mount('#app')

如何使用?在store/index.js里:

import { createStore } from 'vuex'

const store = createStore({
    state:{
        name:"小明"
    }
})
export default store

1.State:

提供唯一的公共数据源,所有共享的数据统一放在store的state进行存储,类似于vue的data / return

<template>
  <div>
    <!-- 在标签中直接使用 -->
    <p>{{ $store.state.name }} - {{ $store.state.age }} - {{ $store.state.age ? '男' : '女' }}</p>
    <p>{{ getName }}</p>
    <!-- 通过mapState获取,在页面中直接使用,辅助函数 -->
    <p>{{ name + age + sex }}</p>
  </div>
</template>
<script>
// 使用 mapState 导出
import { mapState } from 'vuex'
export default {
  data() {
    return {}
  },
  mounted() {
    // 全局使用
    console.log(this.$store.state.name)
  },
  computed: {
    // 通过mapState函数导出变量并获取值
    ...mapState(["name", "age", "sex"]),
    getName() {
      return "myName is : " + this.name
    }
  }
}
</script>

2.Mutation:

* 同步操作触发方法:

第一种方法是this.$store.commit("mutation声明的方法")

第二种方法是通过mapMutations抛出,直接在methods里通过声明的方法触发mutations声明的方法

案例1:使用commit触发Mutation操作:

store/index.js:

import { createStore } from "vuex";

const store = createStore({
  state: {
    index: 1,
  },
  mutations: {
    getInfo1(state, params) {
        if(state.index < 99){
            state.index = +state.index + params;
        }
    },
    getInfo2(state) {
      if(state.index > 1){
        state.index--;
      }
    },
  },
});
export default store;

index:

<template>
  <div>
    <button @click="handleChange2">-</button>
    <input type="text" v-model="$store.state.index" />
    <button @click="handleChange1">+</button>
  </div>
</template>
<script>
export default {
  data() {
    return {}
  },
  mounted() { },
  methods: {
    handleChange1() {
      this.$store.commit("getInfo1", 1)
    },
    handleChange2() {
      this.$store.commit("getInfo2")
    }
  }
}
</script>

案例2:使用辅助函数进行操作,具体方法同上:

store/index.js:

import { createStore } from "vuex";

const store = createStore({
  state: {
    index: 1,
  },
  mutations: {
    getInfo1(state, params) {
        if(state.index < 99){
            state.index = +state.index + params;
        }
    },
    getInfo2(state) {
      if(state.index > 1){
        state.index--;
      }
    },
  },
});
export default store;

index:

<template>
  <div>
    <button @click="handleChange2">-</button>
    <input type="text" v-model="$store.state.index" />
    <button @click="handleChange1">+</button>
  </div>
</template>
<script>
import { mapMutations } from 'vuex';
export default {
  data() {
    return {}
  },
  mounted() { },
  methods: {
    ...mapMutations(["getInfo1","getInfo2"]),
    handleChange1() {
      this.getInfo1(1)
    },
    handleChange2() {
      this.getInfo2()
    }
  }
}
</script>

3.Action:异步操作

* 异步操作触发方法:

第一种方法是this.$store.dispatch("mutation声明的方法")

第二种方法是通过mapActions抛出,直接在methods里通过声明的方法触发

store/index.js:

import { createStore } from "vuex";

const store = createStore({
  state: {},
  mutations: {
    handleFn() {
      alert(123);
    },
  },
  actions: {
    getInfo3(content) {
      setTimeout(() => {
        content.commit("handleFn");
      }, 1000);
    },
  },
});
export default store;

index.js

<template>
  <div>
    <button @click="handleChange3">aaa</button>
  </div>
</template>
<script>
import { mapActions, mapMutations } from 'vuex';
export default {
  data() {
    return {}
  },
  mounted() { },
  methods: {
    ...mapActions(["getInfo3"]),
    handleChange3(){
      this.getInfo3()
    }
  }
}
</script>

4.Getters:

Getters类似于vue中的computed,进行缓存,对store中的数据进行加工

mapGetters语法:

import { mapGetters } from 'vuex
export default {
    computed: {
        ...mapGetters(['计算属性名'])

        ...mapGetters('模块名',['计算属性名'])

        ...mapGetters('模块名',['新计算属性名','新计算属性名'])
    }
}

案例1:

store/index.js:

import { createStore } from "vuex";

const store = createStore({
  state: {
    name: "aabbcc",
  },
  getters: {
    getInfo4(state) {
      return state.name + "zzz";
    },
  },
});
export default store;

index:

<template>
  <div>
    {{searchMsg}}
  </div>
</template>
<script>
export default {
  data() {
    return {}
  },
  mounted() { },
  computed:{
    searchMsg(){
      return this.$store.getters.getInfo4
    }
  }
}
</script>

案例2:

store/index.js:

import { createStore } from "vuex";

const store = createStore({
  state: {
    nameObj: {
        aaa:"xxx",
        bbb:"yyy",
        ccc:"zzz"
    },
  },
  getters: {
    nameObj: state => state.nameObj || {}
  },
});
export default store;

index.js:

<template>
  <div>
    {{searchMsg}}
  </div>
</template>
<script>
import { mapGetters } from 'vuex'
export default {
  data() {
    return {}
  },
  mounted() { },
  computed:{
    ...mapGetters(["nameObj"]),
    searchMsg(){
      return this.nameObj
    }
  }
}
</script>

案例3:购物车案例

store/index.js:

import { createStore } from "vuex";
const store = createStore({
  state: {
    shopList: [
      {
        shopName: "精品男装运动裤",
        shopNum: 1,
        shopPrice: 599,
      },
      {
        shopName: "kappa男装外套",
        shopNum: 1,
        shopPrice: 399,
      },
      {
        shopName: "精品男装运动鞋",
        shopNum: 1,
        shopPrice: 299,
      },
    ],
  },
  mutations: {
    add(state, params) {
      const index = params.index;
      const num = state.shopList[index].shopNum;
      if (num < 99) {
        state.shopList[index].shopNum = +num + params.num;
      }
    },
    reduce(state, params) {
      const index = params.index;
      const num = state.shopList[index].shopNum;
      if (num > 1) {
        state.shopList[index].shopNum--;
      }
    },
  },
  getters: {
    shopData(state) {
      return state.shopList;
    },
    shopPrice(state) {
      return state.shopList.reduce((a, b) => {
        return a + b.shopPrice * b.shopNum;
      }, 0);
    },
  },
});
export default store;

index:

<template>
  <div>
    <table border="1" width="400" cellpadding="5">
      <tr>
        <th>商品名称</th>
        <th>商品个数</th>
        <th>商品价格</th>
      </tr>
      <tr v-for="(item,index) in shopList" :key="index">
        <td align="center">{{item.shopName}}</td>
        <td align="center">
          <button @click="handleReduce({num:1,index:index})">-</button>
          <input type="text" v-model="item.shopNum" style="width:30px;text-align: center;margin:0 5px;" />
          <button @click="handleAdd({num:1,index:index})">+</button>
        </td>
        <td align="center">{{item.shopPrice * item.shopNum}}</td>
      </tr>
      <tr>
        <td colspan="3" align="right">商品总价 : {{shopTotal}}</td>
      </tr>
    </table>
  </div>
</template>
<script>
import { mapGetters, mapMutations } from 'vuex'
export default {
  data() {
    return {}
  },
  mounted() { },
  computed:{
    ...mapGetters(["shopData","shopPrice"]),
    shopList(){
      return this.shopData
    },
    shopTotal(){
      return this.shopPrice
    }
  },
  methods:{
    ...mapMutations(['add','reduce']),
    handleReduce(params){
      this.reduce(params)
    },
    handleAdd(params){
      this.add(params)
    }
  }
}
</script>

5.Modules:

Vuex 允许我们将 store 分割成模块(module) 每个模块拥有自己的 state mutation action getter 甚至是嵌套子模块——从上至下进行同样方式的分割:

store/index.js:

import { createStore } from "vuex";
const modulesA = ({
  state: {
    name:"aaa"
  }
});
const store2 = createStore({
    state:{},
    mutations:{},
    getters:{},
    actions:{},
    modules:{
        namespaced:true,
        A:modulesA
    }
})
export default store2;

index.js

<template>
  <div>
    {{$store.state.A.name}} // aaa
  </div>
</template>

2.vue存储数据 / 获取数据

store/index.js:

import { createStore } from "vuex";

const store2 = createStore({
    state:{
        formData:{
            userName:"",
            passWord:""
        }
    },
    mutations:{
        toLogin(state,params){
            state.formData = params
        }
    },
    getters:{},
    actions:{},
    modules:{}
})
export default store2

index.vue:

<template>
  <div>
    <div>
      username:<input type="text" v-model="formData.userName" />
    </div>
    <div>
      password:<input type="password" v-model="formData.passWord" />
    </div>
    <div>
      <button @click="handleLogin">Login</button>
    </div>
    {{$store.state.formData}}
  </div>
</template>
<script>
  import { mapMutations } from 'vuex';
  export default {
    data(){
      return {
        formData:{
          userName:"",
          passWord:""
        }
      }
    },
    methods:{
      ...mapMutations(['toLogin']),
      handleLogin(){
        // 第一种写法
        this.toLogin(this.formData)
        // 第二种写法
        this.$store.commit("toLogin",this.formData)
      }
    }
  }
</script>

3.持久化存储

1) 自己实现一个持久化本地存储

新建一个 SesstionUtils.js

export class SesstionUtils {
  static get(key) {
    return JSON.parse(window.sessionStorage.getItem(key));
  }
  static set(key, value) {
    window.sessionStorage.setItem(key, JSON.stringify(value));
  }
  static remove(key) {
    window.sessionStorage.removeItem(key);
  }
}

index.vue

import { createStore } from "vuex";
import { SesstionUtils } from "./SessionUtils";

const store2 = createStore({
  state: {
    formData: SesstionUtils.get("loginInfo") || {},
  },
  mutations: {
    toLogin(state, params) {
      state.formData = params;
      SesstionUtils.set("loginInfo", state.formData);
    },
  },
  getters: {},
  actions: {},
  modules: {},
});
export default store2;

此时刷新浏览器,发现数据还在,并且在控制台的存储,可以看到通过本地存储的vuex数据

2) 通过 vuex-persistedstate 第三方插件实现:

npm install vuex-persistedstate --save-dev

如何使用:

store/index.js

import { createStore } from "vuex";
// 引用插件
import  createPersistedState from 'vuex-persistedstate'

const store2 = createStore({
    state:{
        formData:{
            userName:"",
            passWord:""
        }
    },
    mutations:{
        toLogin(state,params){
            state.formData = params
        }
    },
    getters:{},
    actions:{},
    modules:{},
    // 使用 数据持久化
    plugins: [
        createPersistedState({
            // 存储方式:localStorage、sessionStorage、cookies
            storage:window.sessionStorage,
            // 存储的 key 的key值
            key:"userInfo2",
            render(state){
                // 要存储的数据:本项目采用es6扩展运算符的方式存储了state中所有的数据
                return {...state}
            }
        })
    ]
})
export default store2;

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值