Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式。它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化。
这个状态自管理应用包含以下几个部分:
- state,驱动应用的数据源;
- view,以声明方式将 state 映射到视图;
- actions,响应在 view 上的用户输入导致的状态变化。
在全局单例模式管理下,我们的组件树构成了一个巨大的视图;不管在树的哪个位置,任何组件都能获取状态或者触发行动。
通过定义和隔离状态管理中的各种概念并通过强制规则维持视图和状态间的独立性,我们的代码将会变得更结构化且易维护。
在使用vuex的时候,首先要在项目目录下 npm install vuex --save(下载vuex,并在package.json上有显示)
然后与components同一级目录下创建一个store的文件夹;文件夹下面是store.js;
然后在store.js文件中;首先导入vue和vuex;
还有vuecookies 就是把数据放入客户端的cookies中,从而使数据变得可持久化;
Vuex 通过 store
选项,提供了一种机制将状态从根组件“注入”到每一个子组件中(需调用 Vue.use(Vuex)
):
import vuex from 'vuex' import Vue from 'vue' import vuecookies from 'vue-cookies' Vue.use(vuex); Vue.use(vuecookies); export default new vuex.Store({ state: { username: vuecookies.get('username'), token: vuecookies.get('token'), //存放的数据可以供全局使用; apilist: { login: 'http://127.0.0.1:5000/login', register: 'http://127.0.0.1:5000/register' }, house_data:vuecookies.get('house_data'), city:vuecookies.get('city') }, mutations: { //这里存的数据是暂时的,一刷新后就消失了,因此必须把数据保存到cookies里面去。 changeuser(state, data) { //页面不刷新 state.username = data.username; state.token = data.token; //当刷新页面的时候就到cookies中取值 vuecookies.set('username', data.username, '20min'); vuecookies.set('token', data.token, '20min') }, deleteUser(state) { //删除的话也要删除cookies里面 state.username = ''; state.token = ''; vuecookies.remove("username"); vuecookies.remove("token") }, putdata(state,data) { //把后端传入过来的数据放入到cookies中 state.house_data = data; vuecookies.set('house_data', data, '2day'); }, city(state,data) { //把后端传入过来的数据放入到cookies中 state.city = data; vuecookies.set('city', data, '2day'); } }, actions: { changeuser(context, data) { context.commit('changeuser', data) }, deleteUser(context){ context.commit('deleteUser') }, putdata(context,data){ context.commit('putdata',data) }, city(context,data){ context.commit('city',data) } } })
最后还要挂载到vue对象中;
import Vue from 'vue' import App from './App' import router from './router' import axios from 'axios' import store from'./store/store' // import 'bootstrap' Vue.config.productionTip = false; //在vue的全局变量中设置了$axios = axios Vue.prototype.$axios = axios; // 以后在每个组件中使用时: this.$axios /* eslint-disable no-new */ new Vue({ el: '#app', router, store, components: { App }, template: '<App/>' });
通过在根实例中注册 store
选项,该 store 实例会注入到根组件下的所有子组件中,且子组件能通过 this.$store
访问到
axios类似于ajax一样可以发送请求;
axios基于 Promise 的 HTTP 请求客户端,可同时在浏览器和 node.js 中使用
在vue的全局变量中设置了Vue.prototype.$axios = axios;这样就可以在组件中这样的调用this.$axios
var that = this; this.$axios.request({ url: 'http://127.0.0.1:5000/house', method: 'get', }).then(function (arg) { if (arg.data.code === 1000) { console.log("data", arg.data.data, typeof arg.data.data); // console.log("data",arg.data.data.newhouse,typeof arg.data.data.newhouse); that.$store.dispatch('putdata', arg.data.data); } })
为什么要Var that = this呢,这是因为在axios.request中有this对象;所以此时的This对象不是我们Vue的对象;所有需要重新定义为that,然后that 就代表了vue对象;
使用store的时候,需要使用数据就在store.state中;
更改 Vuex 的 store 中的状态的唯一方法是提交 mutation
这个回调函数就是我们实际进行状态更改的地方,并且它会接受 state 作为第一个参数:
const store = new Vuex.Store({ state: { count: 1 }, mutations: { increment (state) { // 变更状态 state.count++ } } })
不能直接的调用mutation方法;而是要通过:
store.commit('increment')
调用的时候是可以传入数据的;
mutation 都是同步事务
Action 类似于 mutation,不同在于:
- Action 提交的是 mutation,而不是直接变更状态。
- Action 可以包含任意异步操作。
const store = new Vuex.Store({ state: { count: 0 }, mutations: { increment (state,data) { state.count++ } }, actions: { increment (context) { context.commit('increment',data) } } })
Action 通过 store.dispatch
方法触发:
store.dispatch('increment')
mutation 必须同步执行这个限制么?Action 就不受约束!我们可以在 action 内部执行异步操作
actions: { incrementAsync ({ commit }) { setTimeout(() => { commit('increment') }, 1000) } }