vuex 渐进式教程(一)

栏目: JavaScript · 发布时间: 5年前

内容简介:vuex 渐进式教程,从入门级带你慢慢深入使用vuex。Vuex 是什么?Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式。它采用集中式存储管理应用的所有组件的状态, 并以相应 的规则保证状态以一种可预测的方式发生变化。

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

Vuex 是什么?

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

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

安装

安装vue-cli:

1.cnpm install -g vue-cli
2. 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 渐进式教程(一)》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

网飞传奇

网飞传奇

[美]吉娜·基廷 / 谭永乐 / 中信出版社 / 2014-1-1 / 42

飞的历史充满了传奇色彩,它的崛起伴随着复杂斗争、幸运转折、个人背叛……它自身的历史比它出租的那些电影还要更富有戏剧性。网飞在1997年建立,而建立的原因仅仅是因为创始人伦道夫和哈斯廷斯没有按时归还租借的DVD,还要缴纳因此而产生的滞纳金。 1999年,网飞公司摒弃了百视达的“每片付租”模式,转而采用了一种订阅模式:用户只需要支付固定费用,就能尽情租片观赏,免去了到期还片日、滞纳金、运费和手续......一起来看看 《网飞传奇》 这本书的介绍吧!

图片转BASE64编码
图片转BASE64编码

在线图片转Base64编码工具

Base64 编码/解码
Base64 编码/解码

Base64 编码/解码

HEX CMYK 转换工具
HEX CMYK 转换工具

HEX CMYK 互转工具