当前位置:   article > 正文

vuex知识

vuex知识

Vuex之Mutation

mutation用于管理同步事件,如果有异步操作,请用action。

更改 Vuex 的 store 中的状态的唯一方法是提交 mutation。

vue中,我们要修改data中的值,一般会这么做。

this.count = 2
  • 1

如果我们要修改vuex的store中的状态值,我们就不能简单的通过赋值的方式来做了,如果你这样做,控制台便会报错。

this.$store.state.count = 2 //控制台打印错误
  • 1

vuex提供了mutation来追踪你对state的值的操作,你要使用commit()来触发mutation里面的方法。

示例如下:

//state.js
let state = {
  count: 1,
  name: 'lyh',
}
export default state
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
//mutation.js
// 第一个参数默认接收state对象
const increment = (state) => {
  state.count++
}
const decrement = (state) => {
  state.count--
}
//第二个参数接收'载荷'
const add = (state, n) => {
  state.count += n
}
const fn = (state, json) => {
  state.name = json.first + json.second + state.name
}
export {increment, decrement, add, fn}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
<template>
  <div>
    <div>
      <button @click="decrement">-</button>
      <span>{{count}}</span>
      <button @click="increment">+</button>
    </div>
    <div style="margin-top:20px;">
      <button @click="add(1)">+1</button>
      <button @click="add(2)">+2</button>
    </div>
    <button style="margin-top:20px" @click = "changeName('my ','name is ')">{{name}}</button>
  </div>
</template>
 
<script>
export default {
  computed: {
    count () {
      return this.$store.state.count
    },
    name () {
      return this.$store.state.name
    }
  },
  methods: {
    decrement () {
      this.$store.commit('decrement')
    },
    increment () {
      this.$store.commit('increment')
    },
    add (n) {
      // 你可以向 store.commit 传入额外的参数,即 mutation 的 载荷(payload)
      this.$store.commit('add', n)
    },
    changeName (first, second) {
      this.$store.commit('fn', {
         'first': first,
         'second': second
      })
    }
  }
}
</script>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45

mutation的辅助函数,用法示例如下:

<template>
  <div>
    <div>
      <button @click="decrement">-</button>
      <span>{{count}}</span>
      <button @click="increment">+</button>
    </div>
    <div style="margin-top:20px;">
      <button @click="add(1)">+1</button>
      <button @click="add(2)">+2</button>
    </div>
    <button style="margin-top:20px" @click = "changeName({'first':'my ',second:'name is '})">{{name}}</button>
  </div>
</template>
 
<script>
import { mapMutations } from 'vuex'
export default {
  computed: {
    count () {
      return this.$store.state.count
    },
    name () {
      return this.$store.state.name
    }
  },
  // 辅助函数写法
  methods: {
    ...mapMutations({
      decrement: 'decrement',
      increment: 'increment', // 将 `this.increment()` 映射为 `this.$store.commit('increment')`
      add: 'add',
      changeName: 'fn' // 将 `this.changeName(json)` 映射为 `this.$store.commit('fn', json)`
    })
  }
}
</script>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37

vuex之action

例子:在action中, 根据传入的参数(数字1-250)异步请求电影数据, 在请求完成后提交mutation。
在state中声明一个对象, 用于存储查询到的电影的相关信息。

searchResult: {}
  • 1

状态更改,在mutation中,将查询的结果(传入的参数), 赋值给state中声明的变量。

 haveRestult(state, ret) {
        state.searchResult = ret;
 }
  • 1
  • 2
  • 3

数据请求,在action中, 根据传入的参数(数字1-250)异步请求电影数据, 在请求完成后提交mutation。

getMoviesRankingInDouban({ commit, state }, number) {
    let num = number - 1 === 0 ? 0 : number - 1 || 1;
    axios({
            method: "get",
            url: "v2/movie/top250?start=" + num + "&count=1"
        })
        .then(res => {
            commit("haveRestult", res.data.subjects[0] || {})
        })
        .catch(err => {
            console.log(err, "获取豆瓣数据失败");
        })
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13

在组件内调用时, 将参数传入即可。

this.$store.dispatch("getMoviesRankingInDouban", this.Ranking);
  • 1

使用辅助函数 mapActions。

 methods: {
    ...mapMutations([
      'action1', // 映射为组件内的同名方法
    ]),
    ...mapActions({
      action2AnotherName: 'action2' // 将action2 映射为组件内名为action2AnotherName的方法.
    })
  }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

组合 Action

对于多个action相互依赖顺序的情况下, 可以使用promise来判断上一个action的结束. 再进行下一步的action操作。
将getMoviesRankingInDouban的action用promise包装一下, 在此次请求结束后, 根据此次请求返回的电影的id, 根据id再次请求电影的信息。

getMoviesRankingInDouban({ commit, state }, number) {
    let num = number.number - 1 === 0 ? 0 : number.number - 1 || 1;
    return new Promise((resolve, reject) => {
        axios({
                method: "get",
                url: "v2/movie/top250?start=" + num + "&count=1"
            })
            .then(res => {
                commit("haveRestult", res.data.subjects[0] || {});
                resolve();
            })
            .catch(err => {
                console.log(err, "获取豆瓣数据失败");
                reject()
            })
    })
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17

在组件内,封装依据id获取电影信息的方法。

getMovieMsgById(id){
    this.$ajax.get("v2/movie/subject/" + this.$store.state.searchResult.id)
        .then((res) => {
            alert(JSON.stringify(res.data));
        })
        .catch((err) => {
            console.log(err)
        })
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

页面按钮绑定点击事件searchMovieById, 事件中 调用getMoviesRankingInDouban, 成功后, 调用getMovieMsgById方法。

searchMovieById(){
    this.$store.dispatch({
        type:"getMoviesRankingInDouban",
        number: this.Ranking
    })
    .then(() => {
        this.getMovieMsgById();
    })
    .catch((err) => {
        console.log(err);
    })
},
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/你好赵伟/article/detail/940179
推荐阅读
相关标签
  

闽ICP备14008679号