详解vuex 渐进式教程实例代码


Posted in Javascript onNovember 27, 2018

vuex 渐进式教程,从入门级带你慢慢深入使用vuex。

Vuex 是什么?

Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式。它采用集中式存储管理应用的所有组件的状态, 并以相应 的规则保证状态以一种可预测的方式发生变化。

vuex官网: vuex.vuejs.org/zh/guide/

安装

安装vue-cli:

cnpm install -g vue-cli
 vue init webpack vuex

安装vuex

cnpm i vuex --save

1.初级使用方法

// main.js

import Vue from 'vue'
import App from './App'
import router from './router'
import Vuex from 'vuex' // 引入vuex

Vue.config.productionTip = false

Vue.use(Vuex);

let store = new Vuex.Store({ // store 对象
 state:{
  count:0
 }
})

/* eslint-disable no-new */
new Vue({
 el: '#app',
 router,
 store, //使用store,这可以把 store 的实例注入所有的子组件
 components: { App },
 template: '<App/>'
})

此时可以在组件中使用 this.$store.state.count 获取store中state的值。如:

// 在组件的computed中使用
 computed:{
   count(){
   return this.$store.state.count;
   }
 }

想想一下当项目比较大的时候数据繁琐,如果按照上述方法使用vuex,当你打开main.js你看的到场景是比较混乱的,各种数据繁杂在一起,不便于日后的维护。请看下一步:

2.中级使用方法: modules 模块化

state用法

2.1 在main.js中删除下述这部分代码

let store = new Vuex.Store({ // store 对象
 state:{
  count:0
 }
})

2.2. 在src目录下新建store文件夹并在该文件夹下新建index.js文件。 在 store/index.js写入:

import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
const store = new Vuex.Store({
 strict:true, // 开启严格模式 确保state 中的数据只能 mutations 修改
 state:{
  count:0
 }
})
export default store;

对应的main.js应该写入:

import store from './store'

写到这里,我们在组件里就可以获取到store里的state的值了

2.3 为了方便测试直接在HelloWorld.vue 中使用store

<template>
 <div class="hello">
  <h2>{{count}}</h2>
 </div>
</template>

<script>
export default {
 name: 'HelloWorld',
 computed:{
   count(){
    return this.$store.state.count;
   }
 }
}
</script>

很多时候咱们要对state里的值进行操作,在vuex提供了一个方法mutations

mutations用法(使用mutations可以修改state的值)

在sore\index.js写入:

//
...
 state:{
  count:0
 },
 mutations:{ // 更改数据的方法
  add(state){
   state.count++
  },
  //提交载荷用法
//   add(state,n){ 
//   state.count += n
//  },
  sub(state){
   state.count--
  }
 }
...
//

组件(HelloWorld.vue)中使用mutations里对应的方法:

<template>
 <div class="hello">
  <button @click="add">+</button>
  <h2>{{count}}</h2>
  <button @click="sub">-</button>
 </div>
</template>

<script>
export default {
 name: 'HelloWorld',
 computed:{
   count(){
    return this.$store.state.count;
   }
 },
  methods:{
  add(){
   this.$store.commit('add');
  },
  
  //提交载荷用法
  // add(){ 
  //  this.$store.commit('add',10);
  // },
  
  //对象风格的提交方式
  //  store.commit({
  //   type: 'add',
  //   n: 10
  //   })
  
  sub(){
   this.$store.commit('sub');
  }
 }
}
</script>

此时就可以对count进行修改了。

当你想异步操作的时候,由于mutation必须是同步的这一点,此时不能采用mutation对state 进行修改。action派上用场了,action就是一个函数集合,在里面怎么操作都可以,只要最后触发mutation 就可以了。

注解mutation不能异步操作的原因:

mutations: {
  add (state) {
   api.callAsyncMethod(() => {
  state.count++
  })
 }
}

现在想象,我们正在 debug 一个 app 并且观察 devtool 中的 mutation 日志。每一条 mutation 被记录,devtools 都需要捕捉到前一状态和后一状态的快照。然而,在上面的例子中 mutation 中的异步函数中的回调让这不可能完成:因为当 mutation 触发的时候,回调函数还没有被调用,devtools 不知道什么时候回调函数实际上被调用——实质上任何在回调函数中进行的状态的改变都是不可追踪的。

Action 用法

在sore\index.js写入:

mutations:{ // 更改数据的方法
add(state){
   state.count++
  },
  sub(state){
   state.count--
  }
 },
++++
 actions:{
  add(context){ // context 与 store 实例具有相同方法和属性(但不是store 实例)
   setTimeout(()=>{
    context.commit('add');
   },1000)
  }
 }
++++

组件(HelloWorld.vue)中使用getters里对应的方法:

<template>
 <div class="hello">
  <button @click="add">+</button>
  ++++
  <button @click="add_action">action +</button>
  ++++
  <h2>{{count}}</h2>
  <button @click="sub">-</button>
  <div>
   test: {{doneTodos[0].text}} <br>
   length: {{doneTodosLength}}
  </div>
 </div>
</template>
export default {
 methods:{
  add(){
   this.$store.commit('add');
   // console.log(this);
  },
  sub(){
   this.$store.commit('sub');
  },
  ++++
  add_action(){
   this.$store.dispatch('add');
  }
  ++++
 }
}

看到这里有没有想过当我们使用state中某一个数据时,我们只想用该数据中符合条件的数据。比如:

state:{
  count:0,
  todos: [
   { id: 1, text: 'text1--true', done: true },
   { id: 2, text: 'text2--false', done: false }
  ]
 }

此时我们只想获取state.todos中done为true的数据时我们应该怎么获取?

可能会有以下两种方案:

1.每个在组件中首先获取todos,然后使用filter方法过滤;

2.写一个公共函数在每个组件中调用以下;

如果用到todos中done为true的组件很多,这两种方法都是很不理想的。Vuex为此为我们引入了一个方法Getter。

Getter 用法

官方解释:Vuex 允许我们在 store 中定义“getter”(可以认为是 store 的计算属性)。就像计算属性一样,getter 的返回值会根据它的依赖被缓存起来,且只有当它的依赖值发生了改变才会被重新计算。

在sore\index.js写入:

mutations:{ // 更改数据的方法
  add(state){
   state.count++
  },
  sub(state){
   state.count--
  }
 },
 +++
 getters:{ // 用法类似组件中的 computed, 可以认为是store的计算属性
  doneTodos:state => { // Getter 接受 state 作为其第一个参数:
   return state.todos.filter(todo => todo.done) // -> [{ id: 1, text: 'text1--true', done: true }]
  },
  // Getter 也可以接受其他 getter 作为第二个参数
  doneTodosLength:(state,getters) => {
   return getters.doneTodos.length // -> 1
  },
 +++
 }

组件(HelloWorld.vue)中使用getters里对应的方法:

<template>
 <div class="hello">
  <button @click="add">+</button>
  <h2>{{count}}</h2>
  <button @click="sub">-</button>
+++
  <div>
   test: {{doneTodos[0].text}} <br>
   length: {{doneTodosLength}}
  </div>
+++  
 </div>
</template>
<script>
export default {
 //...
  computed:{
  +++
    doneTodos(){
     return this.$store.getters.doneTodos // -> [{ id: 1, text: 'text1--true', done: true }]
    },
    doneTodosLength(){
     return this.$store.getters.doneTodosLength // -> 1
    }
  +++
 }
}
</script>

本篇代码地址: github.com/xioasa/vue-…

总结

以上所述是小编给大家介绍的vuex 渐进式教程实例代码,希望对大家有所帮助,如果大家有任何疑问欢迎给我留言,小编会及时回复大家的!

Javascript 相关文章推荐
农历与西历对照
Sep 06 Javascript
翻译整理的jQuery使用查询手册
Mar 07 Javascript
javascript 学习之旅 (2)
Feb 05 Javascript
防止xss和sql注入:JS特殊字符过滤正则
Apr 18 Javascript
JavaScript实现的类字典插入或更新方法实例
Jul 10 Javascript
jquery动感漂浮导航菜单代码分享
Apr 15 Javascript
使用JSON作为函数的参数的优缺点
Oct 27 Javascript
Webpack实战加载SVG的方法
Dec 26 Javascript
关于Angularjs中跨域设置白名单问题
Apr 17 Javascript
angularjs中判断ng-repeat是否迭代完的实例
Sep 12 Javascript
JavaScript判断数组类型的方法
Oct 23 Javascript
JS数组push、unshift、pop、shift方法的实现与使用方法示例
Apr 29 Javascript
解决vue 界面在苹果手机上滑动点击事件等卡顿问题
Nov 27 #Javascript
Node+OCR实现图像文字识别功能
Nov 26 #Javascript
图片文字识别(OCR)插件Ocrad.js教程
Nov 26 #Javascript
JS 验证码功能的三种实现方式
Nov 26 #Javascript
trackingjs+websocket+百度人脸识别API实现人脸签到
Nov 26 #Javascript
tracking.js页面人脸识别插件使用方法
Apr 16 #Javascript
详解Node.js 中使用 ECDSA 签名遇到的坑
Nov 26 #Javascript
You might like
php array的学习笔记
2012/05/10 PHP
Laravle eloquent 多对多模型关联实例详解
2017/11/22 PHP
PHP连接sftp并下载文件的方法教程
2018/08/26 PHP
gearman中worker常驻后台,导致MySQL server has gone away的解决方法
2020/02/27 PHP
我遇到的参数传递中 双引号单引号嵌套问题
2010/02/11 Javascript
javascript cookies操作集合
2010/04/12 Javascript
javascript与CSS复习(二)
2010/06/29 Javascript
js如何判断用户是否是用微信浏览器
2014/06/05 Javascript
使用AngularJS 应用访问 Android 手机的图片库
2015/03/24 Javascript
JavaScript与jQuery实现的闪烁输入效果
2016/02/18 Javascript
JavaScript的instanceof运算符学习教程
2016/06/08 Javascript
Bootstrap禁用响应式布局的实现方法
2017/03/09 Javascript
利用JS对iframe父子(内外)页面进行操作的方法教程
2017/06/15 Javascript
JS实现点击Radio动态更新table数据
2017/07/18 Javascript
Jquery中.bind()、.live()、.delegate()和.on()之间的区别详解
2017/08/01 jQuery
浅谈Postman解决token传参的问题
2018/03/31 Javascript
了解Javascript中函数作为对象的魅力
2019/06/19 Javascript
JavaScript canvas实现雪花随机动态飘落
2020/02/08 Javascript
jQuery实现视频展示效果
2020/05/30 jQuery
[02:18]《我与DAC》之工作人员:为了热爱DOTA2的玩家们
2018/03/28 DOTA
Python 爬虫的工具列表大全
2016/01/31 Python
python互斥锁、加锁、同步机制、异步通信知识总结
2018/02/11 Python
python面向对象 反射原理解析
2019/08/12 Python
Python算法中的时间复杂度问题
2019/11/19 Python
如何将 awk 脚本移植到 Python
2019/12/09 Python
Python截图并保存的具体实例
2021/01/14 Python
利用CSS3的flexbox实现水平垂直居中与三列等高布局
2016/09/12 HTML / CSS
html5 Canvas实现图片旋转的示例
2018/01/15 HTML / CSS
孕妇装中的著名品牌:Isabella Oliver(伊莎贝拉·奥利弗)
2016/10/31 全球购物
Shoes For Crews法国官网:美国领先的防滑鞋设计和制造商
2018/01/01 全球购物
日常奢侈品,轻松购物:Verishop
2019/08/20 全球购物
高中毕业生自我鉴定范文
2013/09/26 职场文书
大学生求职工作的自我评价
2014/02/13 职场文书
银行青年文明号事迹材料
2014/05/31 职场文书
女性健康知识讲座通知
2015/04/23 职场文书
2016年社会管理综治宣传月活动总结
2016/03/16 职场文书