vue_使用vuex
vuex其实就是一个观察者模式
- 可以在Vue实例绑定一个全局的属性,this.$myStore 来创建一个仓库存储数据,只是不是响应式的
- this.$root 可以访问Vue根实例,和上一点差不多,绑定一个全局仓库
- 使用Vue的bus总线机制,原理就是在Vue原型上创建一个vue实例,Vue.prototype.$bus = new Vue(),练习小demo可以使用
vuex 使用
Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式,采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化。
Vuex 可以帮助我们管理共享状态,并附带了更多的概念和框架。这需要对短期和长期效益进行权衡。如果项目很小,可以不使用vuex
每一个Vuex应用的核心就是store(仓库), “store”基本上就是一个容器,它包含着你的应用中大部分的状态(state)。
这个状态自管理应用包含以下几个部分:
- state,驱动应用的数据源;
- view,以声明方式将 state 映射到视图;
- actions,响应在 view 上的用户输入导致的状态变化。
Vuex和单纯的全局对象有以下两点不同:
- Vuex 的状态存储是响应式的。当 Vue 组件从 store 中读取状态的时候,若 store 中的状态发生变化,那么相应的组件也会相应地得到高效更新。
- 不能直接改变 store 中的状态。改变 store 中的状态的唯一途径就是显式地提交 (commit) mutation。
Vuex安装
$ npm install vuex --save
Vuex配置
在一个模块化的打包系统中,您必须显式地通过 Vue.use() 来安装 Vuex:
// 创建一个仓库 src/store/index.js
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
export default new Vuex.Stroe({
state: {
count:'',
....
},
actions: {
....
},
mutations: {
...
}
})
通过在根实例中注册 store 选项,该 store 实例会注入到根组件下的所有子组件中,且子组件能通过 this.$store 访问到
// main.js
import store from './store'
new Vue({
el: '#app',
router,
store,
components: { App },
template: '<App/>'
})
vuex state
通过在根实例中注册store选项后,子组件可以通过this.$store.state.count访问到该状态
当一个组件需要获取多个状态时候,将这些状态都声明为计算属性会有些重复和冗余。
// 为了解决这个问题,我们可以使用 mapState 辅助函数帮助我们生成计算属性,
import { mapState } from 'vuex'
// 解构赋值,相当于mapState = vuex.mapState
// 注意: mapState名字不能随便取,因为随便取的话,vuex对象下没有这个方法
export default {
computed: {
otherComputed () {/* do something... */ },
// 将this.count 映射为 this.$store.state.count
// 将this.city 映射为 this.$store.state.city
...mapState(['count'], ['city']),
// 也可以接收一个对象,
// 将this.currentCount 映射为 this.$store.state.count
// 将this.currentCity 映射为 this.$store.state.city
...mapState({currentCount: 'count', currentCity: 'city'}),
}
}
vuex Mutations
// 更改 Vuex 的 store 中的状态(state)的唯一方法是提交 mutation。
Vuex 中的 mutation 非常类似于事件:每个 mutation 都有一个字符串的 事件类型 (type) 和 一个 回调函数 (handler)。
这个回调函数就是我们实际进行状态更改的地方,并且它会接受 state 作为第一个参数
// store/index.js
export default new Vuex.Stroe({
state: {
count: 0,
},
actions: {
},
mutations: {
increment (state, value) {
state.count = value
},
decrement (state, obj) {
state.count = obj.count--
}
}
})
// 在组件中提交Mutations
- 可以使用this.$store.commit('increment', 10)方法,第二个参数作为要改变的值,也可以是一个对象
- 对象风格的提交方式, this.$store.commit({type: 'decrement', count: 10})
type属性指定调用mutations对象的方法, 其他属性作为该方法的第二参数的属性
// 使用mapMutations辅助函数提交Mutations
import { mapMutations, mapState } from 'vuex' // 也可以同时引用
export default {,
name: '',
data () {/* do something.... */},
computed: {...mapState(['count'])},
methods: {
otherMethods () {/* do something.... */},
handleIncrementClick () {
this.increment(this.count)
this.incr(this.count)
},
handleDecrementClick () {
this.decrement(this.count)
this.decr(this.count)
},
// 将this.increment()映射为 this.$store.commit('increment')
// 将this.decrement()映射为 this.$store.commit('decrement')
...mapMutations(['increment', 'decrement']),
// 对象提交方式
// 将this.incr()映射为 this.$store.commit('increment')
// 将this.decr()映射为 this.$store.commit('decrement')
...mapMutations({incr: 'increment', decr: 'decrement'})
}
}
// Vuex 的 store 中的状态是响应式的,当我们变更状态时,监视状态的 Vue 组件也会自动更新。
// Mutation 必须是同步函数,一条重要的原则就是要记住 mutation 必须是同步函数
vuex actions
在 mutation 中混合异步调用会导致你的程序很难调试。例如,当你调用了两个包含异步回调的 mutation 来改变状态,你怎么知道什么时候回调和哪个先回调呢?这就是为什么我们要区分这两个概念。
Action 类似于 mutation,不同在于:
- Action 提交的是 mutation,而不是直接变更状态。
- Action 可以包含任意异步操作
Action 函数接受一个与 store 实例具有相同方法和属性的 context 对象,
因此你可以调用 context.commit 提交一个 mutation,或者通过 context.state 和 context.getters 来获取 state 和 getters。
// store/index.js
export default new Vuex.Stroe({
state: {
count: 0,
},
actions: {
increment (context) {
context.commit('increment', context.count)
},
// 异步操作
decrementAsync ({ commit }, obj) {
setTimeout(() => {
// 结构赋值, 这里的 commit === commit.commit
// 这里commit保存的是context上下文对象,而他有一个方法叫commit,es6语法键值对都名字一样可以简写
commit('decrement', obj)
}, 1000);
}
},
mutations: {
increment (state, value) {
state.count = value
},
decrement (state, obj) {
state.count = obj.count--
}
}
})
// 在组件中分发action
- 可以使用this.$store.dispatch('increment')
- 或者this.$store.dispatch('decrementAsync', {count: 10}) // 传参对象提交
// 使用mapActions辅助函数
import { mapActions } from 'vuex'
export default {
//....
methods: {
otherMethods () {/* do something... */},
handleIncrementClick () {
this.increment()
this.incr()
},
handleDecrementAsyncClick () {
this.decrementAsync({count: 10})
this.decr({count: 10})
},
// 将 this.increment() 映射为 this.$store.dispatch('increment')
// 将 this.decrementAsync() 映射为 this.$store.dispatch('decrementAsync')
...mapActions(['increment', 'decrementAsync']),
// 对象提交方式
// 将 this.incr() 映射为 this.$store.dispatch('increment')
// 将 this.decr() 映射为 this.$store.dispatch('decrementAsync')
...mapActions({incr: 'increment', decr: 'decrementAsync'})
}
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列:基于图像分类模型对图像进行分类
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 25岁的心里话
· 闲置电脑爆改个人服务器(超详细) #公网映射 #Vmware虚拟网络编辑器
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· 零经验选手,Compose 一天开发一款小游戏!
· 一起来玩mcp_server_sqlite,让AI帮你做增删改查!!