建设企业网站的时间,局网站建设意见,做淘宝客网站违法吗,在什么网站可以做外贸出口劳保鞋文章目录 一、介绍1、概念 2、工作示意图3、安装4、简单示例 二、核心1、State1.1 组件中获取 Vuex 的状态1.2 mapState 辅助函数1.3 对象展开运算符 2、Getter2.1 基本使用2.2 通过属性访问2.3 通过方法访问2.4 mapGetters 辅助函数 3、Mutation3.1 定义 mutation3.2 commit 提… 文章目录 一、介绍1、概念 2、工作示意图3、安装4、简单示例 二、核心1、State1.1 组件中获取 Vuex 的状态1.2 mapState 辅助函数1.3 对象展开运算符 2、Getter2.1 基本使用2.2 通过属性访问2.3 通过方法访问2.4 mapGetters 辅助函数 3、Mutation3.1 定义 mutation3.2 commit 提交 mutation3.3 Mutation 必须是同步函数3.4 mapMutations 辅助函数 4、Actions4.1 Action 函数4.2 dispatch 触发 Action4.3 action 内部执行异步操作4.4 mapActions 辅助函数4.5 组合 Action 三、Modules1、基本使用2、命名空间 一、介绍
1、概念
Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式适用于中大型单页应用每一个 Vuex 应用的核心就是 store仓库。“store”基本上就是一个容器它包含着你的应用中大部分的状态 (state)。Vuex 和单纯的全局对象有以下两点不同 1Vuex 的状态存储是响应式的。当 Vue 组件从 store 中读取状态的时候若 store 中的状态发生变化那么相应的组件也会相应地得到高效更新。 2你不能直接改变 store 中的状态。改变 store 中的状态的唯一途径就是显式地提交 (commit) mutation。这样使得我们可以方便地跟踪每一个状态的变化从而让我们能够实现一些工具帮助我们更好地了解我们的应用。 注意 Vue 2 匹配的 Vuex 3 的文档文档链接 Vue 3 匹配是 Vuex 4 的文档文档链接
2、工作示意图 3、安装
1NPM 这里是 vue2:
npm install vuex3.0.0 --savevue3的话:
npm install vuex --save2Yarn
yarn add vuex3CND 指定版本比如 vue2:
https://unpkg.com/vuex3.0.04、简单示例
store/index.js
import Vue from vue
import Vuex from vuexVue.use(Vuex)const store new Vuex.Store({state: {count: 1},mutations: {increment(state, value) {state.count value}}
})
export default store;在 Vue 的实例中注入 Vuex以便组件中通过 this.$store 访问 main.js
import Vue from vue
import App from ./App.vue
import store from ./storenew Vue({store,render: h h(App),
}).$mount(#app)组件中使用
templatediv classhellodivh3组件中使用 store/h3当前count{{ $store.state.count }}/divdivbutton v-on:clickclickCount(0)减1/buttonbutton v-on:clickclickCount(1)加1/button/div/div
/templatescript
export default {name: CountView,methods: {clickCount(val) {// 提交一个变更this.$store.commit(increment, val 0 ? -1 : 1);},},
};
/script二、核心
1、State
1.1 组件中获取 Vuex 的状态
1在计算属性中返回某个状态
// 创建一个 Counter 组件
const Counter {template: div{{ count }}/div,computed: {count () {return store.state.count}}
}问题在每个需要使用 state 的组件中需要频繁地导入
2在根实例中注册 store 选项该 store 实例会注入到根组件下的所有子组件中
const app new Vue({el: #app,store, // 把 store 对象提供给 “store” 选项这可以把 store 的实例注入所有的子组件components: { Counter },template: div classappcounter/counter/div
})子组件能通过 this.$store 访问
const Counter {template: div{{ count }}/div,computed: {count () {return this.$store.state.count}}
}1.2 mapState 辅助函数
用于组件需要获取多个状态的时候 示例
templatediv classhellodivh3组件中使用 store/h3当前count{{ $store.state.count }}/divdivh3组件中使用 mapState/h3div当前count{{ count }}/divdiv当前countAlias{{ countAlias }}/divdiv当前countPlusLocalState{{ countPlusLocalState }}/div/divdivbutton v-on:clickclickCount(0)减1/buttonbutton v-on:clickclickCount(1)加1/button/div/div
/templatescript
import { mapState } from vuex;export default {name: CountView,methods: {clickCount(val) {this.$store.commit(increment, val 0 ? -1 : 1);},},data: () ({localCount: 3,}),computed: {...mapState({// 箭头函数可使代码更简练count: (state) state.count,// 传字符串参数 count 等同于 state state.countcountAlias: count,// 使用常规函数count data中的localCountcountPlusLocalState(state) {return state.count this.localCount;},}),},
};
/script也可以给 mapState 传一个字符串数组
computed: mapState([// 映射 this.count 为 store.state.countcount
])1.3 对象展开运算符
mapState 函数返回的是一个对象可以将它与局部计算属性混合使用
computed: {localComputed () { /* ... */ },// 使用对象展开运算符将此对象混入到外部对象中...mapState({// ...})
}2、Getter
2.1 基本使用 就像计算属性一样getter 的返回值会根据它的依赖被缓存起来且只有当它的依赖值发生了改变才会被重新计算。 Getter 接受 2 个参数 state 作为其第一个参数getter 作为第二个参数 示例
const store new Vuex.Store({state: {todos: [{ id: 1, text: ..., done: true },{ id: 2, text: ..., done: false }]},getters: {doneTodos: (state, getters) {return state.todos.filter(todo todo.done)}}
})2.2 通过属性访问
Getter 会暴露为 store.getters 对象可以以属性的形式访问这些值
store.getters.doneTodos // - [{ id: 1, text: ..., done: true }]2.3 通过方法访问
也可以通过让 getter 返回一个函数来实现给 getter 传参 示例
getters: {// ...getTodoById: (state) (id) {return state.todos.find(todo todo.id id)}
}使用时
store.getters.getTodoById(2) // - { id: 2, text: ..., done: false }2.4 mapGetters 辅助函数
mapGetters 辅助函数仅仅是将 store 中的 getter 映射到局部计算属性:
import { mapGetters } from vuexexport default {// ...computed: {// 使用对象展开运算符将 getter 混入 computed 对象中...mapGetters([doneTodosCount,anotherGetter,// ...])}
}如果你想将一个 getter 属性另取一个名字使用对象形式
...mapGetters({// 把 this.doneCount 映射为 this.$store.getters.doneTodosCountdoneCount: doneTodosCount
})3、Mutation
3.1 定义 mutation
更改状态的唯一方法是提交 mutation mutations 中回调函数参数 1state 为第一个参数 2payload载荷为第二个参数(可以为基本数据类型也可以为对象)
示例
const store new Vuex.Store({state: {count: 1},mutations: {increment(state, payload) {state.count payload}}
})3.2 commit 提交 mutation
调用 store.commit 方法
store.commit(increment, 2)3.3 Mutation 必须是同步函数
一条重要的原则就是要记住 mutation 必须是同步函数 如下例子
mutations: {someMutation (state) {api.callAsyncMethod(() {state.count})}
}原因是当 mutation 触发的时候回调函数还没有被调用devtools 不知道什么时候回调函数实际上被调用这样状态的变化就变得不可追踪 解决方法使用 Actions
3.4 mapMutations 辅助函数
使用 mapMutations 辅助函数将组件中的 methods 映射为 store.commit 调用:需要先在根节点注入 store
import { mapMutations } from vuexexport default {// ...methods: {...mapMutations([increment, // 将 this.increment() 映射为 this.$store.commit(increment)// mapMutations 也支持载荷incrementBy // 将 this.incrementBy(amount) 映射为 this.$store.commit(incrementBy, amount)]),...mapMutations({add: increment // 将 this.add() 映射为 this.$store.commit(increment)})}
}4、Actions
Action 类似于 mutation不同在于 1Action 提交的是 mutation而不是直接变更状态。 2Action 可以包含任意异步操作。
4.1 Action 函数
Action 函数参数 1context 对象与 store 实例具有相同方法和属性因此你可以调用 context.commit 提交一个 mutation 2payload 载荷可以基本数据也可以对象
示例 定义 action
const store new Vuex.Store({state: {count: 0},mutations: {increment(state, payload) {state.count payload;}},actions: {increment(context, payload) {context.commit(increment, payload)}}
})export default store;4.2 dispatch 触发 Action
Action 通过 store.dispatch 方法触发
store.dispatch(increment, 3)4.3 action 内部执行异步操作
actions: {incrementAsync ({ commit }) {setTimeout(() {commit(increment)}, 1000)}
}购物车示例涉及到调用异步 API 和分发多重 mutation
actions: {checkout ({ commit, state }, products) {// 把当前购物车的物品备份起来const savedCartItems [...state.cart.added]// 发出结账请求然后乐观地清空购物车commit(types.CHECKOUT_REQUEST)// 购物 API 接受一个成功回调和一个失败回调shop.buyProducts(products,// 成功操作() commit(types.CHECKOUT_SUCCESS),// 失败操作() commit(types.CHECKOUT_FAILURE, savedCartItems))}
}4.4 mapActions 辅助函数
使用 mapActions 辅助函数将组件的 methods 映射为 store.dispatch 调用需要先在根节点注入 store
import { mapActions } from vuexexport default {// ...methods: {...mapActions([increment, // 将 this.increment() 映射为 this.$store.dispatch(increment)// mapActions 也支持载荷incrementBy // 将 this.incrementBy(amount) 映射为 this.$store.dispatch(incrementBy, amount)]),...mapActions({add: increment // 将 this.add() 映射为 this.$store.dispatch(increment)})}
}4.5 组合 Action
Action 通常是异步的那么如何知道 action 什么时候结束呢更重要的是我们如何才能组合多个 action以处理更加复杂的异步流程 首先你需要明白 store.dispatch 可以处理被触发的 action 的处理函数返回的 Promise并且 store.dispatch 仍旧返回 Promise
actions: {actionA ({ commit }) {return new Promise((resolve, reject) {setTimeout(() {commit(someMutation)resolve()}, 1000)})}
}现在可以
store.dispatch(actionA).then(() {// ...
})在另外一个 action 中也可以
actions: {// ...actionB ({ dispatch, commit }) {return dispatch(actionA).then(() {commit(someOtherMutation)})}
}最后如果我们利用 async / await (opens new window)我们可以如下组合 action
// 假设 getData() 和 getOtherData() 返回的是 Promiseactions: {async actionA ({ commit }) {commit(gotData, await getData())},async actionB ({ dispatch, commit }) {await dispatch(actionA) // 等待 actionA 完成commit(gotOtherData, await getOtherData())}
}三、Modules
1、基本使用
Vuex 允许我们将 store 分割成模块module 每个模块拥有自己的 state、mutation、action、getter
示例 store/modules/moduleA.js
const moduleA {state: {countA: 1},getters: {},mutations: {},actions: {}
}export default moduleA;store/modules/moduleB.js
const moduleB {state: {countB: 2},getters: {sumWithRootCount(state, getters, rootState) {// 这里的 state 和 getters 对象是模块的局部状态rootState 为根节点状态console.log(B-state, state)console.log(B-getters, getters)console.log(B-rootState, rootState)return state.countB rootState.count}},mutations: {increment(state, payload) {// 这里的 state 对象是模块的局部状态state.countB payload;}},actions: {incrementIfOddOnRootSum({ state, commit, rootState }, payload) {console.log(payload)// 这里的 state 对象是模块的局部状态rootState 为根节点状态console.log(state)commit(increment, rootState.count payload)}}
}export default moduleB;src/store/index.js
import Vue from vue
import Vuex from vuex
import moduleA from ./modules/moduleA
import moduleB from ./modules/moduleBVue.use(Vuex)const store new Vuex.Store({state: {count: 5},modules: {moduleA: moduleA,moduleB: moduleB,}
})export default store;组件中使用 count.vue
templatediv classhellodivh3组件中使用 store/h3divmoduleA中的countA {{ countA }}/divdivmoduleB中的countB {{ countB }}/div/divdivbutton v-on:clickclickCommit(1)commit 加1/buttonbutton v-on:clickclickDispatch(1)dispatch 加1/button/div/div
/templatescriptexport default {name: CountView,methods: {clickCommit(val) {this.$store.commit(increment, val);},clickDispatch(val) {this.$store.dispatch(incrementIfOddOnRootSum, val);},},computed: {countA() {// moduleA 中的 countAreturn this.$store.state.moduleA.countA;},countB() {// moduleB 中的 countBreturn this.$store.state.moduleB.countB;},},
};
/script2、命名空间
默认情况下模块内部的 action、mutation 和 getter 是注册在全局命名空间的——这样使得多个模块能够对同一 mutation 或 action 作出响应 可以通过添加 namespaced: true 的方式使其成为带命名空间的模块。 当模块被注册后它的所有 getter、action 及 mutation 都会自动根据模块注册的路径调整命名。 示例 store/modules/moduleA.js
const moduleA {namespaced: true, // 设为命名空间state: {countA: 1},getters: {},mutations: {},actions: {}
}export default moduleA;store/modules/moduleB.js
const moduleB {namespaced: true, // 设为命名空间state: {countB: 2},getters: {sumWithRootCount(state, getters, rootState) {// 这里的 state 和 getters 对象是模块的局部状态rootState 为根节点状态console.log(B-state, state)console.log(B-getters, getters)console.log(B-rootState, rootState)return state.countB rootState.count}},mutations: {increment(state, payload) {// 这里的 state 对象是模块的局部状态state.countB payload;}},actions: {incrementIfOddOnRootSum({ state, commit, rootState }, payload) {console.log(payload)// 这里的 state 对象是模块的局部状态rootState 为根节点状态console.log(state)commit(increment, rootState.count payload)}}
}export default moduleB;src/store/index.js
import Vue from vue
import Vuex from vuex
import moduleA from ./modules/moduleA
import moduleB from ./modules/moduleBVue.use(Vuex)const store new Vuex.Store({state: {count: 5},modules: {moduleA: moduleA,moduleB: moduleB,}
})export default store;组件中使用 count.vue
templatediv classhellodivh3组件中使用 store/h3divmoduleA中的countA {{ countA }}/divdivmoduleB中的countB {{ countB }}/div/divdivbutton v-on:clickincrement(1)commit 加1/buttonbutton v-on:clickincrementIfOddOnRootSum(1)dispatch 加1/button/div/div
/templatescript
import { mapActions, mapMutations, mapState } from vuex;export default {name: CountView,methods: {// 将模块的空间名称字符串作为第一个参数传递给 mapMutations...mapMutations(moduleB, [increment]),// 将模块的空间名称字符串作为第一个参数传递给 mapActions...mapActions(moduleB, [incrementIfOddOnRootSum]),},computed: {// 将模块的空间名称字符串作为第一个参数传递给 mapState...mapState(moduleA, {countA: (state) state.countA,}),...mapState(moduleB, {countB: (state) state.countB,}),},
};
/script