您当前的位置:首页 > 电脑百科 > 程序开发 > 编程百科

VueX使用干货

时间:2020-09-21 10:34:35  来源:  作者:
VueX使用干货

 

vuex简介

  • Vuex是一个为Vue.js应用程序开发的状态管理模式
    • 采用集中式存储管理应用的所有组件的状态,并且相应的规则保证状态以一种可预测的方式发生变化
    • Vuex也集成到Vue的官方调试工具 devtools extension,提供了注入令配置的time-travel调试,状态快照导入导出功能
  • 状态管理是什么:
    • 可以简单的将其看成把需要的多个组件共享的变量全部存储在一个对象里面
    • 然后将这个对象放在顶层的Vue实例中,让其他组件可以使用
    • 那么,多个组件就可以共享这个对象中的所有变量属性了
    • 简单来说就是多个组件需要共享一个状态(或者是变量),那么这个状态放在哪个组件中都不合适,那么就单独的new一个对象,把这个对象看作是一个管家,来管理这些共享的状态信息
  • 有什么状态时需要多个组件共享:
    • 如果一个项目,存在多个界面共享问题
    • 比如用户的登陆状态,用户名称,头像,地理位置信息,商品收藏,购物车中的物品等等
    • 这些状态信息,都可以放在统一的地方,对它进行保存和管理,而且它们还是响应式的

Vuex 安装

  1. 命令行安装
npm install vuex --save
  1. 在src文件夹下创建 store文件夹,在该文件夹下创建 index.js文件,其中写入:
import Vue from "vue";
import Vuex from "vuex"
//1. 安装插件
Vue.use(Vuex);//2. 创建vuex对象
const store = new Vuex.Store({
  state: {},  mutations: {},  actions: {},  getters: {},  modules: {}})//3. 导出story对象
export default store;
  1. 在main.js文件中引入vuex对象
import Vue from 'vue'
import App from './App'
import router from './router'
//引入 vuex 的store对象
import store from "./store";
Vue.config.productionTip = falsenew Vue({  el: '#app',
  router,  store,  render: h => h(App)})

通过 mutation 修改vuex管理的状态

  • 要修改vuex管理的状态必须通过mutation
  • index.js文件
import Vue from "vue";
import Vuex from "vuex"
//1. 安装插件
Vue.use(Vuex);//2. 创建vuex对象
const store = new Vuex.Store({
  state: { //定义被vuex管理的各个状态
    counter: 10
  },  mutations: {//定义方法用于修改vuex管理的状态
    increment(state){      state.counter++;    },    decrement(state){      state.counter--;    }  },  actions: {},  getters: {},  modules: {}})//3. 导出story对象
export default store;
  • App.vue文件
<template>
<div id="app">
  <h3>{{$store.state.counter}}</h3>
  <!--操作vuex管理的状态-->
  <button @click="addition">+</button>
  <button @click="subtration">-</button>
  <hr>
  <hello-vuex/>
</div>
</template>
<script>
    import HelloVuex from "./components/HelloVuex";
    export default {
      name: 'App',
      components:{
        HelloVuex
      },
      methods:{
        addition(){
          //通过mutation修改被vuex管理的状态
          this.$store.commit('increment')
        },
        subtration(){
          //commit()传入的是在index.js中mutations中定义的方法名
          this.$store.commit('decrement')
        }
      }
    }
</script>
  • 具体描述
    • 提取出一个公共的store对象,用于保存多个组件中共享的状态
    • 将store对象放置在 new Vue对象中,这样可以保证在所有的组件中都可以使用到
    • 在其他组件中使用store对象中保存的状态即可
      • 通过 this.$store.属性 的方式来访问状态
      • 通过 this.$store.commit('mutation方法名') 来修改状态
  • 注意事项:
    • 通过提交 mutation的方式,而非直接改变 store.state.属性
    • 这是因为Vuex可以更明确的追踪状态的变化,所以不要直接改变store.state.counter 的值

vuex Getters 的使用

  • 有时候,需要从store 中获取一些state 变异后的状态
  • 在组件中需要拿到 store中的数据,而且这个数据是需要变化后才给到组件或者页面的时候,这时就需要永高getters
  • 抽取出的vuex的index.js配置文件
import Vue from "vue";
import Vuex from "vuex"
//1. 安装插件
Vue.use(Vuex);
//2. 创建vuex对象
const store = new Vuex.Store({
  state: { //定义被vuex管理的各个状态
    students: [
      {id: 1, name: 'bob', age: 18},
      {id: 2, name: 'kobe', age: 22},
      {id: 3, name: 'xyx', age: 25},
      {id: 4, name: 'john', age: 17}
    ]
  },
  getters: {
    //这里定义的是state中变化后的内容
    more20stu(state){
      return state.students.filter(s => s.age > 20);
    }
  }
})
//3. 导出story对象
export default store;
<template>
<div id="app">
  <p>getters中定义的powerConter内容----</p>
  <h3>{{$store.getters.powerConter}}</h3>
  <p>通过getters 中的more20stu 获取state中age大于20的对象---</p>
    <!--通过getters拿到变化后的store中的内容-->
  	{{$store.getters.more20stu}}</div>
</template>
<script>
export default {
  name: 'App',
}
</script>

getters作为参数和传递参数

  1. 作为参数
  • 以上面的代码为例,如果需要拿到 {{$store.getters.more20stu}} 获取的学生的个数
  • 在getters中定义的函数还可以传入第二个参数
import Vue from "vue";
import Vuex from "vuex"
//1. 安装插件
Vue.use(Vuex);
//2. 创建vuex对象
const store = new Vuex.Store({
  state: {
    counter: 10,
    students: [
      {id: 1, name: 'bob', age: 18},
      {id: 2, name: 'kobe', age: 22},
      {id: 3, name: 'xyx', age: 25},
      {id: 4, name: 'john', age: 17}
    ]
  },
  getters: {
    more20stu(state){
      return state.students.filter(s => s.age > 20);
    },
    //传入的第二个参数代表就是当前对象中的getters
    more20stuLenthg(state,getters){
      return getters.more20stu.length;
    }
  },
})
//3. 导出story对象
export default store;
<template>
<div id="app">
  <p>通过getters 中的more20stu 获取state中age大于20的对象---</p>
  {{$store.getters.more20stu}}  <p>getters 作为参数</p>
  <h3>{{$store.getters.more20stuLenthg}}</h3>
</div>
</template>
<script>
export default {
  name: 'App'
}
</script>
  1. 传递参数
  • getters默认是不能传递参数的,如果希望传递参数,那么只能让getters本身返回另一个函数
  • 要获取年龄大于 age的stu对象,age由外部传递进来
import Vue from "vue";
import Vuex from "vuex"
Vue.use(Vuex);
const store = new Vuex.Store({
  state: { //定义被vuex管理的各个状态
    counter: 10,
    students: [
      {id: 1, name: 'bob', age: 18},
      {id: 2, name: 'kobe', age: 22},
      {id: 3, name: 'xyx', age: 25},
      {id: 4, name: 'john', age: 17}
    ]
  },
  getters: {
    //获取年龄大于 age 的学生,这个Age不是写死的,而且别的地方传入进来的
    moreAgeStu(state) {
        //返回一个函数
      return function (age) {
        return state.students.filter(s => s.age > age);
      }
    }
  }
})
//3. 导出story对象
export default store;
<template>
<div id="app">
  <p>getters 传递参数----</p>
    <!--传入一个22给getters中定义的方法,这个方法返回一个函数,这个22就是函数的参数-->
  <p>{{$store.getters.moreAgeStu(22)}}</p>
</div>
</template>
<script>
export default {
  name: 'App'
}
</script>

mutainons 携带参数

  • vuex的store状态的更新唯一方式是:提交Mutations
  • mutations主要包括两部分
  • 字符串的事件类型(type)
  • 一个回调函数(handler) ,该回调函数的第一个参数就是state
  • mutations的定义方式:
mutations: {
    increment(state){        state.count++;    }}
  • 通过mutations更新
increment: function(){
    this.$stote.commit('increment')
}
  • 之前的mutations改变counter是每次 ++ 或者 --,现在需要每次点击按钮 + 多少 -多少由外部传入
mutations: {
    // 第二个参数是外部传入的
    incrementCount(state,count){
        state.counter += count;
    }
},
<template>
<div id="app">
  <p>mutations 传递参数----</p>
  <h4>{{this.$store.state.counter}}</h4>
  <button @click="addCount(5)">+5</button>
  <button @click="addCount(10)">+10</button>
</div>
</template>
<script>
export default {
  name: 'App'
  methods:{
    addCount(count){
        //提交,并传入参数
      this.$store.commit('incrementCount',count);
    }
  }
}
</script>
  • mutitaions传递参数就是在提交comiit的时,commit的第二个参数就是传递给mutations的参数

mutitaions 传入多个参数

  • 多个参数使用一个对象传入
addStu(){
      const stu = {id: 5, name: 'alan', age:30};
      this.$store.commit('addSutdent',stu);
}

mutations提交风格

  • 之前通过commit进行提交是一种普通的方式
  • Vue还提供了另外一种风格,它是一个包含type属性的对象,被称为mutations负载(payload)
addCount(count){
    //普通的提交风格    //this.$store.commit('incrementCount',count);
    //特殊的提交风格    this.$store.commit({
        type: 'incrementCount',
        count    })},
mutations: {//定义方法用于修改vuex管理的状态
    incrementCount(state,payload){
      state.counter += payload.count;
    }
}

mutations响应规则

  • vuex的store中的state是响应式的,当state中的数据发生改变时,vue组件会自动更新
  • 这就要求必须遵守一些vuex对应的规则
    • 提前在store中初始化好所需的属性
    • 当给state中的对象添加新属性时,使用下面的方式
      • 方式一: 使用 Vue.set(obj, 'newProp', 123)
      • 方式二: 用新对象给旧对象重新赋值
  • 给state中定义好的对象添加属性
<template>
<div id="app">
  <p>store.state.info的内容是否是响应式的-------</p>
  <button @click="updateInfo">修改 info</button>
  <h2>{{$store.state.info}}</h2>
</div>
</template>
<script>
export default {
  name: 'App',
  methods:{
      //修改info对象,并且是响应式的
    updateInfo(){
      this.$store.commit('updateInfo')
    }
  }
}
</script>
import Vue from "vue";
import Vuex from "vuex"
Vue.use(Vuex);const store = new Vuex.Store({
  state: { //定义被vuex管理的各个状态  
    info: {      name: 'xiaoyouxin',
      age: 25,
      height: 1.75
    }  },  mutations: {//定义方法用于修改vuex管理的状态
   //通过Vue.set(obj, key, value) 响应式的修改info的信息
    updateInfo(state){      Vue.set(state.info, 'addr', '重庆');
    }  }  })export default store;
  • 给state中定义好的对象删除属性
import Vue from "vue";
import Vuex from "vuex"
Vue.use(Vuex);const store = new Vuex.Store({
  state: { //定义被vuex管理的各个状态
    info: {      name: 'xiaoyouxin',
      age: 25,
      height: 1.75
    }  },  mutations: {//定义方法用于修改vuex管理的状态
    deleteInfo(state){      //删除属性该方式做不到响应式
      // delete state.info.name;
      Vue.delete(state.info, 'name');
    }  } })export default store;

mutation常量类型

  • 在mutation中,自定义了很多事件类型(也就是其中的方法名称)
  • 当项目增大时,vuex管理的状态越来越多,需要更新状态的情况越来越多,那么意味着mutation中的方法越来越多
  • 方法过多,使用者需要花费大量的精力去记住这些方法,甚至是多个文件之间来回切换,查看方法名称,甚至如果不是复制的时候,可能还会出现写错的情况
  • 这时候可以在store文件夹下创建一个js文件用于保存常量
export const INCREMENT = 'increment';
export const INCREMENTCOUNT = 'incrementCount';
export const DECREMENT = 'decrement';
export const ADDSTUDENT = 'addSutdent';
export const UPDATEINFO = 'updateInfo';
export const DELETEINFO = 'deleteInfo';
  • 然后再index.js文件中引入这些常量,并修改mutations中的方法名为 :
import Vue from "vue";
import Vuex from "vuex"// 引入这些常量import {  INCREMENT,DELETEINFO,DECREMENT,ADDSTUDENT,UPDATEINFO,INCREMENTCOUNT} from './mutations-types'Vue.use(Vuex);const store = new Vuex.Store({  state: { //定义被vuex管理的各个状态    counter: 10,    students: [      {id: 1, name: 'bob', age: 18},
      {id: 2, name: 'kobe', age: 22},
      {id: 3, name: 'xyx', age: 25},
      {id: 4, name: 'john', age: 17}
    ],
    info: {      name: 'xiaoyouxin',      age: 25,      height: 1.75    }  },  mutations: {     //修改方法名为 : [常量](){} 的方式
    [INCREMENT](state) {
      state.counter++;    },    [DECREMENT](state) {
      state.counter--;    },    [INCREMENTCOUNT](state,payload){
      state.counter += payload.count;    },    [ADDSTUDENT](state,stu){
      state.students.push(stu);    },    [UPDATEINFO](state){
      Vue.set(state.info, 'addr', '重庆');    },    [DELETEINFO](state){
      Vue.delete(state.info, 'name');    }  }})export default store;
  • 在组件中使用这些常量
<template>
<div id="app">
  <p>mutations 传递参数----</p>
  <h4>{{this.$store.state.counter}}</h4>
  <button @click="addCount(5)">+5</button>
  <button @click="addCount(10)">+10</button>
  <p>mutations 传递参数2----</p>
  <button @click="addStu">添加学生</button>
  {{$store.state.students}}  <p>store.state.info的内容是否是响应式的-------</p>
  <button @click="updateInfo">修改 info 添加属性</button>
  <h2>{{$store.state.info}}</h2>
  <button @click="deleteInfo">修改 info 删除属性</button>
  <h2>{{$store.state.info}}</h2>
</div>
</template>
<script>
  import HelloVuex from "./components/HelloVuex";
    //引入常量
  import {
    INCREMENTCOUNT, ADDSTUDENT, UPDATEINFO, DELETEINFO
  } from "./store/mutations-types"
export default {
  name: 'App',
  methods:{
    addCount(count){
      this.$store.commit({
        type: INCREMENTCOUNT,  
        count
      })
    },
    addStu(){
      const stu = {id: 5, name: 'alan', age:30};
        //使用常量作为commit提交的参数
      this.$store.commit(ADDSTUDENT,stu);
    },
    updateInfo(){
        //使用常量作为commit提交的参数
      this.$store.commit(UPDATEINFO)
    },
    deleteInfo(){
      this.$store.commit(DELETEINFO);
    }
  }
}
</script>
<style>
</style>

Action 基本定义

  • 通常情况下Vuex要求mutation中的方法必须是同步方法
    • 主要原因是当我们使用devtools时,devtools可以帮助我们捕捉mytations的快照
    • 但是如果是异步操作,那么devtools将不能很好的追踪这个操作由什么时候被完成
  • 如果有些情况下,确实需要在vuex中进行一些异步操作,比如网络请求,必然时异步的,这时候使用Action,Action类似于mutations,但是是来替代mutations进行异步操作的
  • 用法,在组件中需要异步修改state中的属性
    • $this.store.dispatch('Action中的函数名')
    • Action中定义的异步函数内部通过mutitaons修改state中的属性
import Vue from "vue";
import Vuex from "vuex"
import {
  INCREMENT,DELETEINFO,DECREMENT,ADDSTUDENT,UPDATEINFO,INCREMENTCOUNT} from './mutations-types'
Vue.use(Vuex);const store = new Vuex.Store({
  state: { //定义被vuex管理的各个状态
    info: {      name: 'xiaoyouxin',
      age: 25,
      height: 1.75
    }  },  mutations: {    [UPDATEINFO](state){      Vue.set(state.info, 'addr', '重庆');
    }  },  actions: {      //在actions中定义的函数中异步调用mutations中的方法
    aUpdateInfo(context){      setTimeout(() => {
        context.commit(UPDATEINFO)      },1000)
    }  }})export default store;
<template>
<div id="app">
  <button @click="updateInfo">修改 info 添加属性</button>
  <h2>{{$store.state.info}}</h2>
</div>
</template>
<script>
  import {
    INCREMENTCOUNT, ADDSTUDENT, UPDATEINFO, DELETEINFO
  } from "./store/mutations-types"
export default {
  name: 'App',
  methods:{
    updateInfo(){
        //通过 dispatch的方式对state中的属性进行异步操作
      this.$store.dispatch('aUpdateInfo')
    }
  }
}
</script>

注意: action传递参数的方式mutitaions的方式一致

modules 的使用

  • vue使用单一状态树,那么也意味着很多状态都会交给vuex来管理
  • 当应用变得非常复杂时,store对象就有了能变得相当臃肿
  • 为了解决这个问题,vuex允许将store分割成模块,而每个模块都拥有自己的state,mutations,actions,gettets等
  • 定义在模块中的东西使用方式和之前是一样的,不做过多笔记
  • 不过getters中定义的函数除了 state,getters之外还可呢传入第三个参数 rootState,这个参数表示之前没有用模块分割的哪个state,可以从这个参数中取出原本定义好的属性
  • 还有一个就是在modules中的cations中定义的函数commit的时候是针对于自己这个模块中的mutations的

项目结构

  • 当vuex管理过多内容时,好的项目结构可以使代码更加清晰
    • index.html
    • main.js
    • api
      • ... 抽取出的API请求
    • components
      • App.vue
      • ...
    • store
      • index.js 组装模块并导出store的地方
      • actions.js 根级别的 action
      • mutations.js 根级别的mutation
      • modules
        • cart.js 购物车模块
        • user.js 用户模块

如果遇到文中代码格式被压缩的情况时,请复制代码到ide中查看



Tags:VueX   点击:()  评论:()
声明:本站部分内容及图片来自互联网,转载是出于传递更多信息之目的,内容观点仅代表作者本人,如有任何标注错误或版权侵犯请与我们联系(Email:2595517585@qq.com),我们将及时更正、删除,谢谢。
▌相关推荐
vuex简介 Vuex是一个为Vue.js应用程序开发的状态管理模式 采用集中式存储管理应用的所有组件的状态,并且相应的规则保证状态以一种可预测的方式发生变化 Vuex也集成到Vu...【详细内容】
2020-09-21  Tags: VueX  点击:(74)  评论:(0)  加入收藏
作者:前端先锋转发链接:https://mp.weixin.qq.com/s/1sl21P0AHPlbFEq4_Q7hVQ前言Vuex 是一把双刃剑。如果使用得当,Vue 可以使你的工作更加轻松。如果不小心,也会使让的代码混...【详细内容】
2020-09-10  Tags: VueX  点击:(110)  评论:(0)  加入收藏
Vuex概念为Vue.js程序开发的一套状态管理器State项目的数据源,整个项目的状态都保存在state里面。 state:{ number:123, name:&#39;bulang&#39;, sex:&#39;boy...【详细内容】
2020-08-20  Tags: VueX  点击:(127)  评论:(0)  加入收藏
▌简易百科推荐
摘 要 (OF作品展示)OF之前介绍了用python实现数据可视化、数据分析及一些小项目,但基本都是后端的知识。想要做一个好看的可视化大屏,我们还要学一些前端的知识(vue),网上有很多比...【详细内容】
2021-12-27  项目与数据管理    Tags:Vue   点击:(1)  评论:(0)  加入收藏
程序是如何被执行的&emsp;&emsp;程序是如何被执行的?许多开发者可能也没法回答这个问题,大多数人更注重的是如何编写程序,却不会太注意编写好的程序是如何被运行,这并不是一个好...【详细内容】
2021-12-23  IT学习日记    Tags:程序   点击:(9)  评论:(0)  加入收藏
阅读收获✔️1. 了解单点登录实现原理✔️2. 掌握快速使用xxl-sso接入单点登录功能一、早期的多系统登录解决方案 单系统登录解决方案的核心是cookie,cookie携带会话id在浏览器...【详细内容】
2021-12-23  程序yuan    Tags:单点登录(   点击:(8)  评论:(0)  加入收藏
下载Eclipse RCP IDE如果你电脑上还没有安装Eclipse,那么请到这里下载对应版本的软件进行安装。具体的安装步骤就不在这赘述了。创建第一个标准Eclipse RCP应用(总共分为六步)1...【详细内容】
2021-12-22  阿福ChrisYuan    Tags:RCP应用   点击:(7)  评论:(0)  加入收藏
今天想简单聊一聊 Token 的 Value Capture,就是币的价值问题。首先说明啊,这个话题包含的内容非常之光,Token 的经济学设计也可以包含诸多问题,所以几乎不可能把这个问题说的清...【详细内容】
2021-12-21  唐少华TSH    Tags:Token   点击:(9)  评论:(0)  加入收藏
实现效果:假如有10条数据,分组展示,默认在当前页面展示4个,点击换一批,从第5个开始继续展示,到最后一组,再重新返回到第一组 data() { return { qList: [], //处理后...【详细内容】
2021-12-17  Mason程    Tags:VUE   点击:(14)  评论:(0)  加入收藏
什么是性能调优?(what) 为什么需要性能调优?(why) 什么时候需要性能调优?(when) 什么地方需要性能调优?(where) 什么时候来进行性能调优?(who) 怎么样进行性能调优?(How) 硬件配...【详细内容】
2021-12-16  软件测试小p    Tags:性能调优   点击:(19)  评论:(0)  加入收藏
Tasker 是一款适用于 Android 设备的高级自动化应用,它可以通过脚本让重复性的操作自动运行,提高效率。 不知道从哪里听说的抖音 app 会导致 OLED 屏幕烧屏。于是就现学现卖,自...【详细内容】
2021-12-15  ITBang    Tags:抖音防烧屏   点击:(23)  评论:(0)  加入收藏
11 月 23 日,Rust Moderation Team(审核团队)在 GitHub 上发布了辞职公告,即刻生效。根据公告,审核团队集体辞职是为了抗议 Rust 核心团队(Core team)在执行社区行为准则和标准上...【详细内容】
2021-12-15  InfoQ    Tags:Rust   点击:(24)  评论:(0)  加入收藏
一个项目的大部分API,测试用例在参数和参数值等信息会有很多相似的地方。我们可以复制API,复制用例来快速生成,然后做细微调整既可以满足我们的测试需求1.复制API:在菜单发布单...【详细内容】
2021-12-14  AutoMeter    Tags:AutoMeter   点击:(20)  评论:(0)  加入收藏
最新更新
栏目热门
栏目头条