Vue —— 精讲 VueX (2)

五、mutation的提交风格

这个是commit的另一种写法,高档货
两种写法是有区别的,就是传递的参数不一样的表现

this.$sorte.commit('incrementCour',palyload)
拿到的是一个原模原样的palyload

this.$store.commit({
  type:'incrementCour',
  palyload:palyload
})

和这个时候你拿到的就是一个对象,

六,mutation响应规则

这里写的都是,有关Vue的数据管理,响应式系统的知识点,set方法非常的重要,更改数据,delete是不行的,vue.delete就可以了

这里的知识点,在vue中有很多地方都是这个东西,实际上,vue的响应式原理就是这样的

  1. 首先我们看看如果我修改state里的数据,会发生响应式吗?

我们的state有些情况下是响应式的,有些情况下不是的,什么情况下不是响应式呢?
这里我就直接说明了,

  • 提前在store中初始化所需要的属性,这样才能响应,后添加的属性不会做到数据响应式

如何解决 数据无法深度检测的问题呢? set就能解决


1. 修改
Vue.set( originDate, modifyData ,newValue )
参数说明:originDate ----> 原数据
         modifyData ----> 要更改的数据 Strng:key || number ,如果是修改对象就是 key 数组就是number下标
         newVlaue ----> 新的值 

2. 删除
Vue.delete(object,key)

  1. 以上就是我们的整个的vue的核心响应式原理,其它的部分与vueX里面的响应式原理是差不多类似的东西

七,mutation类型常量

这个东西,跟我们的angular里面的定义类型文件有点相像
核心思想就是定义类型常量

我们目前发现现在这样的一个问题,也就是我们的

  1. 先来看看我们的需求,

我们需求就是,把commit里的字符串提取出啦

我希望我这样用

   additon() {
      this.$store.commit(INCREMENT)
    },
    就能出发修改,而不需要
    additon() {
      this.$store.commit('increment')
    },
  1. 那么我们改如何做呢?
  • 第一步,找到我们的store的文件夹,定义一个类型文件mutation-types.js
export const INCREMENT = 'increment'
  • 第二步,把store里的定义换了,注意啊要把这个类型文件先引入
import { INCREMENT } from './mutations-types'
// 安装
Vue.use(Vuex)

// 使用
const store = new Vuex.Store({
  state: {
      contuned: 1000,
      students: [
          { id: 110, name: 'why', age: 18 },
          { id: 111, name: 'haha', age: 25 },
          { id: 112, name: 'laoli', age: 45 }
      ],
      info: {
          name: 'laoli',
          age: 18,
          number: 666
      }
  },
  mutations: {
      [INCREMENT](state) {
          state.contuned++
      },
  • 第三步 在用的地方搞掉就好了

/app.vue


<template>
  <div id="app">
    <p>{{ $store.state.contuned }}</p>
    
      <button @click="additon" >+</button>
      <button @click="subraction" >-</button>
    
    <h1>------bmlaoli的界面--------</h1>

    <bmlao></bmlao>





<p>{{$store.state.info}}</p>
<button @click="uplateInfo">修改信息</button>
<h1>-------我是测试响应式的数据-------</h1>
<div>

<p>{{$store.state.info}}</p>

</div>
  </div>
</template>

<script>

import bmlao from '@/components/Bmlaoli';
import { INCREMENT  } from './store/mutations-types'

export default {
  name: 'App',
  components: {
    bmlao,
  },
  data() {
    return {
      // contuned: 100
    }
  },
  methods: {
    additon() {
      this.$store.commit(INCREMENT)
    },
    subraction() {
      this.$store.commit('decrement')
      
    },
    uplateInfo(){
      this.$store.commit('uplateInfo')
    }
  },
  
}
</script>

<style>
</style>


八,actions里面的异步操作

1. 简单的异步处理

目前,我们的需求是:我们的修改muatrion里面的存在着异步的操作,那么我如何解决呢?
解决方案就是使用action对mutaion替代

  • 定义action
    /store/index.js

  actions: {

        // context = store对象 上下文对象
        aupdataeInfo(context) {
            // 这样就是一个异步的操作了
            setTimeout(() => {
                context.commit('uplateInfo')
            }, 1000)

        }

    },

  • 触发action
    /app.vue
  this.$store.dispatch( 'aupdataeInfo')

2. 传递参数

实际上这个action和mutacion是差不多一样的写法 palyad负载
/store/index.js

    // context = store对象 上下文对象
        aupdataeInfo(context) {
            // 这样就是一个异步的操作了
            setTimeout(() => {
                context.commit('uplateInfo', payload)
                console.log(payload);//这就是你丢过来的参数
            }, 1000)

        }

APP.vue

  this.$store.dispatch( 'aupdataeInfo','我是携带的讯息')

3. 通知(回调)

  1. 大对象的方式
    我们传递的是这样的东西就可以了,在异步的里面进行回调就好了

app.vue

  this.$store.dispatch( 'aupdataeInfo',{
    message:{
      name:'我是携带的讯息'
    },
    success:() => {
      conslog.log('我是回调')
    }
  })

/stoe/


 // context = store对象 上下文对象
aupdataeInfo(context) {
    // 这样就是一个异步的操作了
    setTimeout(() => {
        context.commit('uplateInfo', payload)
        console.log(payload.message);//这就是你丢过来的参数
        payload.sucees()//我是回调
  }, 1000)
}

问题,不够高端,B格不够
2. promise的方式

/store/index.js

aupdataeInfo(context,payload) {
    // 这样就是一个异步的操作了
    setTimeout(() => {

      retrun new Promies( (resolve,rejcet)=>{
          context.commit('uplateInfo')
          consloe.log(payload)

          // resolve()//回调出去就好了。如果有讯息就可以外卖拿
          resolve('message is susecce')
      } )

  }, 1000)
}

*问题严重了,我们去哪儿点then呢?答案很简单,我们去被用到的地方*,这个设计就非常的好,谁用了,就在谁哪里调

app.vue

  this.$store.dispatch()
  .then( (res)=>{
    console.log('回调完成了任务')
    console.log(res)
  } )

以上就是我们的action的相关讲解

九、mouldes分模块出去

简单的抽离

我们现在有这样的有这样的需求,我现在发现我们的store对象里面的state有点多,有没有办法把这个东西抽离出去呢?答案是有的,这就是我们的模块核心modules

  1. 抽离

这里我干的事情就是把我的林一个状态,以模块的形式抽离出去
/store/index.js

    modules: {

        // 假设我们这里有abc三个模块,注意 每一个模块实际上就是一个子的store对象
        a:{
            state:{},
            getters:{},
            mutations:{},
            actions:{}
        },

        c:{
            state:{},
            getters:{},
            mutations:{},
            actions:{}
        },
    }

// 实际上我应该这样的抽离出去

// 模块
const moduleA = {
  state: {
      state:{
          name:'厉害着'
      }
  },
  mutations: {},
  actions:{},
  getters:{
  }
}

++++
    modules: {
        a : moduleA,
        b : moduleB
    }


  1. 使用

使用起来也是相对的比较简单
/App.vue

  <h1>------module的界面--------</h1>
  <p>{{$store.state.a.name}}</p>
  <!-- 注意啊 有点奇怪。确确实实你需啊哟state.a才能拿到模块 -->

mutation怎么搞?

如果我要在模块里面使用mutataion那么我该如何做呢?实际上也非常的简单
store/index.js

const moduleA = {
  state: {
      state:{
          name:'厉害着'
      }
  },
  mutations: {
    //    注意啊,这里的名字不能喝下面的重复
      upadtaeName(state,payload){
          state.name = payload
      }
  },
  actions:{},
  getters:{
  }
}
  • 使用的时候也是一样
    /App.vue
upadtae(){
   this.$store.dispatch( 'upadtaeName','我是模块修改的内容')
}

getter如何搞?

getter也是一样的,和我们的平常的使用是一样的
/store/index.js

  getters:{
    fullName(state){
        return state.name + '111'
    },
    
    // 如果我想要要自己毁掉呢?
    fullName2(state,getters){
        return  getters.fullName + '222'// 这里的fullNamez这里的getter指代的就是这个模块的getter
    },

    //如果我想用下面的大的对象的 爸爸的数据呢?
    fullName3(state,getters,rootState){
        return  getters.fullName + '222'// 这里的fullNamez这里的getter指代的就是这个模块的getter
        // rootState 就是我们的大的store的state
    },
  }

使用
/App.vue

<P>{{ $store.getter.fullName }} </p>

action异步的操作是怎么样的?

异步操作也是非常的简单的 ,定义操作模式

/store/index.js

// 注意啊,这里的上下文和以前的是不一样的
actions:{
      aupdateName( context ){
        setTimeout(() => {
            // 拿到这个操作对象 你就能干很多的东西了
            console.log(context);
        }, 1000);
      }
  },

基础的使用也是非常的简单的


asnycUpdateName(){
  this.$store.dispatch('aupdateName')
}


十、文件抽离组织

十、文件抽离组织

高度解耦,来来来,我们看看管方给的定义

我们现在要做一件这样的事情,把我们的一些代码抽离到一些文件中去,这样我们就能非常的方便灵活的管理我们的vuex的一些状态了

├── index.html
├── main.js
├── api
│ └── ... # 抽取出API请求
├── components
│ ├── App.vue
│ └── ...
└── store
├── index.js # 我们组装模块并导出 store 的地方
├── actions.js # 根级别的 action
├── mutations.js # 根级别的 mutation
└── modules
├── cart.js # 购物车模块
└── products.js # 产品模块

我们现在就分别抽离出去就好了
--- 抽离出去之后我们的vuex的代码就简洁多得多了
/sotre/index.js


import Vue from 'vue'
import Vuex from 'vuex'

import mutations from './mutation'
import actions from './actions'
import getters from './getters'

// 模块
import moduleA from './modules/modules'

// 安装
Vue.use(Vuex)


// 使用
const store = new Vuex.Store({
    state: {
    contuned: 1000,
    students: [
        { id: 110, name: 'why', age: 18 },
        { id: 111, name: 'haha', age: 25 },
        { id: 112, name: 'laoli', age: 45 }
    ],
    info: {
        name: 'laoli',
        age: 18,
        number: 666
    }
    },
    mutations,
    actions,
    getters,
    modules: {
        a : moduleA,
    }
})

// 倒出
export default store

posted @ 2020-06-11 18:45  BM老李  阅读(280)  评论(0编辑  收藏  举报