vuex 核心 & 数据响应式原理

code_lee3年前vue1910

vuex核心

1. state单一状态树

单一状态树: single sourse of truth ,也称单一数据源

2. getters (类似与单个组件中的计算属性computed)

    more20(state){
      return state.stu.filter(s => s.age > 20 )
    },
    length(state,getters){
      return getters.more20.length
    },
    moreAge(state){  // 使用时需传参
      // return function(age){
      //   return state.stu.filter(s => s.age > age)
      // }
      return age => {
        return state.stu.filter(s => s.age > age)
      }
    }

3. mutation (类似于methods)

vuex里store状态更新的唯一方式,提交mutation
主要包括两部分:

  • 字符串的事件类型(type)

  • 回调函数(handle),第一个参数是state

  //定义
  //index.js:
  increment (state) {
       state.countor ++;
  }
  //increment: 事件类型
  //剩余部分:回调函数

  //使用:
  //App.vue:
  this.$store.commit('increment')

传递参数:更新数据时额外携带一些参数(payload)

index.js

 // 加上一个不固定的数 
 // 1. 普通提交风格
    addCount(state,count){
      state.countor += count
    },
// 2. 特殊提交风格
    addCount(state,payload){   //传过来的payload是一整个对象
      state.countor += payload.count
    }

 // 添加学生
    addStu(state,nStu){
      state.stu.push(nStu)
    }

App.vue:

//普通
addCount(count){
    this.$store.commit('addCount',count)
},
//特殊
addCount(count){
    this.$store.commit({
        type: 'addCount',
        count
    })
},
addSt(){
    const stu = {id: 115, name: 'ali', age: 27}
    this.$store.commit('addStu',stu)
}

类型常量

在store文件夹下,创建一个mutation-types.js文件
存放mutations里面的方法名字 对应的常量,
使用时导入,避免index.js定义时和.vue使用时,方法名写错,不好维护 (适合多人开发)
同步函数

mutation中必须是同步函数,否则devtools跟踪不到数据的修改
异步—— 移步action
4. action (类似mutation,但是异步)

Action 函数接受一个与 store 实例具有相同方法和属性的 context 对象 (context不是store实例本身)
index.js:

actions: {
    // context上下文
    achangeStu(context) {
      setTimeout(() => {
        context.commit('changeStu')
      }, 1000);
    }
  }

App.vue:

changeStuAc(){ // 异步修改
    this.$store.dispatch('achangeStu')
}

结合promise:

achangeStu(context, payload) {
    return new Promise((resolve,reject)=>{
        setTimeout(() => {
          context.commit('changeStu')
          console.log(payload.message);
          
          resolve('1111promise')
        }, 1000);
      })

}
changeStuAc(){ // 异步修改
      this.$store.dispatch('achangeStu',{
        message: '携带的信息'
      }).then(ac =>{
        console.log('里面已完成');    
        console.log(ac);
    })
}

5. modules

由于使用单一状态树,应用的所有状态会集中到一个比较大的对象。当应用变得非常复杂时,store 对象就有可能变得相当臃肿。

为了解决以上问题,Vuex 允许我们将 store 分割成模块(module)。每个模块拥有自己的 state、mutation、action、getter、甚至是嵌套子模块——从上至下进行同样方式的分割:

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 的状态

App.vue:

    $store.state.a.mAcount  //---- moduleA中的 state -- mAcount
    
    $store.getters.mApowercount   //------- moduleA中的 gettsers -- mApowercount    
    
    chan(){
          this.$store.commit('mAchangec','年') // ---- moduleA中的 mutations -- mAchangc
     }

    acchan(){
          this.$store.dispatch('mAchanC','2月')   //---- moduleA中的actions -- mAchanC
    }

数据响应式原理:

state中的数据,属性,会被加入到响应式系统中,而响应式系统会监听属性的变化。
当属性变化,通知所有界面中用到该属性的地方,是界面发生刷新

响应式规则:

    提前在store中初始化好需要的属性
    当给state中的对象添加新属性时,使用下面的方式:
    – 使用Vue.set(obj, ‘new prop name’, ‘value’ ); Vue.delete(obj, ‘prop name’)
    – 用新对象给旧对象重新赋值

相关文章

格式金额,默认保留两位小数,并格式化为千分位

格式金额,默认保留两位小数,并格式化为千分位

项目场景:商城类项目中大多需要格式化金额,后缀保留两位小数,并且千元之后加上千分位符号 例子:32,131.00 这种金额,贴上js代码,可以新建一个js引用就行解决方案://格式金额,默认保留两位小...

vue中provide和inject使用

vue中provide和inject使用

1、provide/inject有什么用?常用的父子组件通信方式都是父组件绑定要传递给子组件的数据,子组件通过props属性接收,一旦组件层级变多时,采用这种方式一级一级传递值非常麻烦,而且代码可读性...

解决Error: Cannot find module 'node-sass'问题

解决Error: Cannot find module 'node-sass'问题

解决办法:1.在项目目录cmd下运行 npm install -g cnpm --registry=https://registry.npm.taobao.or...

vue3中报ESLint: 'defineProps' is not defined.(no-undef)

vue3中报ESLint: 'defineProps' is not defined.(no-undef)

遇到问题:vue3中使用defineProps中报错,飘红,如下图解决方案:找到eslint.js文件,在env处添加代码  'vue/setup-compiler-mac...

el-table 单元格显示tooltip提示,并修改样式

 <el-table-column v-for="(item, index) in tableLabel" pro...

svg 圆形渐变进度条

componentProgress.vue<template>   <div class='progress-container'&g...