一篇文章带你深入浅出Vuex

野性酷女 2021-08-26 18:27 725阅读 0赞

在写Vuex之前,我们先用一个简单的例子来实现一个小demo

大家都知道Vue的父传子用在很多场景,比如像这样:

父组件:

  1. <template>
  2. <div id="app">
  3. <product-list-one :msg='msg'></product-list-one>
  4. </div>
  5. </template>
  6. <script> export default { name: 'app', components:{ 'product-list-one':ProductListOne, }, data () { return { msg:'love' } } } </script>

子组件:

  1. <template>
  2. <div id="product-list-one">
  3. <div>{
  4. {msg}}</div>
  5. </div>
  6. </template>
  7. <script> props:['msg'] </script>

有父传子,当然也有子传父:

子组件:

  1. <template>
  2. <div id="product-list-one">
  3. <button @click="but">点击</button>
  4. </div>
  5. </template>
  6. <script> data(){ return { txt:'hello' } }, methods:{ but() { this.$emit('get',this.txt); } } </script>

父组件:

  1. <template>
  2. <div id="app">
  3. <product-list-one :msg='msg' @get='world'></product-list-one>
  4. </div>
  5. </template>
  6. <script> import ProductListOne from './components/ProductListOne.vue' export default { name: 'app', components:{ 'product-list-one':ProductListOne }, methods:{ world(data){ console.log(data) } } } </script>

但是有些场景如果使用父传子、子传父的话,很难实现。比如说:
在这里插入图片描述
a组件b组件相互通信,必须要有一个公共变量库才更方便。
所以Vuex应运而生,通过创建一个集中的数据存储,供程序中所有组件访问。

一、安装

  1. npm install vuex

二、配置

创建一个store文件夹在根目录src下,然后在文件夹里创建一个名叫index.js文件。

  1. import Vue from 'vue'
  2. import Vuex from 'vuex'
  3. Vue.use(Vuex)
  4. export const store = new Vuex.Store({
  5. strict:true,
  6. state:{ },
  7. getters:{ },
  8. mutations:{ },
  9. actions:{ }
  10. });

然后在src文件夹下的main.js文件里引入store

  1. import Vue from 'vue'
  2. import App from './App.vue'
  3. import { store} from './store/store'
  4. new Vue({
  5. store:store,
  6. el: '#app',
  7. render: h => h(App)
  8. })

三、实际操作

Vuex分为四大板块:

  • state
  • getters
  • mutations
  • actions

那么我们接下来分别讲解一下。

1、state

state用于存储数据。

  1. import Vue from 'vue'
  2. import Vuex from 'vuex'
  3. Vue.use(Vuex)
  4. export const store = new Vuex.Store({
  5. strict:true,
  6. state:{
  7. products:[
  8. { name:"马云",price:200},
  9. { name:"马化腾",price:140},
  10. { name:"马冬梅",price:20},
  11. { name:"马蓉",price:10}
  12. ]
  13. }
  14. });

使用this.$store.state.products获取获取数据。

  1. <template>
  2. <div id="product-list-one">
  3. <ul>
  4. <li v-for="(product,index) in saleProducts" :key="index">
  5. <span class="name">{
  6. {product.name}}</span>
  7. <span class="price">${
  8. {product.price}}</span>
  9. </li>
  10. </ul>
  11. </div>
  12. </template>
  13. <script> export default { computed:{ products(){ return this.$store.state.products; } }, } </script>
2、getters

getters用于获取数据。

  1. import Vue from 'vue'
  2. import Vuex from 'vuex'
  3. Vue.use(Vuex)
  4. export const store = new Vuex.Store({
  5. strict:true,
  6. state:{
  7. products:[
  8. { name:"马云",price:200},
  9. { name:"马化腾",price:140},
  10. { name:"马冬梅",price:20},
  11. { name:"马蓉",price:10}
  12. ]
  13. },
  14. getters:{
  15. saleProducts: (state) =>{
  16. var saleProducts = state.products.map(product =>{
  17. return {
  18. name: "**" + product.name + "**",
  19. price: product.price / 2
  20. };
  21. });
  22. return saleProducts;
  23. }
  24. }
  25. });

调用获取数据的方法。

  1. <template>
  2. <div id="product-list-one">
  3. <ul>
  4. <li v-for="(product,index) in saleProducts" :key="index">
  5. <span class="name">{
  6. {product.name}}</span>
  7. <span class="price">${
  8. {product.price}}</span>
  9. </li>
  10. </ul>
  11. </div>
  12. </template>
  13. <script> import { mapGetters} from 'vuex' export default { computed:{ ...mapGetters([ "saleProducts" ]) } } </script>
3、mutations

mutations用于变更state中的状态。

  1. import Vue from 'vue'
  2. import Vuex from 'vuex'
  3. Vue.use(Vuex)
  4. export const store = new Vuex.Store({
  5. strict:true,
  6. state:{
  7. products:[
  8. { name:"马云",price:200},
  9. { name:"马化腾",price:140},
  10. { name:"马冬梅",price:20},
  11. { name:"马蓉",price:10}
  12. ]
  13. },
  14. getters:{
  15. saleProducts: (state) =>{
  16. var saleProducts = state.products.map(product =>{
  17. return {
  18. name: "**" + product.name + "**",
  19. price: product.price / 2
  20. };
  21. });
  22. return saleProducts;
  23. }
  24. },
  25. mutations:{
  26. reducePrice: (state,payload) =>{
  27. state.products.forEach(product =>{
  28. product.price -= payload;
  29. })
  30. }
  31. }
  32. });

mutations更像是事件注册,所以需要我们需要store.commit()触发一下。

  1. <template>
  2. <div id="product-list-one">
  3. <ul>
  4. <li v-for="(product,index) in saleProducts" :key="index">
  5. <span class="name">{
  6. {product.name}}</span>
  7. <span class="price">${
  8. {product.price}}</span>
  9. </li>
  10. </ul>
  11. <button @click="reducePrice(2)">商品降价</button>
  12. </div>
  13. </template>
  14. <script> import { mapGetters} from 'vuex' export default { computed:{ products(){ return this.$store.state.products; }, ...mapGetters([ "saleProducts" ]) }, methods:{ reducePrice (n) { this.$store.commit('reducePrice',n); } } } </script>
4、actions
  • actions用于提交的是mutations,而不是直接提交状态。
  • actions可以包含任意异步操作。

    import Vue from ‘vue’
    import Vuex from ‘vuex’

    Vue.use(Vuex)

    export const store = new Vuex.Store({

    1. strict:true,
    2. state:{
    3. products:[
    4. { name:"马云",price:200},
    5. { name:"马化腾",price:140},
    6. { name:"马冬梅",price:20},
    7. { name:"马蓉",price:10}
    8. ]
    9. },
    10. getters:{
    11. saleProducts: (state) =>{
    12. var saleProducts = state.products.map(product =>{
    13. return {
    14. name: "**" + product.name + "**",
    15. price: product.price / 2
    16. };
    17. });
    18. return saleProducts;
    19. }
    20. },
    21. mutations:{
    22. reducePrice: (state,payload) =>{
    23. // setTimeout(function(){
    24. state.products.forEach(product =>{
    25. product.price -= payload;
    26. })
    27. // },3000);
    28. }
    29. },
    30. actions:{
    31. reducePrice:(context,payload) =>{
    32. setTimeout(function(){
    33. context.commit("reducePrice",payload); // context.commit()相当于 this.$store.commit(),触发mutations事件。
    34. },2000);
    35. }
    36. }

    });

需要用store.dispatch()触发actions,但是为了方便,我们这里使用mapActions

  1. <template>
  2. <div id="product-list-one">
  3. <ul>
  4. <li v-for="(product,index) in saleProducts" :key="index">
  5. <span class="name">{
  6. {product.name}}</span>
  7. <span class="price">${
  8. {product.price}}</span>
  9. </li>
  10. </ul>
  11. <button @click="reducePrice(2)">商品降价</button>
  12. </div>
  13. </template>
  14. <script> import { mapGetters} from 'vuex' import { mapActions} from 'vuex' export default { props:['msg'], data(){ return { txt:'hello' } }, computed:{ products(){ return this.$store.state.products; }, ...mapGetters([ "saleProducts" ]) }, methods:{ ...mapActions([ "reducePrice" ]) } } </script>

好了,这就是简单的Vuex入门,谢谢大家

发表评论

表情:
评论列表 (有 0 条评论,725人围观)

还没有评论,来说两句吧...

相关阅读

    相关 文章了解Netty

    Netty 传统的IO模型的web容器,比如老版本的Tomcat,为了增加系统的吞吐量,需要不断增加系统核心线程数量,或者通过水平扩展服务器数量,来增加系统处理请求的能力