一、Vuex 大规模管理状态的数据池
- 由于组件传值比较脆弱,子组件,同级组件,会很麻烦,发布订阅模式,使代码管理起来比较困难 (newButtons)
- 该变状态的两种方法
- 直接修改state的值, store.state.count = 100;
- 1.vueTools检测不到数据变化,调试空难,
- new Vuex.Store进行参数配置 , 不允许直接修改state
- 同步改变,没有异步请求 this.$store.commit(fnName) =>提交到mutations里面 => mutations该变state存储的数据 => state存储的数据是响应式的,修改了 => render 重新渲染页面
- 异步该变, ajax请求数据完成后 this.$store.dispatch => 通知actions我去触发一个动作 => 这个动作在去调用mutations => state存储的数据是响应式的,修改了 => render 重新渲染页面
- state和getters存储的是object {}, mutations和actions存储的方法
- 直接修改state的值, store.state.count = 100;
=> 分解:
1. store: 管理这个数据池的对象(仓库)
2. state: 存储所有数据的对象
3. getters
4. mutations: 去提交修改state数据池里面的值
5.actions
6.modules
mutations和actions里面的方法的this指向store对象
=> 修改state方法
1. store.state.count = 1; {{{{store.state.count}}}} 不建议使用,观测不到count的变化
2.computed计算属性 {{getCount}} (两种写法)
getCount() {
return this.$store.state.count;
}
3. commit修改 commit提交 mutations进行修改state
<!--1.方法store对象获取-->
{{store.state.count}}
<!-- 2.计算属性获取 -->
{{getCount}}
<!-- 3.提交commit进行mutations进行修改state -->
<button @click="add">add</button>
<button @click="remove">remove</button>
//=>创建store对象
const store = new Vuex.Store({
state: {
count: 0
},
mutations: {
add(state) {
this.state.count ++; // => this指向store对象
},
remove(state) {
this.state.count --;
}
},
computed:{
getCount() {
return store.state.count(前提是在同一个文件里面); // => 等价关系 this.$store.state.count; 建议用他
}
}
});
const vm = new Vue({
el: '#root',
store,
computed:{
getCount() { //=> 计算属性
return this.$store.state.count;
}
},
methods: {
add() { //= >commit进行提交
this.$store.commit('add');
},
remove() {
this.$store.commit('remove');
}
}
});
复制代码
二、使用方式
学习网址:
https://www.jianshu.com/p/aae7fee46c36
https://www.jianshu.com/p/054486340a9b?utm_campaign=maleskine&utm_content=note&utm_medium=seo_notes&utm_source=recommendation
安装: npm isntall vuex --save => 保存到正式环境中
1. 引入Vuex import Vuex from 'vuex'
2. 依赖注入 Vue.use(Vuex);
3. 创建Vuex的实例 const store = new Vuex.Store({});
4 在跟组件中挂在vuex, store参数配置 就可以使用$store进行管理状态了,类似于vue-router, router, 注册了就有了$route, $router
5. 所有的组件可以使用store里的数据了,实现了数据共享, store里面的数据也是响应式的
this.$store.state获取和设置状态了 this可以简写
tips:{
template:`<div>{{$store.state.count}}</div>`
}
复制代码
三、new Vuex.Store进行配置选项
=> state (类似存储全局变量的数据) object类型 state: {}
=> getters (提供用来获取state数据的方法) object类型 、里面方法接收一个参数, 参数存储state的状态 getters: {},类似于computed计算属性 [类似于 Vue 中的计算属性,根据其他 getter 或 state 计算返回值。]
=> actions (提供跟后台接口打交道的方法,并调用mutations提供的方法) object类型 、里面方法接收一个参数, 参数存储state的状态 actions: {} 异步操作
=> mutations (提供存储设置state数据的方法) object类型 、里面方法接收一个参数, 参数存储state的状态 mutations: {} 通过commit进行提交,执行它里面的方法 [一组方法,是改变**store**中状态的执行者]
复制代码
四、 Vuex的静态方法
Store ==> 存储大规模状态容器 是一个类 使用的时候 是Vuex类上的静态方法Store, Store是一个类 new Vuex.Store({});
=> 是一些快捷写法:
Vuex.mapActions
Vuex.mapGetters
Vuex.mapMutations
Vuex.mapState
复制代码
console.dir(Vuex);
五 Vuex.Store Store上的静态方法
复制代码
六 new Vuex.Store Vuex.store.prototype原型上的方法
七,依次详解new Vuex.Store里面的各个参数
<< store数据池对象,管理这些数据的 >>
一、state (状态,大规模存储状态,也就是共享的数据) (存储所有数据的对象) => mapState函数的使用
=> 组件中的computed使用的
- 第一种方法: computed: { count: state => state.count, num1: state => state.num1 }
- 第二种方法: computed: ...mapState(['count', 'num1', 'num2']); 计算属性都是store的,无法添加自己的了,弊端
- 第三种方法: computed: { ...mapState(['count', 'num1', 'num2']), // ==> store里面的数据 getX() {return 100} // => 自己私有的数据 }
=> mapState是Vuex类的静态方法
HTML页面: <todo></todo>
components: {
todo: {
template: `<div>{{count}}-{{num1}}-{{num2}} {{x}}</div>`,
data() {
return {
x: 'vuex'
}
},
// 1.=> 依次获取,可以添加自己的计算属性
computed: Vuex.mapState({
count: state => state.count,
num1: state => state.num1,
num2: state => state.num2,
getX() {
return this.x;
}
}),
// 2.=> 数组传递法,不能加添自己的属性
computed: Vuex.mapState(['count', 'num1', 'num2']),
// 3.=> 数组传递法,使用展开运算符,还可以添加自己的计算属性方法
computed: {
...Vuex.mapState(['count', 'num1', 'num2']),
getX() {
return this.x;
}
}
}
}
复制代码
Vuex 使用 state来存储应用中需要共享的状态。为了能让 Vue 组件在 state更改后也随着更改,需要基于state创建computed计算属性。 computed计算属性必须有返回值return
<div>{{count}}</div>
<div>{{$store.state.count}}</div> // ==>> 这样写起来太麻烦, 所有用到了计算属性x
const store = new Vuex.Store({
state: {
userName: '',
isLogin: true,
count: 0
}
});
组件使用:
let home = {
template: `<div>{{$store.state.usreName}}</div>`,
computed:{
count() {
return this.$store.state.count;
}
}
}
复制代码
二、getters 类似于组件中的computed属性,计算属性,关联的数据发生改变,会重新计算值得 mapGetters
mapGetters用法和mapState一样,也是三种用法, ...mapGetters最常用
const store = new Vuex.Store({
state: {
count: 1,
num1: 2,
num2: 3
},
getters:{
sum(state) {
console.log(this);
let sum = state.count + state.num1 + state.num2;
return sum;
},
avg(state) {
return (this.getters.sum)/3; this.$store.getters.sum//=========> 这两个是错误的,this是window对象
return (store.getters.sum)/3;
}
}
});
const vm = new Vue({
el: '#root',
store,
components: {
todo: {
template: `<div>{{count}}-{{num1}}-{{num2}} {{x}} {{sum}} {{avg}}</div>`,
data() {
return {
x: 'vuex'
}
},
computed: {
...Vuex.mapState(['count', 'num1', 'num2']), // ===> state里面的数据
...Vuex.mapGetters(['sum', 'avg']), // ===>> getters里面的方法
getX() {
return this.x;
}
}
}
}
});
复制代码
三、mutations (改变) mutations里的方法 => 修改state的数据 => render [ commit=> muations=>states=>render ]
前面两个都是状态值本身,mutations才是改变状态的执行者。mutations用于同步地更改状态
- 字符串形式提交 => this.$store.commit(方法名,'1', '100') 方法名是mutations里的方法 => 进行提交
- 对象形式提交 => 他里面的方法第一个参数默认是state,是数据对象,以后的参数是用户传的
- mutations里面的方法第一个参数是代理的是state,数据集对象,形参可以修改其他的
- 提交commit的两种方式
- this.$store.commit('setX', 'vuex');
- this.$store.commit({ type: 'setX', val: 'vuex' }); mutations:{ setX(state,playod) { console.log(playod); //=> {type: "remove", x: 1, y: 2} } } 额外的参数会封装进一个对象,作为第二个参数传入mutation定义的方法中。
<div>{{x}}</div>
mutations: {
setX(state, val) {
this.state.x = val;
},
getX(state, playod) {
console.log(playod); // => {type: "remove", x: 1, y: 2}
}
};
methods: {
fn1() {
// 字符串形式提交commit
this.commit('setX', 100);
},
fn2() {
// ==>> 正规提交commit,对象形式
this.commit({
type: 'getX',
x: 1,
y: 2
});
}
}
computed: {
getX() {
return this.$store.state.x;
},
}
复制代码
四、actions (通知) mutatoins, 异步获取数据改变state的状态 [ dispatch => actoins => mutations => states => render ] actions里面的方法第一个参数必须是{commit} 包起来,不包的话commit是一个对象,包起来是函数
- 字符串形式提交
- 对象形式提交(规范)
- actions 里面的方法第一个参数必须是 {commit} 是提交函数
mutations:{
setX(state, val) {
this.state.count = val.x;
},
setX1(state, val) {
this.state.count = val;
}
}
actions: {
fn({commit}, playod) { //=> 加了{}, commit就是一个函数,不加就是一个对象了
commit('setX', playod); // playod=> 就是 {type:'fn', val:'vuex'}对象
},
fn({commit}, val) {
commit('setX1', val);
}
}
methods: {
change() {
// ==>> 规范的对象提交
this.$store.dispatch({
type: 'fn',
val: 'vuex'
});
},
// ==> 字符串提交
change1() {
this.$store.dispathc('fn1', 'vuex-vx');
}
}
复制代码
action处理异步的正确使用方式
=> 想要使用action处理异步工作很简单,只需要将异步操作放到action中执行(如上面代码中的setTimeout)。
=> 要想在异步操作完成后继续进行相应的流程操作,有两种方式:
1. action返回一个 promise。[ actions里面的方法执行完毕返回一个promise对象 ]
dispatch方法的本质也就是返回相应的action的执行结果。所以dispatch也返回一个promise
methods: {
let act1 = this.$store.dispatch('fn1');
console.log(act1 instanceof Promise); //=> true
act1.then(res => {
console.log(res);
}).catch(err => {
console.log(err);
})
}
复制代码
<!DOCTYPE html>
<html>
<head>
<title></title>
</head>
<body>
<div id="app">
{{x}}
<button @click='add'>增加</button>
<button @click='remove'>减去</button>
<button>getters</button>
</div>
<script src="https://unpkg.com/vue/dist/vue.js"></script>
<script type="text/javascript" src="vuex.js"></script>
<script type="text/javascript">
const store = new Vuex.Store({
state: {
x: 1
},
mutations:{
add(state) {
state.x ++;
},
remove(state) {
state.x --;
}
},
getters: {
getX(state) {
return 100;
}
}
});
console.dir(Vuex);
/*
Vuex 集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化
*/
/*
new Vuex.Store(options)
state (类似存储全局变量的数据) object类型
getters (提供用来获取state数据的方法) object类型 、里面方法接收一个参数, 参数存储state的状态
actions (提供跟后台接口打交道的方法,并调用mutations提供的方法) object类型 、里面方法接收一个参数, 参数存储state的状态
mutations (提供存储设置state数据的方法) object类型 、里面方法接收一个参数, 参数存储state的状态
*/
/*
Vuex的静态方法
Store ==> 存储大规模状态容器 是一个类 使用的时候 是Vuex类上的静态方法Store, Store是一个类 new Vuex.Store({});
mapActions
mapGetters
mapMutations
mapState
*/
/*
new Vuex.Store()返回Store的一个实例
new Vuex.Store() instanceof Vuex.Store // => true
store实例上的东西
代理了:
_actions
_mutations
commit
dispatch
getters
state
*/
/*
将store注入到根组件中, 就可以使用this.$store了 (通过在根实例中注册 store 选项,该 store 实例会注入到根组件下的所有子组件中,且子组件能通过 this.$store 访问到。让我们更新下 Counter 的实现:)
this.$store.state.city
*/
console.dir(Vuex.prototype);
console.dir(store);
console.dir(store.prototype);
const vm = new Vue({
el: '#app',
store,
computed:{
val() {
return this.$store.state.city
}
}
methods: {
add() {
store.commit('add');
},
remove() {
store.commit('remove');
},
}
});
</script>
</body>
</html>复制代码