Vuex

一、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存储的方法
    => 分解:
       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>复制代码
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值