vuex是什么
vuex全局的状态管理,挂载到根实例的vue 的状态管理器,依赖vue ,不可以单独使用
【注意】:Vuex 依赖 Promise (opens new window)。如果你支持的浏览器并没有实现 Promise (比如 IE),那么你可以使用一个 polyfill 的库,例如 es6-promise
npm install es6-promise --save # npm yarn add es6-promise # Yarn
安装vuex
- yarn add vuex - npm i vuex
什么情况下使用vuex
解决跨层级组件通信
vuex5个核心 外加plugins
## state
存储全局状态的,数据也是双向绑定的
等价于组件里的data
## getters
用于对state进行计算,返回一个新值,等价于组件中的computed
好像是四个参数 求答案 ??
常用的第一个参数(state)
## mutations
唯一用于修改state的方法,且只能执行同步代码。使用commit方法调用 ,自动被注入state参数
两个参数(state,commit传来的值)
## actions
用于执行异步操作的方法,只能通过调用mutations来修改state。使用dispatch调用,自动注入context对象参数
两个参数(content,dispatch传来的值)
## modules
模块化开发,当多人开发项目时modules就显得及为重要
默认情况下,只有 state 用有作用域对象,其他部分自动提升到根模块上。所以为了避免发生命名冲突,要使用命名空间
在独立的模块化中使用namespaced设置为true,在该模块中除了state之外,其他的部分名字前自动拼接上模块名称
## plugins
额外的vuex插件,用于增强扩展vuex没有的功能
比如vuex 本地数据持久化 vuex -persist
安装 npm i vuex-vuex-persist as yarn add vuex-vuex-persist
例子按回车时存入一条数据(基础做法)
<template> <div> <h1>按回车时存入一条数据</h1> <input @keyup.13="addlist" type="text" v-model="text" /> <ul> <li>当前共{{ $store.getters.len }}条数据</li> <li v-for="v in $store.state.list" :key="v">{{ v }}</li> </ul> </div> </template> <script> import store from './store' export default { store, data() { return { text: '', } }, methods: { addlist() { // 通过dispatch调用actions里的setList函数,参数是this.text,因为actions用了promise封装所以这里可以用then调用返回结果 this.$store.dispatch('setList', this.text).then((res) => { if (res) { alert('数据添加成功') } }) }, }, } </script>
//store.js文件 import Vue from 'vue' import Vuex from 'vuex' Vue.use(Vuex) const store = new Vuex.Store({ state: { list: [] }, getters: { len(state) { return state.list.length } }, mutations: { setList(stata, data) { stata.list.push(data) } }, actions: { setList({ commit }, data) { return new Promise((resolve, reject) => { // 模拟异步操作 setTimeout(() => { commit('setList', data) resolve(true) }, 500) }) } }, modules: {} }) export default store
例子按回车时存入一条数据(辅助函数)
mapState,mapGetters是在computed中解构的
mapMutations,mapActions是在methods中解构的
<template> <div> <h1>按回车时存入一条数据</h1> <input @keyup.13="addlist" type="text" v-model="text" /> <ul> <li>当前共{{ length }}条数据</li> <li v-for="v in list" :key="v">{{ v }}</li> </ul> </div> </template> <script> import store from './store' //vuex中引入辅助函数 import { mapState, mapGetters, mapMutations, mapActions } from 'vuex' export default { store, data() { return { text: '', } }, computed: { // 可以用数组结构和对象结构两种方式,数据复杂有可能重复就用对象形式 ...mapState(['list']), ...mapGetters({ length: 'len' }), }, methods: { ...mapActions(['setList']), addlist() { // 通过dispatch调用actions里的setList函数,参数是this.text,因为actions用了promise封装所以这里可以用then调用返回结果 this.setList(this.text).then((res) => { if (res) { alert('数据添加成功') } }) }, }, } </script>
import Vue from 'vue' import Vuex from 'vuex' Vue.use(Vuex) const store = new Vuex.Store({ state: { list: [] }, getters: { len(state) { return state.list.length } }, mutations: { setList(stata, data) { stata.list.push(data) } }, actions: { setList({ commit }, data) { return new Promise((resolve, reject) => { // 模拟异步操作 setTimeout(() => { commit('setList', data) resolve(true) }, 500) }) } }, modules: {} }) export default store
vuex模块化开发
辅助函数的应用(最方便的应用方式)
第一种
createNamespacedHelpers
创建命名空间的助手函数,方便让当前组件的所有store里的独立资源都是来自于同一个模块中的
//两个js文件与第二种方法一致 <template> <div> <h1>按回车时存入一条数据</h1> <input @keyup.13="addlist" type="text" v-model="text" /> <ul> <li>当前共{{ len }}条数据</li> <li v-for="v in list" :key="v">{{ v }}</li> </ul> </div> </template> <script> import store from './store' //es6语法as 给createNamespacedHelpers命名为helper import { createNamespacedHelpers as helper } from 'vuex' //helper会默认给每个函数都加上路径参数 'a/' const { mapState, mapMutations, mapGetters, mapActions } = helper('a/') export default { store, data() { return { text: '', } }, computed: { // 可以用数组结构和对象结构两种方式,数据复杂有可能重复就用对象形式 ...mapState(['list']), ...mapGetters({ len: 'len' }), }, methods: { ...mapActions(['setList']), addlist() { // 通过dispatch调用actions里的setList函数,参数是this.text,因为actions用了promise封装所以这里可以用then调用返回结果 this.setList(this.text).then((res) => { if (res) { alert('数据添加成功') console.log(this) } }) }, }, mounted() {}, } </script>
第二种
<template> <div> <h1>按回车时存入一条数据</h1> <input @keyup.13="addlist" type="text" v-model="text" /> <ul> <li>当前共{{ len }}条数据</li> <li v-for="v in list" :key="v">{{ v }}</li> </ul> </div> </template> <script> import store from './store' import { mapState, mapGetters, mapMutations, mapActions } from 'vuex' export default { store, data() { return { text: '', } }, computed: { // 可以用数组结构和对象结构两种方式,数据复杂有可能重复就用对象形式 ...mapState('a/', ['list']), ...mapGetters('a/', { len: 'len' }), }, methods: { ...mapActions('a/', ['setList']), addlist() { // 通过dispatch调用actions里的setList函数,参数是this.text,因为actions用了promise封装所以这里可以用then调用返回结果 this.setList(this.text).then((res) => { if (res) { alert('数据添加成功') console.log(this) } }) }, }, mounted() {}, } </script>
//store.js 文件 import Vue from 'vue' import Vuex from 'vuex' import a from './a' Vue.use(Vuex) const store = new Vuex.Store({ modules: { a } }) export default store //a.js文件 export default { namespaced: true, state: { list: [] }, getters: { len(state) { return state.list.length } }, mutations: { setList(stata, data) { stata.list.push(data) } }, actions: { setList({ commit }, data) { return new Promise((resolve, reject) => { // 模拟异步操作 setTimeout(() => { commit('setList', data) resolve(true) }, 500) }) } }, }
plugins插件使用
<template> <div> <!-- vuex插件:plugins 本地数据持久化 --> {{ count }} <button @click="setCount(count - 100)">递减</button> </div> </template> <script> import store from '../store' import { mapState, mapMutations } from 'vuex' export default { store, data() { return {} }, computed: { ...mapState(['count']), }, methods: { ...mapMutations(['setCount']), }, } </script>
import Vue from 'vue' import Vuex from 'vuex' import VuexPersist from 'vuex-persist' Vue.use(Vuex) // 初始化本地存储 const Persist = new VuexPersist({ // 指定数据存到哪里 storage: window.sessionStorage }) const store = new Vuex.Store({ // 安装插件 plugins: [Persist.plugin], state: { count: 10000 }, mutations: { setCount(state, v) { state.count = v } } }) export default store