vuex系列---【vuex基础知识】

1.官网:

https://vuex.vuejs.org/zh/

2.什么是vuex?

Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式。它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化。Vuex 也集成到 Vue 的官方调试工具 devtools extension (opens new window),提供了诸如零配置的 time-travel 调试、状态快照导入导出等高级调试功能。

3.安装

npm
npm i vuex --save
yarn
npm i yarn -g
yarn add vuex

4.创建仓库

src/store/index.js

import Vue from 'vue'
import Vuex from "vuex"
Vue.use(Vuex)

export default new Vuex.Store({
  //状态【数据】
  state: {
    name:"妲己",
    age:10,
    arr:[],//从后端取回来的数据
  },

//只有mutations才直接修改state,mutations做的是同步操作
  mutations: {
    changeName(state,name){
      state.name=name;
    },
    changeAge(state,age){
      state.age=age;
    },
    changeArr(state,arr){
      state.arr=arr;
    }
  },

//可以做异步操作|逻辑操作,一般情况下主要做ajax
  actions: {
    // context是仓库本身
    asyncChangeName(context,name){
      setTimeout(()=>{
        context.commit('changeName',name)
      },1000)
    },

    reqArr(context){
      /*
      axios().then(res=>{
        context.commit("changeArr",res.data.list)
      })*/
    }

  },

//类似计算属性 computed,导出数据给组件的
  getters:{
    name(state){
      return state.name;
    },
    age(state){
      return state.age
    },
    arr(state){
      return state.arr;
    },
    info(state){
      return `我叫${state.name},年龄${state.age}`
    }
  },

})

组件使用方法:

1.组价取值:$store.state.name
2.触发mutations中的方法:$store.commit('changeName','王昭君')
3.触发actions中的方法:$store.dispatch('asyncChangeName','王昭君')
4.this.$store.getters.name

5.小结

vuex是单向数据流,表单是双向数据绑定,所以有表单的地方就不要使用vuex。

state—(getters)—>组件展示的数据——(actions)——>mutations—(修改)—>state---(getters)—>组件展示—>…..

image

6.辅助函数

可以通过mapGetters将getters上的数据导入给组件的computed

可以通过mapActions将actions上的方法导入给组件的methods

<template>
  <div class="box">
      <h3>this is D</h3>
      <div> getters name:{{name}}</div>
      <div> getters info:{{info}}</div>
      <button @click="changeName('鲁班')">鲁班</button>
      <button @click="asyncChangeName('宫本')">宫本</button>
  </div>
</template>

<script>
import {mapGetters,mapActions} from "vuex"
export default {
  computed:{
      //...mapGetters(["name","info"]),
    	...mapGetters({
        name:"name",
        info:"info"
      }),
      a(){
          return 10;
      }
  },
  methods:{
      //...mapActions(["changeName","asyncChangeName"])
    ...mapActions({
        changeName:"changeName",
        asyncChangeName:"asyncChangeName"
      }),
  }
}
</script>

7.mutations VS actions

mutations 同步操作、       可以修改state   $store.commit()触发
actions   异步操作、逻辑   不可以修改state  $store.dispatch()触发

8.Vuex VS 本地存储

(需要整理下代码,上传)

vuex      刷新数据没有了  ,方便组件取值,数据改变可以实时渲染
本地存储  刷新数据还在  ,取值不方便,不会实时渲染

9.vuex中数组变了,页面不渲染,怎么解决?

(需要整理下代码,上传)

arr.splice()
Vue.set()

10.模块化

new Vuex.Store({
	state:{},
  mutations:{},
  actions:{},
  getters:{},
  modules:{
    home:{
      state:{},
      mutations:{},
      actions:{},
      getters:{},
      namespaced:true,//命名空间
    }
  }
})

3.案例 组件层(vue)和状态层(vuex)解耦

(未上传)

1.轮播图数据

store/index.js

export default new Vuex.Store({
  state: {
    //轮播图数据
    bannerList: []
  },
  mutations: {
    //修改bannerList
    changeBannerList(state, arr) {
      state.bannerList = arr;
    }
  },
  actions: {
    //发请求bannerList
    reqBannerList(context){
      //发请求
      reqBanner().then(res=>{
        //修改bannerList
        context.commit("changeBannerList",res.data.list)
      })
    }
  },
  getters:{
    //导出数据给组件用
    bannerList(state){
      return state.bannerList;
    }
  },
  modules: {
  }
})

home.vue

import {mapGetters,mapActions} from "vuex"
export default {
  computed:{
    ...mapGetters(["bannerList"])
  },
  methods:{
    ...mapActions(["reqBannerList"])
  },
  mounted(){
    //进来发请求
    this.reqBannerList()
  }
}

2.首页分类数据

store/index.js

export default new Vuex.Store({
  state: {
    //首页分类数据
    cateList: []
  },
  mutations: {
    //修改分类列表
    changeCateList(state, arr) {
      state.cateList = arr;
    }
  },
  actions: {
    //请求分类列表
    reqCateList(context){
      //发请求
      reqCate().then(res=>{
        //修改分类列表
        context.commit("changeCateList",res.data.list)
      })
    }
  },
  getters: {
    //导出分类列表
    cateList(state){
      return state.cateList
    }
  },
})

home.vue

import {mapGetters,mapActions} from "vuex"
export default {
  computed:{
    ...mapGetters(["cateList"])
  },
  methods:{
    ...mapActions(["reqCateList"])
  },
  mounted(){

    //获取分类
    this.reqCateList()
  }
}

3.首页商品数据

store/index.js

export default new Vuex.Store({
  state: {
    
    //商品
    goodsList: [],
    //导航数据
    navs:["热门推荐","上新推荐","所有商品"],
    n:0
  },
  mutations: {
    
    changeGoodsList(state, arr) {
      state.goodsList = arr;
    },
    //修改n
    changeN(state,n){
      state.n=n;
    }
  },
  actions: {
   
    //请求goodsList
    reqGoodsList(context){
      //发请求
      reqGoods().then(res=>{
        //修改分类列表
        context.commit("changeGoodsList", res.data.list)
      })
    },
    //修改n
    changeN(context,n){
      context.commit("changeN",n)
    }
  },
  getters: {
   
    //导出goodsList
    goodsList(state){
      return state.goodsList
    },
    //导出navs
    navs(state){
      return state.navs
    },
    //导出n
    n(state){
      return state.n
    },
  },
})

home.vue引入使用

import {mapGetters,mapActions} from "vuex"
export default {
  computed:{
    ...mapGetters(["goodsList","navs","n"])
  },
  methods:{
    ...mapActions([reqGoodsList","changeN"])
  },
  mounted(){
  
    //获取商品
    this.reqGoodsList();//[{content:[{},{}]},{content:[{},{}]},{content:[{},{}]}]
  }
}

4.状态层分模块

目录:

-src
	-store
		index.js //创建仓库对象,并导出
		mutations.js //根上的state、getters、mutations
		actions.js //根上的状态的逻辑
		-modules //模块
			home.js
			list.js

list.js

import {  reqList } from '../../request';
let state = {
    //商品列表页面的数据
    list: []
}
let mutations = {
    //修改商品列表页面的数据
    changeList(state, arr) {
        state.list = arr;
    }
}
let actions = {
    //请求商品列表页面的数据
    reqList(context, id) {
        //发请求
        reqList(id).then(res => {
            context.commit("changeList", res.data.list.goodData)
        })
    }
}
let getters = {
    //导出list
    list(state) {
        return state.list
    },
}


export default {
    state,
    mutations,
    actions,
    getters,
     //命名空间
     namespaced: true
}

index.js

import actions from "./actions"
import {state,mutations,getters} from "./mutations"

import home from "./modules/home"
import list from "./modules/list"

export default new Vuex.Store({
  state,
  mutations,
  actions,
  getters,
  modules: {
    home,
    list,
  }
})

list.vue取数据

import {mapGetters,mapActions} from "vuex"
export default {
  computed:{
    ...mapGetters({
      d:"list/list"
    })
  },
  methods:{
    ...mapActions({
      getList:"list/reqList"
    })
  },
  mounted(){
    this.getList(this.$route.query.id)
  }
}

4.登录

store/mutations.js

export let state={
    userInfo:localStorage.getItem("userInfo")?JSON.parse(localStorage.getItem('userInfo')):{}
}
export let mutations= {
   changeUserInfo(state,obj){
       state.userInfo=obj
   }
}
export let getters={
    userInfo(state){
        return state.userInfo;
    }
}

store/actions.js

export default {
    //修改userInfo
    changeUserInfo(context,obj){
        //提交mutations
        context.commit("changeUserInfo",obj)

        //本地存储存一份
        localStorage.setItem("userInfo",JSON.stringify(obj))
    }
}

login.vue

methods: {
    ...mapActions(["changeUserInfo"]),
    login() {
      reqLogin(this.user).then((res) => {
          if(res.data.code==200){
            //存入vuex
            this.changeUserInfo(res.data.list)
            
            this.$router.push("/")
          }
      });

    },
  },

home.vue退出登录

 logout(){
      this.changeUserInfo({})
    }
原文地址:https://www.cnblogs.com/chenhaiyun/p/14788111.html