【Vue2】Vuex 基础使用

作者: 睡神疯子 | 来源:发表于2021-03-24 03:55 被阅读0次

本文仅为 vuex 使用方法,如有不对的地方,欢迎指正。
项目使用可以直接拉到后面 vuex 实际项目中使用部分。

首先为啥要用 vuex,用它有什么好处。

  • 数据跨组件共享。
  • 防止数据意外修改。程序过于庞大或多人开发时,容易不知道是哪改数据, vuex 可以记录哪个组件修改的修改的。
  • 调试、测试方便,同上。

vuex 基本描述

文档地址:https://vuex.vuejs.org/zh/
核心思想(流程):

vuex 流程
  • state 存储、数据;包含了所有变量也只有变量。
  • mutations 修改数据、追踪;操作 state;vue-devtools 上监控到的就是这一属性,只能有同步操作。
    mutation 都有一个字符串的 事件类型 (type)和 一个 回调函数 (handler)。这个回调函数就是我们实际进行状态更改的地方,并且它会接受 state 作为第一个参数:
mutations: {
  add (state) {
    // 变更状态
    state.count++
  }
}

store.commit('add') 调用 mutations 中函数的方法,可以传入参数。

mutations: {
  add (state, args) {
    state.count += args.n
  }
}
// 调用
store.commit('add', {n: 10})
  • actions 封装、组合;操作 mutations,可以有异步和同步操作,数据请求一般放这。
    Action 函数接受一个与 store 实例具有相同方法和属性的 context 对象,因此你可以调用 context.commit 提交一个 mutation,或者通过 context.statecontext.getters 来获取 stategetters
actions: {
  add (context) {
   context.commit('add')
  }
}

store.dispatch('add') 调用 actions 中函数的方法,可以传入参数。

actions: {
  add ({commit}, args) {
   commit('add', args)
  }
}
// 以载荷形式分发
store.dispatch('add', {
  n: 10
})

// 以对象形式分发
store.dispatch({
  type: 'add',
  n: 10
})
  • vue components 可以从 state 读数据,state更新了 vue components 也会更新,vue components只能通过调用 actions 操作数据。

vuex 目录结构

这只是个示例,这目录官网扒的,嘿嘿嘿

├── 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 使用前置

vuex 可以直接在 main.js 中直接引入,也可以独立出一个文件,再引入到 main.js 中。
先安装 vuex:npm install vuex

直接在 main.js 中直接引入

main.js 文件:

import Vue from 'vue'
// 第一步 引入
// 在主 js 文件 main.js 中引入
import Vuex from 'vuex';

// 第二步 添加到vue身上
// 把 vuex 的操作方法挂到 vue 上
Vue.use(Vuex);

// 第三步 声明 store 对象
// 必须先 use 才能进行操作,然后把 store 对象挂到 vue 上
const store=new Vuex.Store({
  strict: process.env.NODE_ENV!='production',   //严格模式:防止直接修改state,打开时会影响性能,只在开发模式打开;process.env.NODE_ENV 是 webpack 配置取的变量
  state: {a: 12, b: 5},                         //核心:数据
  mutations: {
    add(state, n){
      state.a+=n;
    }
  },
  actions: {
    add({commit}, n){
      commit('add', n); // 调用 mutations 中的 add
    }
  },
  getters: {},
  modules: {}
});
new Vue({
  el: '#app',
  router,
  store,
  components: { App },
  template: '<App/>'
})

vue 文件:

<template>
    <div>
      a: {{$store.state.a}}<br/>
      <input type="button" value="+5" @click="fn()">
    </div>
  </template>
  
  <script>
  export default {
    data () {
      return {
      }
    },
    methods: {
      fn(){
        //this.$store.state.a+=5;// 直接改也可以改,但会报错
        //this.$store.commit('add', 5);// 使用 mutations 也可以改,但是一般不会用
        this.$store.dispatch('add', 5);
      }
    }
  }
  </script>

把 vuex 独立到 store 文件夹中

store/index.js 文件:

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

Vue.use(Vuex);
const store=new Vuex.Store({
  strict: process.env.NODE_ENV!='production', 
  state: {a: 12, b: 5},
  mutations: {
    add(state, n){
      state.a+=n;
    }
  },
  actions: {
    add({commit}, n){
      commit('add', n);
    }
  },
  getters: {},
  modules: {}
});
export default store

main.js 文件:

import Vue from 'vue'
import App from './App'
import router from './router'
import store from './store'

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

vue 文件无需改动。

vuex 实际项目中使用

项目中使用时就要用到 getters 函数,可以把它看成 store 的计算属性。

vuex 有几个辅助函数,把 vuex 的函数映射成 vue 组件中对应的函数,简化操作

  • mapState state -> computed
  • mapActions actions -> methods
  • mapGetters getters -> computed

store/index.js 文件:

import Vue from 'vue'
import Vuex from 'vuex';
Vue.use(Vuex);
const store=new Vuex.Store({
  strict: process.env.NODE_ENV!='production',
  state: {a: 12, b: 5},
  mutations: {
    add(state, n){
      state.a+=n;
    },
    addA(state, n){
      state.a+=n;
    },
    addB(state, n){
      state.b+=n;
    },
    setOnline(state, id){
      state.users.forEach(user=>{
        if(user.id==id){
          user.online=true;
        }
      });
    },
    setUsers(state, users){
      state.users=users;
    }
  },
  actions: {
    add({commit}, n){
      commit('add', n);
    },
    addA({commit}, n){
      commit('addA', n);
    },
    addB({commit}, n){
      commit('addB', n);
    },
    setOnline({commit}, id){
      commit('setOnline', id);
    },
    async readUsers({commit}){
      let res=await fetch('http://localhost:2021/static/user.txt');
      // [{"id":3,"name":"blue","age":18,"online":true},{"id":5,"name":"zhangsan","age":22,"online":false},{"id":11,"name":"lisi","age":25,"online":true}]
      let users=await res.json();

      commit('setUsers', users);
    }
  },
  getters: {
    count(state){
      return state.a+state.b;
    },
    onlineUsers(state){
      return state.users.filter(user=>user.online);
    }
  },
  modules: {}
});
export default store

vue 文件:

<template>
  <div>
    <div>a: {{a}}</div>
    <div>b: {{b}}</div>
    <div>count: {{count}}</div>
    <input type="button" value="a+5" @click="addA(5)" />
    <input type="button" value="b+3" @click="addB(3)" />
    <br>
    <br>
    <input type="button" value="法外狂徒出现" @click="setOnline(5)" />
    <ul>
      <li v-for="user in onlineUsers" :key="user.name">
        名字:{{user.name}}
        年龄:{{user.age}}
      </li>
    </ul>
  </div>
</template>

<script>
import {mapState, mapActions, mapGetters} from 'vuex';

export default {
  async created(){
    await this.readUsers();
  },
  methods: {
    ...mapActions(['addA', 'addB', 'setOnline', 'readUsers']),
  },
  computed: {
    ...mapState(['a', 'b']),
    ...mapGetters(['count', 'onlineUsers'])
  }
}
</script>

vuex 模块化

首先需要在 store/index.js引入对应子模块,注意子模块的 mutationsactions 重名会多次执行。
store/index.js:

import Vue from 'vue'
import Vuex from 'vuex';
import boy from './boy';
import girl from './girl';
Vue.use(Vuex);

const store=new Vuex.Store({
  strict: process.env.NODE_ENV!='production',
  state: {str: 'liangzai'},
  getters: {
    couples(state) {
      return `${state.boy.str} && ${state.girl.str}`;
    }
  },
  modules: {
    boy,
    girl
  }
});
export default store

store/boy.js:

export default {
  state: {
    str: 'boy'
  },
  mutations: {
    'boySetStr': function (state, s){
      console.log('boy 的 setStr');
      state.str=s;
    }
  },
  actions: {
    'boySetStr': function ({commit}, s){
      commit('boySetStr', s);
    }
  }
}

store/girl.js:

export default {
  state: {
    str: 'girl'
  },
  mutations: {
    'girlSetStr': function (state, s){
      console.log('girl 的 setStr');
      state.str=s;
    }
  },
  actions: {
    'girlSetStr': function ({commit}, s){
      commit('girlSetStr', s);
    }
  }
}

vue 文件:

<template>
  <div>
    str: {{str}}<br>
    couples: {{couples}}<br>
    a_str: {{str_boy}}<br>
    b_str: {{str_girl}}<br>
    <input type="button" value="设置 boy" @click="set_boy('aaa')">
    <input type="button" value="设置 girl" @click="set_girl('bbb')">
    <br>
  </div>
</template>
<script>
import {mapState, mapActions, mapGetters} from 'vuex';

export default {
  // created(){console.log(this.$store)},
  methods: {
    ...mapActions({
      set_boy: 'boySetStr',
      set_girl: 'girlSetStr'
    })
  },
  computed: {
    ...mapState(['str']),
    ...mapState({
      str_boy: state=>state.boy.str,
      str_girl: state=>state.girl.str,
    }),
    ...mapGetters(['couples'])
  }
}
</script>

参考代码下载:https://github.com/windliang/simpleJS/tree/master/vue/vuexDemo

相关文章

  • 【Vue2】Vuex 基础使用

    本文仅为 vuex 使用方法,如有不对的地方,欢迎指正。项目使用可以直接拉到后面 vuex 实际项目中使用部分。 ...

  • Vuex最详细教学

    一、Vuex单界面到多界面状态管理切换: 1.安装配置vuex,版本依赖 vue2的项目使用vuex3,vue3的...

  • vue2 vuex的使用

    vuex在vue2中的使用与在vue3中不同,首先,需要安装vuex3而不是vuex4,然后,需要在全局中进行定义...

  • vue项目构建

    一、项目使用技术栈: vue2、 vue-router、 vuex、 axios、关于ui的框架选取,依项目而定(...

  • 1.Nuxt 介绍

    一. Nuxt.js 默认集成一下组件/框架 Vue2 、Vue-router、Vuex、Vue-Meta 且使用...

  • vue3 打造一个可以发挥compositionAPI优势的轻量

    Vuex 的遗憾 Vuex 是基于 Vue2 的 option API 设计的,因为 optionAPI 的一些先...

  • 制作一个轻量级的状态管理插件:Vue-data-state

    Vuex 是不是有点繁琐? Vuex 是针对 Vue2 来设计的,因为 option API 本身有很多缺点,所以...

  • Vuex的使用

    目录 安装 注意这里如果使用的是vue2版本需要指定vuex版本为3,如果用的是vue3版本那可以用最新的vuex...

  • Vue3中使用Pinia

    Vue2 中使用Vuex进行状态管理,在Vue3中,引入了Pinia,如果使用Vue3的脚手架搭建项目,其中包含了...

  • vuex基础使用

    vuex是什么? vuex是一个状态管理工具,在使用vue写代码的时候能帮助我们更好的管理数据 当我们需要对数据进...

网友评论

    本文标题:【Vue2】Vuex 基础使用

    本文链接:https://www.haomeiwen.com/subject/srpacltx.html