vue中vuex的使用练习

Vuex 是什么?

Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式。它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化。访问官网,点击这里

每一个 Vuex 应用的核心就是 store(仓库)。“store”基本上就是一个容器,它包含着你的应用中大部分的状态 (state)。Vuex 和单纯的全局对象有以下两点不同:

  1. Vuex 的状态存储是响应式的。当 Vue 组件从 store 中读取状态的时候,若 store 中的状态发生变化,那么相应的组件也会相应地得到高效更新。

  2. 你不能直接改变 store 中的状态。改变 store 中的状态的唯一途径就是显式地提交 (commit) mutation。这样使得我们可以方便地跟踪每一个状态的变化,从而让我们能够实现一些工具帮助我们更好地了解我们的应用。

vuex中,有默认的五种基本的对象:

  • state:存储状态(变量)

  • getters:对数据获取之前的再次编译,可以理解为state的计算属性。我们在组件中使用 $sotre.getters.fun()

  • mutations:修改状态,并且是同步的。在组件中使用$store.commit('',params)。这个和我们组件中的自定义事件类似。

    扫描二维码关注公众号,回复: 8362082 查看本文章
  • actions:异步操作。在组件中使用是$store.dispath('')

  • modules:store的子模块,为了开发大型项目,方便状态管理而使用的。这里我们就不解释了,用起来和上面的一样。

0、在 main.js里面,引入vuex相关的js文件

import store from './store'
// store.js

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

import user from './module/user'
import app from './module/app'

Vue.use(Vuex)

export default new Vuex.Store({
  state: {
    //
    number: 0
  },
  mutations: {
  
  },
  getters: {
   
  },
  actions: {
    
  },
  modules: {

  }
})

1、在 Vue 组件中获得 Vuex 状态(state)

(1)直接在组件father.vue中调用:

<div style="border: 2px solid #007606;padding: 5px;">
      VUEX的数据【number】:
      <span style="font-size: 30px;font-weight: bolder;">
        {{this.$store.state.number}}
      </span>
</div>

 (2)或者在计算属性中处理后使用

<div style="border: 2px solid #007606;padding: 5px;">
  VUEX的数据【number】:
  <span style="font-size: 30px;font-weight: bolder;">
    {{count}}
  </span>
</div>
computed: {
  count () {
    return '==这是VUEX中定义的Number==:'+this.$store.state.number
  }
},

2、Getter

有时候我们需要从 store 中的 state 中派生出一些状态,

如果有多个组件需要用到此属性,我们要么复制这个函数,或者抽取到一个共享函数然后在多处导入它——无论哪种方式都不是很理想。

Vuex 允许我们在 store 中定义“getter”(可以认为是 store 的计算属性)。就像计算属性一样,getter 的返回值会根据它的依赖被缓存起来,且只有当它的依赖值发生了改变才会被重新计算。

(1)实例:孙子级组件F中,处理【number】的值,*2

<div style="border: 2px solid #2700ff;padding: 5px;">
  Vuex的数值【number*2】:
  <span style="font-size: 30px;font-weight: bolder;">
  {{$store.getters.doneTodosCount}}
  </span>
</div>

(2)store.js代码:

getters: {
  doneTodosCount: (state, getters) => {
    return state.number * 2
  }
},

3、Mutation(Mutation 必须是同步函数)

更改 Vuex 的 store 中的状态的唯一方法是提交 mutation。Vuex 中的 mutation 非常类似于事件:每个 mutation 都有一个字符串的 事件类型 (type) 和 一个 回调函数 (handler)。这个回调函数就是我们实际进行状态更改的地方,并且它会接受 state 作为第一个参数

(1)实例:祖父级组件parent,点击按钮,对number进行++或者--的操作

<div style="border: 2px solid #007606;padding: 5px;">
  VUEX的数据【number】:
  <span style="font-size: 30px;font-weight: bolder;">
    {{count}}
  </span>

  <br>
  <el-button @click="vuexClick1">点击++</el-button>
  <el-button @click="vuexClick2">点击--</el-button>
</div>
methods: {
  vuexClick1 () {
    this.$store.commit('vuexClick1')
  },
  vuexClick2 () {
    this.$store.commit('vuexClick2')
  }
},

(2)store.js代码:

mutations: {
  //
  vuexClick1 (state) {
    return state.number++
  },
  vuexClick2 (state) {
    return state.number--
  }
},

4、Ation

Action 类似于 mutation,不同在于:

  • Action 提交的是 mutation,而不是直接变更状态。

  • Action 可以包含任意异步操作。

(1)实例:祖父级组件parent,点击按钮"number延时3s加10",对number进行延时3s加10的操作

<el-button @click="vuexClick3">number延时3s加10</el-button>
vuexClick3 () {
  this.$store.dispatch('vuexClick3')
}

(2)store.js代码:

actions: {
  //
  vuexClick3 (state) {
    setTimeout(() => {
      return state.commit('NumberChange3')
    }, 3000)
  }
},
NumberChange3 (state) {
  return state.number += 10
}

5、Module

官方文档

完整代码:

1.store.js

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

import user from './module/user'
import app from './module/app'

Vue.use(Vuex)

export default new Vuex.Store({
  state: {
    //
    number: 0
  },
  mutations: {
    //
    vuexClick1 (state) {
      return state.number++
    },
    vuexClick2 (state) {
      return state.number--
    },
    NumberChange3 (state) {
      return state.number += 10
    }
  },
  getters: {
    doneTodosCount: (state, getters) => {
      return state.number * 2
    }
  },
  actions: {
    //
    vuexClick3 (state) {
      setTimeout(() => {
        return state.commit('NumberChange3')
      }, 3000)
    }
  },
  modules: {
    user,
    app
  }
})

2.father.vue

<!--
  文件描述:祖父级组件
  创建时间:2019/12/28 15:30
-->
<template>
  <div class="" style="width: 900px;height: 700px;background-color: #d6e7ff;padding: 20px;">
    <span style="font-size: 20px;font-weight: bold;">祖父级组件:father</span>
    <div style="border: 2px solid #007606;padding: 5px;">
      VUEX的数据【number】:
      <span style="font-size: 30px;font-weight: bolder;">
        {{count}}
      </span>

      <br>
      <el-button @click="vuexClick1">点击++</el-button>
      <el-button @click="vuexClick2">点击--</el-button>
      <el-button @click="vuexClick3">number延时3s加10</el-button>
    </div>
    <br>

    <div>
      <childrenA></childrenA>
      <childrenB></childrenB>
      <childrenC></childrenC>
    </div>
  </div>
</template>

<script>
// 这里可以导入其他文件(比如:组件,工具js,第三方插件js,json文件,图片文件等等)
// 例如:import 《组件名称》 from '《组件路径》';
import childrenA from './childrenA'
import childrenB from './childrenB'
import childrenC from './childrenC'

export default {
  name: 'father',
  // import引入的组件需要注入到对象中才能使用
  components: {
    childrenA,
    childrenB,
    childrenC
  },
  computed: {
    count () {
      return this.$store.state.number
    }
  },
  methods: {
    vuexClick1 () {
      this.$store.commit('vuexClick1')
    },
    vuexClick2 () {
      this.$store.commit('vuexClick2')
    },
    vuexClick3 () {
      this.$store.dispatch('vuexClick3')
    }
  },
  data () {
    // 这里存放数据
    return {
    }
  }
}
</script>

3.childrenG.vue

<!--文件描述:孙子级组件G
  创建时间:2019/12/28 15:37-->
<template>
  <div class="" style="float: left;margin: 10px;width: 200px;height: 200px;background-color: #ff00de;padding: 20px;color:#fff;">
    <span style="font-size: 14px;font-weight: bold;color:#fff;">孙子级组件G:childrenG</span>
    <div style="border: 2px solid #00ff09;padding: 5px;">
      VUEX的数据【number】:
      <span style="font-size: 30px;font-weight: bolder;">
        {{this.$store.state.number}}
      </span>
    </div>
  </div>
</template>

<script>
export default {
  name: 'childrenA',
  // import引入的组件需要注入到对象中才能使用
  components: {},
  data () {
    // 这里存放数据
    return {
    }
  }
}
</script>

4.childrenF.vue

<!--
  文件描述:孙子级组件F
  创建时间:2019/12/28 15:37
  创建人:
-->
<template>
  <div class="" style="float: left;margin: 10px;width: 200px;height: 200px;background-color: #aaff1a;padding: 20px;">
    <span style="font-size: 14px;font-weight: bold;color:#000000;">孙子级组件F:childrenF</span>
    <div style="border: 2px solid #2700ff;padding: 5px;">
      Vuex的数值【number*2】:
      <span style="font-size: 30px;font-weight: bolder;">
      {{$store.getters.doneTodosCount}}
      </span>
    </div>
  </div>
</template>

<script>
// 这里可以导入其他文件(比如:组件,工具js,第三方插件js,json文件,图片文件等等)
// 例如:import 《组件名称》 from '《组件路径》';
// 例如:import uploadFile from '@/components/uploadFile/uploadFile'

export default {
  name: 'childrenA',
  // import引入的组件需要注入到对象中才能使用
  components: {},
  data () {
    // 这里存放数据
    return {

    }
  },
  // 监听属性 类似于data概念
  computed: {},
  // 方法集合
  methods: {},
  // 监控data中的数据变化
  watch: {},
  // 生命周期 - 创建完成(可以访问当前this实例)
  created () {

  },
  // 生命周期 - 挂载完成(可以访问DOM元素)
  mounted () {

  },
  beforeCreate () {
  }, // 生命周期 - 创建之前
  beforeMount () {
  }, // 生命周期 - 挂载之前
  beforeUpdate () {
  }, // 生命周期 - 更新之前
  updated () {
  }, // 生命周期 - 更新之后
  beforeDestroy () {
  }, // 生命周期 - 销毁之前
  destroyed () {
  }, // 生命周期 - 销毁完成
  activated () {
  } // 如果页面有keep-alive缓存功能,这个函数会触发
}
</script>

<style scoped  lang="scss">
  //@import url(); 引入公共css类
</style>

猜你喜欢

转载自www.cnblogs.com/pangchunlei/p/12118391.html