vuex快速入门

简介: vuex快速入门

资料


Google浏览器怎么添加vue-devtools拓展工具


vuex-demo代码在github



Vuex 概述


1.1 组价之间共享数据的方式


父向子传值:v-bind 属性绑定


子向父传值:v-on 事件绑定


兄弟组件之间数据共享:EventBus


  • $on 接收数据的那个组件
  • $emit 发送数据的那个组件


1.2 Vuex 是什么

Vuex 是实现组件全局状态(数据)管理的一种机制,可以方便的实现组件之间数据的共享。

aHR0cHM6Ly9ub3RlLnlvdWRhby5jb20veXdzL3B1YmxpYy9yZXNvdXJjZS84OTQ0MTRlMmJiODJmZGM5YmEzMTMxNmJlMjc1NzI3Zi9GQzE1RjFDOTQ2NEM0ODNFQUVCNDlCNUMyNTU3NkJDMA.png


1.3、使用 Vuex 统一管理状态的好处


1、能够在 vuex 中集中管理共享的数据,易于开发和后期维护


2、能够高效地实现组件之间的数据共享,提高开发效率


3、储存在vuex中的数据都是响应式的,能够实时保持数据与页面的同步


1.4 什么样的数据适合存储到 Vuex 中

一般情况下,只有组件之间共享的数据才有必要存储到 vuex 中;对于组件中私有数据,依旧存储在组件自身的data中即可。



Vuex 的基本使用


1、安装 vuex 依赖包

npm install vuex --save


2、导入 vuex 包

import Vuex from 'vuex'
Vue.use(Vuex)


3、创建 store 对象

const store = new Vuex.Store({
    // state 中存放的就是全局共享的数据
    state: { count: 0 }
})


4、将 store 对象挂载到 vue 实例中

new Vue({
    el: '#app',
    render: h => h(app),
    router,
    // 将创建的共享数据对象,挂载到 Vue 实例中
    // 所有的组件,就可以直接从 store 中获取全局的数据了
    store
})


5、用可视化工具创建一个项目

可以看我之前我写的一篇笔记:怎么使用 vue ui 可视化工具创建一个项目


6、添加一个计数器 demo, 为实现演示 vuex 做准备

aHR0cHM6Ly9ub3RlLnlvdWRhby5jb20veXdzL3B1YmxpYy9yZXNvdXJjZS84OTQ0MTRlMmJiODJmZGM5YmEzMTMxNmJlMjc1NzI3Zi9CRjNBNjdGMkRGRjI0RkI4QjUyNkQ3ODREMDE4NTFGMg.png



1、修改 app.vue 文件

<template>
  <div>
    <my-addition></my-addition>
    <hr />
    <my-subtraction></my-subtraction>
  </div>
</template>
<script>
import Addition from './components/Addition.vue'
import Subtraction from './components/Subtraction.vue'
export default {
  data() {
    return {}
  },
  components: {
    'my-addition': Addition,
    'my-subtraction': Subtraction
  }
}
</script>


2、在 components 文件夹添加加法组件Addition.vue

<template>
  <div>
    <h3>当前最新的count值:</h3>
    <button>+1</button>
  </div>
</template>
<script>
export default {
  data() {
    return {}
  }
}
</script>



3、在 components 文件夹添加减法组件Subtraction.vue

<template>
  <div>
    <h3>当前最新的count值:</h3>
    <button>-1</button>
  </div>
</template>
<script>
export default {
  data() {
    return {}
  }
}
</script>


4、关于代码格式化的问题,使用 prettier 处理格式化问题,配置文件 .prettierrc

配置好后可以使用vscode的快捷键shift+alt+f

{
  "semi": false, // 不使用分号
  "singleQuote": true // 使用单引号
}

如果出现函数需要空格 eslint 报错,可以在 eslint 的配置文件的规则里添加space-before-function-paren关闭

module.exports = {
  root: true,
  env: {
    node: true
  },
  extends: ['plugin:vue/essential', '@vue/standard'],
  parserOptions: {
    parser: 'babel-eslint'
  },
  rules: {
    'space-before-function-paren': 0, // 0 = off, 1 = warn, 2 = error
    'no-console': process.env.NODE_ENV === 'production' ? 'warn' : 'off',
    'no-debugger': process.env.NODE_ENV === 'production' ? 'warn' : 'off'
  }
}




Vuex 的核心概念


3.1 核心概念的描述


Vuex 中的主要核心概念如下:


  • State
  • Mution
  • Action
  • Getter



3.2 State

State 提供唯一的公共数据源,所有共享的数据都要统一放到 Store 的 State 中进行存储。

// 创建store数据源,提供唯一公共数据
const store = new Vuex.Store({
    state: { count: 0 }
})


1、组件访问 State 中的数据的第一种方式

// this.$store.state.全局数据名称
this.$store.state.count


2、组件访问 State 中的数据的第二种方式

// 1、从 vuex 中按需导入 mapState 函数
import { mapState } from 'vuex'


通过刚才导入的mapState函数,将当前组件需要的全局数据。映射为当前组件的computed计算属性:

// 2、将全局数据,映射为当前组件的计算属性
computed: {
    ...mapState('count')
}



在加法组件里添加代码:

<template>
  <div>
    <h3>方法一:当前最新的count值:{{$store.state.count}}</h3>
    <h3>方法二:当前最新的count值:{{count}}</h3>
    <button>+1</button>
  </div>
</template>
<script>
import { mapState } from 'vuex'
export default {
  data() {
    return {}
  },
  computed: {
    ...mapState(['count'])
  }
}
</script>


效果如下:

aHR0cHM6Ly9ub3RlLnlvdWRhby5jb20veXdzL3B1YmxpYy9yZXNvdXJjZS84OTQ0MTRlMmJiODJmZGM5YmEzMTMxNmJlMjc1NzI3Zi8zM0Q3QjI5MjQ0Nzg0OUI0OTNGNTFCRDUwMTk0OTQ3Qw.png


3.3 Mutation

Mutation 用于变更 Store 中的数据。


  • 1、只有通过 mutation 变更 Store 数据,不可以直接操作 Store 中的数据
  • 2、通过这种方式虽然操作起来稍微繁琐一些,但是可以集中监控所有数据的变化

1、触发 mutations 的第一种方式

// 定义 Mutation
const store = new Vuex.Store({
    state: {
        count: 0
    },
    mutations: {
        add(state) {
            // 变更状态 
            state.count++
        }
    }
})


// 触发 mutation
methods: {
    handle() {
        this.$store.commit('add')
    }
}


可以触发 mutation 传递参数:

const store = new Vuex.Store({
    state: {
        count: 0
    },
    mutations: {
        addN(state,step) {
            // 变更状态 
            state.count += step
        }
    }
})


// 触发 mutation
methods: {
    handle() {
        this.$store.commit('add', 6)
    }
}



在加法组件里添加代码:

<template>
  <div>
    <h3>方法一:当前最新的count值:{{ $store.state.count }}</h3>
    <h3>方法二:当前最新的count值:{{ count }}</h3>
    <button @click="btnHandle1">+1</button>
    <button @click="btnHandle1N">+N</button>
  </div>
</template>
<script>
import { mapState } from 'vuex'
export default {
  data() {
    return {}
  },
  computed: {
    ...mapState(['count'])
  },
  methods: {
    btnHandle1() {
      this.$store.commit('add')
    },
    btnHandle1N() {
      this.$store.commit('addN', 6)
    }
  }
}
</script>


效果如下:

aHR0cHM6Ly9ub3RlLnlvdWRhby5jb20veXdzL3B1YmxpYy9yZXNvdXJjZS84OTQ0MTRlMmJiODJmZGM5YmEzMTMxNmJlMjc1NzI3Zi9BQUJDRUMwNjE3NzQ0MEFGODQ2QjA1MTYxOUIyNjdFRA.png

2、触发 mutations 的第二种方式

// 1、从 vuex 中按需导入 mapMutations 函数
import { mapMutations } from 'vuex'


通过刚才导入的 mapMutations 函数,将需要的mutations函数,映射为当前组件的 methods 方法:

// 2、将指定的 mapMutations 函数,映射为当前组件的methods方法
methods: {
    ...mapMutations(['add', 'addN'])
}


我们在减法组件里面实现

store里添加代码:

import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
export default new Vuex.Store({
  state: {
    count: 0
  },
  mutations: {
    add(state) {
      state.count++
    },
    addN(state, step) {
      state.count += step
    },
    sub(state) {
      state.count--
    },
    subN(state, step) {
      state.count -= step
    }
  },
  actions: {
  },
  modules: {
  }
})



<template>
  <div>
    <h3>方法一:当前最新的count值:{{ $store.state.count }}</h3>
    <h3>方法二:当前最新的count值:{{ count }}</h3>
    <button @click="btnHandle2">-1</button>
    <button @click="btnHandle2N">-N</button>
  </div>
</template>
<script>
import { mapState, mapMutations } from 'vuex'
export default {
  data() {
    return {}
  },
  computed: {
    ...mapState(['count'])
  },
  methods: {
    ...mapMutations(['sub', 'subN']),
    btnHandle2() {
      this.sub()
    },
    btnHandle2N() {
      this.subN(6)
    }
  }
}
</script>


效果如下:

aHR0cHM6Ly9ub3RlLnlvdWRhby5jb20veXdzL3B1YmxpYy9yZXNvdXJjZS84OTQ0MTRlMmJiODJmZGM5YmEzMTMxNmJlMjc1NzI3Zi80NjBCRDIzNTRBNUY0OTM1QkY3ODE5Rjc3RUQyM0Y2NA.png

3.4 Action

Action 用于处理异步任务。


如果通过异步操作变更数据,必须通过Action,而不能使用Mutation,但是在Action中还是要通过触发Mutation的方式去间接变更数据。

1、触发 actions 的第一种方式

// 定义 Action
const store = new Vuex.Store({
    // ...省略其他代码
    mutations: {
        add(state) {
            state.count++
        }
    }
    actions: {
        addAsync(context) {
            setTimeout(() => {
                context.commit('add')
            }, 1000)
        }
    }
})


// 触发Action
methods: {
    handle() {
        this.$store.dispatch('addAsync')
    }
}



触发actions异步任务时携带参数

// 定义 Action
const store = new Vuex.Store({
    // ...省略其他代码
    mutations: {
        addN(state, step) {
            state.count += step
        }
    }
    actions: {
        addNAsync(context, step) {
            setTimeout(() => {
                context.commit('addN', step)
            }, 1000)
        }
    }
})


// 触发Action
methods: {
    handle() {
        // 调用dispatch触发actions时携带参数
        this.$store.dispatch('addNAsync', 6)
    }
}



在加法组件里面添加代码

import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
export default new Vuex.Store({
  state: {
    count: 0
  },
  // 只有 mutations 中定义的函数,才有权利修噶 state 中的数据
  mutations: {
    add(state) {
      // 不要在mutations函数里,执行异步代码
      // setTimeout(() => {
      //   state.count++
      // }, 1000)
      state.count++
    },
    addN(state, step) {
      state.count += step
    },
    sub(state) {
      state.count--
    },
    subN(state, step) {
      state.count -= step
    }
  },
  actions: {
    addAsync(context) {
      setTimeout(() => {
        // 在 action 中,不能直接修改 state 中的数据
        // 必须通过 context.commit() 触发某个 mutation 才行
        context.commit('add')
      }, 1000)
    },
    addNAsync(context, step) {
      setTimeout(() => {
        context.commit('addN', step)
      }, 1000)
    }
  },
  modules: {
  }
})
<template>
  <div>
    <h3>方法一:当前最新的count值:{{ $store.state.count }}</h3>
    <button @click="btnHandle1">+1</button>
    <button @click="btnHandle2">+N</button>
    <button @click="btnHandle3">+1 Async</button>
    <button @click="btnHandle4">+N Async</button>
  </div>
</template>
<script>
export default {
  data() {
    return {}
  },
  methods: {
    btnHandle1() {
      this.$store.commit('add')
    },
    btnHandle2() {
      // commit的作用就是调用某个 mutation 函数
      this.$store.commit('addN', 6)
    },
    // 异步 + 1
    btnHandle3() {
      // dispatch 函数专门用来触发 actions
      this.$store.dispatch('addAsync')
    },
    btnHandle4() {
      this.$store.dispatch('addNAsync', 6)
    }
  }
}
</script>



点击异步的按钮就会出现延迟才会数据变化

aHR0cHM6Ly9ub3RlLnlvdWRhby5jb20veXdzL3B1YmxpYy9yZXNvdXJjZS84OTQ0MTRlMmJiODJmZGM5YmEzMTMxNmJlMjc1NzI3Zi85RDBGQkRCQTk3NEI0NEY2QjNFRDk2RTVCODZGN0YyQg.png


2、触发 actions 的第二种方式

// 1、从 vuex 中按需导入 mapActions 函数
import { mapActions } from 'vuex'



通过刚才导入的 mapActions 函数,将需要的 actions 函数,映射为当前组件的 methods 方法:

// 2、将指定的 mapActions 函数,映射为当前组件的methods方法
methods: {
    ...mapActions(['addAsync', 'addNAsync'])
}

我们在减法组件里添加代码

import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
export default new Vuex.Store({
  state: {
    count: 0
  },
  // 只有 mutations 中定义的函数,才有权利修噶 state 中的数据
  mutations: {
    add(state) {
      // 不要在mutations函数里,执行异步代码
      // setTimeout(() => {
      //   state.count++
      // }, 1000)
      state.count++
    },
    addN(state, step) {
      state.count += step
    },
    sub(state) {
      state.count--
    },
    subN(state, step) {
      state.count -= step
    }
  },
  actions: {
    addAsync(context) {
      setTimeout(() => {
        // 在 action 中,不能直接修改 state 中的数据
        // 必须通过 context.commit() 触发某个 mutation 才行
        context.commit('add')
      }, 1000)
    },
    addNAsync(context, step) {
      setTimeout(() => {
        context.commit('addN', step)
      }, 1000)
    },
    subAsync(context) {
      setTimeout(() => {
        context.commit('sub')
      }, 1000)
    },
    subNAsync(context, step) {
      setTimeout(() => {
        context.commit('subN', step)
      }, 1000)
    }
  },
  modules: {}
})



<template>
  <div>
    <h3>方法二:当前最新的count值:{{ count }}</h3>
    <button @click="sub">-1</button>
    <button @click="subN(6)">-N</button>
    <button @click="subAsync">-1 Async</button>
    <button @click="subNAsync(6)">-N Async</button>
  </div>
</template>
<script>
import { mapState, mapMutations, mapActions } from 'vuex'
export default {
  data() {
    return {}
  },
  computed: {
    ...mapState(['count'])
  },
  methods: {
    ...mapMutations(['sub', 'subN']),
    ...mapActions(['subAsync', 'subNAsync'])
  }
}
</script>


效果:

aHR0cHM6Ly9ub3RlLnlvdWRhby5jb20veXdzL3B1YmxpYy9yZXNvdXJjZS84OTQ0MTRlMmJiODJmZGM5YmEzMTMxNmJlMjc1NzI3Zi9GN0E2MjAxOTlEQUY0NzRGQUUzNjAxN0YzRjVBNjg2RQ.png


如果上面的vue-devtools插件里vuex的state不会自动更新的话需要自己设置一下开启就行了

aHR0cHM6Ly9ub3RlLnlvdWRhby5jb20veXdzL3B1YmxpYy9yZXNvdXJjZS84OTQ0MTRlMmJiODJmZGM5YmEzMTMxNmJlMjc1NzI3Zi8yODJCNkY4RTU0NDc0NjNCQUY2RUNENjY2QzhDNEE1MQ.png



3.5 Getter


Getter 用于对 Store 中的数据进行加工处理形成的新的数据。


  • 1、Getter类似vue的计算属性
  • 2、Store中数据的变化,Getter的数据也会发生变化



// 定义 Getter
const store = new Vuex.Store({
    state: {
        count: 0
    },
    getters: {
        showNum: state => {
            return `当前的新数据是【${state}】`
        }
    }
})



1、使用 getters 的第一种方式

// this.$store.getters.名称
this.$store.getters.showNum


2、使用 getters 的第二种方式

import { mapGetters } from 'vuex'
computed: {
    ...mapGetters(['showNum'])
}


在store文件里添加

import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
export default new Vuex.Store({
  state: {
    count: 0
  },
  // 只有 mutations 中定义的函数,才有权利修噶 state 中的数据
  mutations: {
    add(state) {
      // 不要在mutations函数里,执行异步代码
      // setTimeout(() => {
      //   state.count++
      // }, 1000)
      state.count++
    },
    addN(state, step) {
      state.count += step
    },
    sub(state) {
      state.count--
    },
    subN(state, step) {
      state.count -= step
    }
  },
  actions: {
    addAsync(context) {
      setTimeout(() => {
        // 在 action 中,不能直接修改 state 中的数据
        // 必须通过 context.commit() 触发某个 mutation 才行
        context.commit('add')
      }, 1000)
    },
    addNAsync(context, step) {
      setTimeout(() => {
        context.commit('addN', step)
      }, 1000)
    },
    subAsync(context) {
      setTimeout(() => {
        context.commit('sub')
      }, 1000)
    },
    subNAsync(context, step) {
      setTimeout(() => {
        context.commit('subN', step)
      }, 1000)
    }
  },
  getters: {
    showNum(state) {
      return `当前的getters数据是【${state.count}】`
    }
  }
})


在加法实现第一种

<template>
  <div>
    <h3>方法一:当前最新的count值:{{ $store.state.count }}</h3>
    <h3>getters:{{ $store.getters.showNum }}</h3>
    <button @click="btnHandle1">+1</button>
    <button @click="btnHandle2">+N</button>
    <button @click="btnHandle3">+1 Async</button>
    <button @click="btnHandle4">+N Async</button>
  </div>
</template>
<script>
export default {
  data() {
    return {}
  },
  methods: {
    btnHandle1() {
      this.$store.commit('add')
    },
    btnHandle2() {
      // commit的作用就是调用某个 mutation 函数
      this.$store.commit('addN', 6)
    },
    // 异步 + 1
    btnHandle3() {
      // dispatch 函数专门用来触发 actions
      this.$store.dispatch('addAsync')
    },
    btnHandle4() {
      this.$store.dispatch('addNAsync', 6)
    }
  }
}
</script>


在减法实现第二种

<template>
  <div>
    <h3>方法二:当前最新的count值:{{ count }}</h3>
    <h3>getters:{{ showNum }}</h3>
    <button @click="sub">-1</button>
    <button @click="subN(6)">-N</button>
    <button @click="subAsync">-1 Async</button>
    <button @click="subNAsync(6)">-N Async</button>
  </div>
</template>
<script>
import { mapState, mapMutations, mapActions, mapGetters } from 'vuex'
export default {
  data() {
    return {}
  },
  computed: {
    ...mapState(['count']),
    ...mapGetters(['showNum'])
  },
  methods: {
    ...mapMutations(['sub', 'subN']),
    ...mapActions(['subAsync', 'subNAsync'])
  }
}
</script>


效果如下:

aHR0cHM6Ly9ub3RlLnlvdWRhby5jb20veXdzL3B1YmxpYy9yZXNvdXJjZS84OTQ0MTRlMmJiODJmZGM5YmEzMTMxNmJlMjc1NzI3Zi82NTM2MjVBMzEyOUY0M0Q0ODQ4ODFCMjM1MEUyMUFDNg.png


目录
相关文章
|
JSON JavaScript 前端开发
快速入门Vue-2
快速入门Vue
55 0
|
Web App开发 JavaScript 前端开发
Vue快速入门
Vue (读音 /vjuː/,类似于 view) 是一套用于构建用户界面的渐进式框架。与其它大型框架不同的是,Vue 被设计为可以自底向上逐层应用。Vue 的核心库只关注视图层,不仅易于上手,还便于与第三方库或既有项目整合。另一方面,当与现代化的工具链以及各种支持类库结合使用时,Vue 也完全能够为复杂的单页应用提供驱动。
96 0
Vue快速入门
|
6月前
|
移动开发 JSON JavaScript
VUE2.0快速入门(二)
VUE2.0快速入门
50 2
|
6月前
|
缓存 JavaScript 前端开发
VUE2.0快速入门(一)
VUE2.0快速入门
76 0
|
11月前
|
存储 JavaScript 前端开发
vuex入门
vuex入门
59 0
|
缓存 JavaScript 前端开发
快速入门Vue-1
快速入门Vue
50 0
|
存储 JavaScript 前端开发
快速入门Vue-3
快速入门Vue
50 0
|
资源调度 JavaScript
vuex如何使用
Vuex是一个专为Vue.js设计的状态管理模式。它集中式管理了应用中所有组件的状态,使得状态管理更加简单和高效。下面是使用Vuex的基本步骤:
60 0
|
缓存 JavaScript 前端开发
快速入门Vue3(上)
快速入门Vue3(上)
108 0
|
缓存 JavaScript API
快速入门Vue3(下)
快速入门Vue3(下)
138 0
下一篇
无影云桌面