文章目录

  • 用处
  • 解析
    • 结构
    • 单一状态树 state
    • getters使用
    • mutations
      • mutations 提交风格
      • mutations 响应规则
      • mutations 常量类型 名称使用常量
      • mutations 同步函数
    • actions
    • modules
      • 基本使用
      • 命名空间 namespaced
  • vuex使用
    • 分离模块文件配置
    • 访问仓库数据
      • 直接访问
      • 通过计算属性
      • vuex辅助函数
    • 修改仓库数据 mutation
    • actions 业务逻辑处理
  • store 变化逻辑
  • 在main.js 触发dispatch
  • store 目录结构

用处

vuex专门用于解决共享数据问题,是将数据提升到顶层,不过他使用了一些特别的技巧,不仅让组件的依赖更加清晰,当数据变动时,仅渲染依赖该数据的组件
注意:并非所有数据都需要用vuex管理,通常vuex只管理那些需要被组件共享的数据
在实际开发中,一些逻辑特别复杂的数据,尽管不共享,也可能提取到vuex中进行管理

解析

结构

import Vue from 'vue'
import VueX from 'vuex'Vue.use(VueX)const store = new VueX.Store({state:{  // 仓库  count:0// 访问 this.$store.state.count},mutations:{  // 状态更新 只能通过mutations的方法修改 仓库数据// 修改仓库内容  浏览器场景devtoos 可检测到修改信息 // 不能执行异操作 不然检测的修改记录不准确// 事件类型:回调函数// 修改仓库数据// state 仓库  payload 参数(负荷:携带着某某)setCount(state, payload){state.count = payload}// 通过mutations 更新普通提交风格// this.$store.commit('setCount',2) // payload => 2特殊提交风格// this.$store.commit({//     type:'setCount',//    count:2,//  age:18// }) // payload => {type:'setCount',count:2,age:18}},actions:{  // 执行异步操作的地方// 操作mutations方法// 当前store对象  context.commit-> this.$store.commitoperationCount(context, payload){context.commit('setCount',2)}// 调用 operationCount // this.$store.dispatch('operationCount')},getters:{ // 类似于计算属性// 访问   this.$store.getters.xxx// state 仓库 gettes 当前gettes对象 可用来访问其它gettes方法getFun(state, gettes){// gettes.xxx}// 传递参数 默认是不能传递参数的  可返回一个函数 调用该函数传参数getParams(state){return function(par){return par*state.count}}// 调用 $store.getters.getParams(99)},modules:{  // 多个仓库整合 仓库模块划分}
})
export default store

单一状态树 state

Vuex提出使用单一状态树
Single Source of Truth => 单一数据源
即全局只使用一个 store 对象

getters使用

仓库

const store = new VueX.Store({state:{  count:2},getters:{powCount(state){return state.count*state.count},isPow(state, gettes){return gettes.powCount > 10},// 给 getter 传参 返回一个函数 调用该函数传参数getParams(state){return function(par){return par*state.count}}// 简化getParams: state => par => par*state.count}
})

组件使用

<template><div>获取count的平方:{{computedCount}}获取count的平方:{{$store.getters.powCount}}count的平方是否大于10:{{$store.getters.is20}}指定一个数乘以count {{$store.getters.getParams(99)}}</div>
</template><script>
export default{computed:{computedCount(){ // 直接获取然后计算return this.$store.state.count * this.$store.state.count }}
}
</script>

mutations

mutations 提交风格

普通提交风格

// 触发
this.$store.commit('setCount',2) // 参数接收
mutations:{setCount(state, payload){//  payload => 2 }
}

特殊提交风格

// 触发
this.$store.commit({type:'setCount',count:2,age:18
}) // 参数接收
mutations:{setCount(state, payload){// payload => {type:'setCount',count:2,age:18}}
}
mutations 响应规则

Vuex中的store的state是响应式的,当state中的数据发生变化时,Vue组件会自动更新
这必须遵循一些Vuex对应的规则

  1. 提前在store中初始化好所需的属性(这些属性都会被加入响应式系统中,当属性发生变化时,会通知所有界面中用到该属性的地方,让界面发生刷新)
  2. 当给state中的对象添加新属性时,使用
    • 使用Vue.set(obj, 'newProp', 123)
    • 用新对象给旧对象赋值
  3. 当给state中的对象删除属性时
    • 使用Vue.delete(obj, 'prop')
state:{  obj:{name:"可响应的属性",}
},
mutations:{addNewProp(state){// 给state中的对象添加新属性// 直接添加是不可响应的state.obj['name2'] = '不可响应的属性'// 添加响应式属性 name3属性是可响应的Vue.set(state.obj, 'name3', '添加响应式属性')// 赋值一个新对象state.obj = {...state.obj, name3:'添加响应式属性'}// 删除属性 该方式删除不会响应delete state.obj.name// 删除响应式属性Vue.delete(state.obj, 'name')}
}
mutations 常量类型 名称使用常量

当项目增大时,Vuex管理的状态越来越多,需要更新的状态越来越多,那么意味着Mutations中的方法越来越多
方法过多,使用中需要花费大量的精力去记住这些方法,甚至是多个文件间来回切换,查看方法名称,甚至不是复制的时候,还会写错的情况。

mutations-types.js 保存方法名

export const INCREMENT = 'increment'
// 其它mutations类型
// ...

store.js

import Vue from 'vue'
import Vuex from 'vuex'
import {INCREMENT} from './mutations-types'Vue.use(Vuex)
export default new Vuex.Store({state:{},mutations:{[INCREMENT]:function(state, payload){// ...}}
})

使用

import {INCREMENT} from './store/mutations-types'
export default{methods:{setFun(){this.$store.commit(INCREMENT)}}
}
mutations 同步函数

通常情况下,Vuex要求muations中的方法必须是同步方法
主要原因是当我们使用devtools时,可以让devtools帮助捕捉mutations的提交信息
如果是异步操作,那么devtools将不能很好的追踪这个操作什么时候完成
如果有异步操作 使用actions的方法 来操作mutations

actions

action 类似于Mutation,但是用来代替Mutation来进行异步操作的

actions:{  // 执行异步操作的地方// 操作mutations方法// 当前store对象  context.commit-> this.$store.commitoperationCount(context, payload){context.commit('setCount',payload)}// 不能直接操作state// context.state.xxx = xxx// 调用 operationCount // this.$store.dispatch('operationCount', 2)
},

modules

Vue使用单一状态树,那么也就意味着有很多状态都会交给Vuex来管理
当应用变得非常复杂时,store对象就有可能变得非常臃肿,为了解决这个问题,Vuex允许将store分割成模块,而没个模块都有自己的 state mutations actions getters 等

基本使用

结构

modules:{a:{state:{},mutations:{},getters:{},actions:{},modules:{....}}
}
const moduleA = {state:{name:"moduleA"},mutations:{updataName(state, payload){console.log('moduleA -- mutations')}},getters:{// state 对应单前模块的getters// getters对应单前模块的getters// 在模块里面有第三个参数 rootState 获取根StaterepeatName(state, getters, rootState){return state.name.repeat(10)}},actions:{actRname(context, payload){// context.rootGetters// context.rootStateconsole.log(context)setTimeout(() => {// 只能提交该模块的mutations方法context.commit('upName',payload)}, 3000);}}
}
const moduleB = {state:{},mutations:{},getters:{},
}cons store = new Vuex({modules:{moduleA,moduleB}
})
// 相当于
//state:{//  moduleA:{...}
//}// 调用
this.$store.state.moduleA.name
this.$store.commit('updataName')
{{$store.getters.repeatName}}
this.$store.dispatch('actRname')
命名空间 namespaced
const moduleA = {namespaced: true,mutations:{setisLoading(state, payload){//...}}//...
}// 调用模块A下面的 mutations 的 setisLoading方法
this.$store.commit('moduleA/setisLoading',true)

vuex使用

安装

npm i vuex

main.js配置

import vuex from 'vuex'
Vue.use(vuex )
const store = new vuex.Store({// 配置// state:{} //仓库
})
new Vue({render:h=>h(App)router,store
}).$mount("#app")

或者

import {Store} from 'vuex'
new Store({})

分离模块文件配置

新建 store/index.js

import Vue from 'vue'
import vuex from 'vuex'
import user from './user' // 导入用户信息仓库Vue.use(vuex)
const store = new vuex.Store({// 配置modules:{// user(仓库名称):useruser, // 简写// ... 其他仓库}
})
export default store

新建 store/user.js

// 用户信息仓库
export default {state:{user:{data:{}, // 用户信息isLogin:false // 登录状态}}
}

main.js

import Vue from 'vue'
import App from './App.vue'
import store from './store'Vue.config.productionTip = falsenew Vue({render: h => h(App),store,
}).$mount('#app')

仓库结构

20200721205143871.png)

访问仓库数据

直接访问
this.$store.state.user.isLogin
通过计算属性
computed:{isLogin(){return this.$store.state.user.isLogin}
}
vuex辅助函数
import {mapState} from 'vuex'
computed:mapState('user',['data','isLogin'])this.isLogin // false

访问多个 访问会以前面的为准

computed:{...mapState('user',['data','isLogin']),...mapState('user2',{user2data:'data',user2isLogin:'isLogin'}),
}

修改仓库数据 mutation

数据的改动必须要提交commit 一个mutation
在vuex中,提交mutation是数据变化的唯一原因
在 mutation 中不能出现副作用(不能改动或使用外部的数据,ajax,其他异步行为…)会影响vue监听工具的使用

mutations:{setData(state,data){/// setTimeout}
}

配置

// user
export default {namespaced:true, // 开启命名空间state:{data:[],isLoading:false},mutations:{// 这里配置多种变异方式// state:原来的状态// payload:负荷 setisLoading(state,payload){state.isLoading = payload},setData(state,data){state.data = data}}
}

调用

// 开启命名空间的写法
this.$store.commit('user/setisLoading',true)
// 没有开启命名空间的写法
this.$store.commit('setisLoading',true)

actions 业务逻辑处理

export default {namespaced:true, // 开启命名空间state:{data:[],isLoading:false},mutations:{setisLoading(state,payload){state.isLoading = payload},setData(state,data){state.data = data}},actions:{// context 等同于 this.$store 只能传递一个参数payloadasync initData(context,params){// 由于是在当前命名空间 可不写 channels/context.commit('setisLoading',true);let dat = await getNewsChanges() //接口获取数据context.commit('setData',dat.data);context.commit('setisLoading',false);}}
}

调用 dispatch 触发action

this.$store.dispatch('channels/initData',1)

store 变化逻辑

直接通过mutation 改动仓库数据

通过action 改动仓库数据

在main.js 触发dispatch

// 初始化数据
store.dispatch('user/initData')

store 目录结构


actions.js

export default {asyncCount(context, payload){setTimeout(()=>{context.commit('addCount',payload)})}
}

getters.js

export default {count(state){return state.count > 10}
}

mutations.js

export default {addCount(state, payload){state.count = payload}
}

index.js

import Vue from 'vue'
import Vuex from 'vuex'
import mutations from './mutations'
import actionsfrom from  './actions'
import getters from  './getters'
import moduleA from  './modules/moduleA'const state = {count:0
}Vue.use(Vuex)export default new Vuex.Store({state,mutations,actions,getters,modules:{moduleA}
})

modules/moduleA.js

export default {namespaced:true, // 开启命名空间state:{},mutations:{},actions:{},getters:{}
}

vuex 配置使用解析 mutations响应式规则 Vue.delete/set 目录划分相关推荐

  1. 使用Vue+Vuex+CSS3完成管理端响应式架构模板实战

    前言 上节回顾 上一节我们通过引入md5,对密码进行了不可逆加密:然后对用户名和密码进行了数据整理,发送axios请求,同时引入了Vuex前端本地化数据管理,将用户名和token进行存储.还不明白上下 ...

  2. response获取响应内容_Project Reactor 深度解析 - 1. 响应式编程介绍,实现以及现有问题

    现在, Java 的各种基于 Reactor 模型的响应式编程库或者框架越来越多了,像是 RxJava,Project Reactor,Vert.x 等等等等.在 Java 9, Java 也引入了自 ...

  3. Vue响应式原理 vue源码(十一)

    前言 看过很多讲响应式的文章,大多都是告诉你们,有Observer,Dep,Wathcer类,Object.definePorperty,先会触发get中的dep.depend收集依赖,然后数据改变时 ...

  4. Vue响应式原理Vue中数据的监听

    文章目录 Observer理解如上图 Dep「依赖管理」 Watcher理解如上图 总结:Vue响应式原理的核心就是Observer.Dep.Watcher. Vue响应式原理理解以后就知道Vue是怎 ...

  5. 利用JS响应式修改vue实现页面的input赋值

    背景 公司有一个基于Vue实现的登录,页面上是一个常规的登录界面,用户名输入框.密码输入框和登录按钮各一个. 需求:拉起登录页面时,自动将用户帐号和密码填入,然后自动点击登录. 尝试 我们把登录页面简 ...

  6. 浅谈vue 之双向绑定和响应式(vue的响应式)

    初识vue小伙伴通常都会被他的双向绑定所感叹,神奇?方便?而且在不少的面试中也会被面试官问到,上来就是:请问vue双向绑定的原来是什么?我们就来研究研究这是个什么东西: v-model 官方其实已经说 ...

  7. 【Vue.js源码解析 一】-- 响应式原理

    前言 笔记来源:拉勾教育 大前端高薪训练营 阅读建议:建议通过左侧导航栏进行阅读 课程目标 Vue.js 的静态成员和实例成员初始化过程 首次渲染的过程 数据响应式原理 – 最核心的特性之一 准备工作 ...

  8. Vue3的响应式原理解析

    Vue3的响应式原理解析 Vue2响应式原理回顾 // 1.对象响应化:遍历每个key,定义getter.setter // 2.数组响应化:覆盖数组原型方法,额外增加通知逻辑 const origi ...

  9. vue2的动画,混入Mixin,插件,指令,渲染函数,响应式,MVVM

    文章目录 过渡 & 动画 Transition 组件 基于 CSS 的过渡效果 CSS 过渡类名 class 为过渡效果命名 CSS 过渡 transition 实例1: 实例2: CSS 动 ...

最新文章

  1. Firefox 65.0.2 发布,Firefox 66 预计3月19日推出
  2. Ubuntu增加(swap)交换分区
  3. ThreadLocal 和 InheritableThreadLocal
  4. mysql高级笔记_MySQL高级部分笔记
  5. django+asyncio资料调研整合
  6. 使用的 SQL Server 版本不支持数据类型“datetime2”的错误解决方法
  7. 禁用UITabBarController双击事件
  8. 新iPhone将采用更大容量电池:最低3110mAh?
  9. 庖丁解牛!深入剖析React Native下一代架构重构
  10. python数据分析之(3)pandas
  11. 天翼网关未欠费有信号且不能上网解决办法
  12. 瑞吉外卖-全网最全笔记-Day06
  13. OpenCV开发笔记(六十二):红胖子8分钟带你深入了解亚像素角点检测(图文并茂+浅显易懂+程序源码)
  14. 电子元器件封装设计规范
  15. css 设置背景图一半_css怎么背景图片显示不全?
  16. 浙江大学PAT-1003. 我要通过!(20)
  17. mmap()、munmap()的用法、例子
  18. 浙江最好的计算机学校,浙江2021年什么计算机学校最好
  19. iOS逆向 - 环境搭建
  20. 无法连接到 LAPTOP-O283RBCD。,在与 SQL Server 建立连接时出现与网络相关的或特定于实例的错误。(已解决)

热门文章

  1. LinuxProbe 0x17 DHCP动态管理主机地址、电子邮件系统
  2. 我使用的深圳电信ADSL的宽带又要到期了
  3. Token验证—JWT方法
  4. JavaScript 生成随机数
  5. 免费资源_第三篇 竞赛(1)_Kaggle
  6. scss中的@each 指令
  7. spring cloud学习,转载自纯洁的微笑
  8. yum卸载软件 不卸载依赖_如何使用Yum Remove卸载,删除软件包
  9. 【MySQL · Innodb架构简析】三、Innodb Indexes
  10. Asp.net使用oledb方式连接SQL server