另一个双向绑定machine---状态机vuex

前言

在对于一些要时常大量抓取适当已经请求过来的数据的系统,在路由的转换中我们不想连着路由一起把数据倒来倒去,这个时候我们就需要一个可以存取大量数据的静态存储数据库,这个东西就是我们要讲到的-------状态机Vuex

	官方说法:Vuex 是专门为 Vue.js 设计的状态管理库,它采用集中式存储管理应用的所有组件的状态。

原理

其实在原理上仍然是Vue的双向响应式原理,根据这个框架本身对数据进行劫持和订阅观察,但是他的存取则是新的规则,有新的限制

	核心还是
	Object.defineProperty(obj,obj.attr,descriptor)
  参数: 
    obj
      要在其上定义属性的对象。
    prop
      要定义或修改的属性的名称。

工具

工具作用
State用于数据的存储,是store中的唯一数据源
Getter类似于计算属性,就是对State中的数据进行二次的处理,比如筛选和对多个数据进行求值等
Mutation类似事件,是改变Store中数据的唯一途径,只能进行同步操作
Action类似Mutation,通过提交Mutation来改变数据,而不直接操作State,可以进行异步操作
Module当业务复杂的时候,可以把store分成多个模块进行管理,便于维护

为项目配置状态机

一般在项目中
在这里插入图片描述
基本上这个东西是这样的

import Vue from "vue";
import Vuex from "vuex"; //当然你要先npm下vuex啦 npm install vuex --save


Vue.use(Vuex); //配置进vue里
export default new Vuex.Store({ // 创建状态机实例
  state: {
    user: {
      userName: "",
      avtived: false
    }
  },
  mutations: {
    setUser(state, data) {
      state.user.userName = data.userName;
      state.user.avtived = data.avtived;
    }
  },
  actions: {
    setUser({ commit }, data) {
      // 模拟异步处理
      setTimeout(() => {
        commit("setUser", data);
      }, 3000);
    }
  },
  getters: {
    getUser(state) {
      return state.user;
    }
  }
});


运用

State(其实你可以认为是Vue实例或者其中一个组件的data)

在组件中,通常我们可以用计算属性(computed)来获取state状态并进行处理
下面这个就可以遍历出一个产品清单

<template>
  <div id="app">
     <h2>product-one</h2> 
     <ul>
       <li v-for="(item,index) in product" :key="index">
         <div class="name" v-text="item.name"></div>
         <div class="price" v-text="item.price"></div>
       </li>
     </ul>
  </div>
</template>
<script>

export default {
  components:{
  },
  data() {
    return {
        
    }
  },
  created(){
  },
  computed:{
    product(){
      return this.$store.state.product   //获取状态机中状态
    }
  },
  watch:{
   
  },
  methods: {
    
  }
};

</script>
<style>
#app{
  padding: 1rem;
}
ul{
  list-style: none;
  padding: 0;
}
</style>


Getter(可以认为是vue实例或其中一个组件中的computed)

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

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

Vue.use(Vuex)

export default new Vuex.Store({
  state: {
    product:[
      {name:'apple', price: '2'},
      {name:'banana', price: '3'},
      {name:'pear', price: '4'},
      {name:'melon', price: '5'}
    ],
    count:0,
    str:'江西九江',
  },
  //Getter 接受 state 作为其第一个参数
  getters:{
    changeProduct: (state) => {
      return state.product.map(val => {
          return {
              name: '**' + val.name + '--',
              price: val.price*2
          }
      })
      return state.product
    }
  },
  mutations: {
  },
  actions: {
  },
  modules: {
  }
})

Mutation(类似于methods但是只能同步操作不支持异步)

mutation 必须是同步函数,即是他不支持异步,无法发起请求
更改 Vuex 的 store 中的状态的唯一方法是提交 mutation。Vuex 中的 mutation 非常类似于事件:每个 mutation 都有一个字符串的 事件类型 (type) 和 一个 回调函数 (handler)。这个回调函数就是我们实际进行状态更改的地方,并且它会接受 state 作为第一个参数

  mutations: {
    decrePrice(state){
      state.product.forEach(val => {
          val.price -= 1
      })
    }
  },

mutations就类似事件,子组件中用this.$store.commit(‘事件名’)来获取

<template>
  <div id="app">
     <h2>product-two</h2> 
    <ul>
      <li v-for="(item,index) in product" :key="index">
        <div class="name">水果名:{{item.name}}</div>
        <div class="price">价格:{{item.price}}</div>
      </li>
    </ul>
  </div>
</template>
<script>
import {mapGetters} from 'vuex'
export default {
  components:{
  },
  data() {
    return {
      str:'中国'
    }
  },
  created(){
    this.decrePrice()
  },
  computed:{
  // 使用对象展开运算符将 getter 混入 computed 对象中
  ...mapGetters({
    product:'changeProduct'
  })
  },
  watch:{
   
  },
  methods: {
    decrePrice(){
      return this.$store.commit('decrePrice')
    }
  }
};

</script>

Action

类似于 mutation,不同在于:
(1)Action 提交的是 mutation,而不是直接变更状态。
(2)Action 可以包含任意异步操作
Action 函数接受一个与 store 实例具有相同方法和属性的 context 对象,因此你可以调用 context.commit 提交一个 mutation,或者通过 context.state 和 context.getters 来获取 state 和 getters。
分发dispatch action
子组件中,用this.$store.dispatch(‘action的名字’)来获取。

actions: {
    decrePriceAction(context){
      setTimeout(()=>{
          context.commit('decrePrice')
      }, 2000)
    }
  },

Module

const moduleA = {
  state: { ... },
  mutations: { ... },
  actions: { ... },
  getters: { ... }
}

const moduleB = {
  state: { ... },
  mutations: { ... },
  actions: { ... }
}

const store = new Vuex.Store({
  modules: {
    a: moduleA,
    b: moduleB
  }
})

store.state.a // -> moduleA 的状态
store.state.b // -> moduleB 的状态

严格模式

开启严格模式,仅需在创建 store 的时候传入 strict: true:

const store = new Vuex.Store({
  // ...
  strict: true
})

在严格模式下,无论何时发生了状态变更且不是由 mutation 函数引起的,将会抛出错误。这能保证所有的状态变更都能被调试工具跟踪到。
#开发环境与发布环境
不要在发布环境下启用严格模式!严格模式会深度监测状态树来检测不合规的状态变更——请确保在发布环境下关闭严格模式,以避免性能损失。

你也可以看看这篇

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值