开始之前
前面章节中使用vue-cli脚手架
创建项目时候,会根据文章性质去安装对应的工具包,本章节会带着大家一起了解vuex语法
的内容,所以我们还是需要创建一个新的项目,在创建项目的过程中,把上一章节的vue-router
和本章节所需要的vuex
工具都一起安装,这样项目里面就会出现对应的目录和引用内容,可以很方便我们做一些扩展和学习。
- 在安装的时候,我们将
Router和Vuex
都选择上,就会在最后一起安装到项目中了。
main.js
- 在
main.js
中除了会有router路由
的引用之外,还多了一个store
的引用。
store
就是一个全局的仓库,也是Vuex
提供给我们使用的一个仓库。
store
👉 打开store目录
下面的index.js
createStore
就是创建一个仓库,通过vuex
解构出来的方法。
- 创建仓库的时候,会有几个 固定的对象。
Vuex
❓ 在项目中我们为什么要去用Vuex
呢
我们可以把
Vuex
理解为一个数据管理框架。
前面的章节中我们一起学过在vue里面如何管理数据的内容,可以使用
父子组件传递参数
、还可以使用provide和inject
的方式跨越组件层级去传递参数。但是当我们的项目越来越大,越来越复杂之后,有可能不是组件之间传递数据了,而是页面之间去传递数据或者修改数据。
比如在A页面有一个数据,在B页面也需要显示一样的数据,当B页面里面的数据修改之后,A页面的数据也同样被修改成相同的数据值。亦或者是十几个页面甚至几十个页面都需要共用一些数据,这时候不管是用组件传值还是跨越层级的方式传值的方式,都不是特别适合了,这时候就要使用Vuex数据管理框架了。
state
👉还是打开store目录
下面的index.js
🔥 createStore
创建的是一个全局唯一
的仓库,用来存放全局的数据。
import { createStore } from 'vuex' export default createStore({ state: { name: '蜡笔小心_' }, getters: { }, mutations: { }, actions: { }, modules: { } }) 复制代码
state
就是vuex
创建的仓库中用来存放全局数据的地方。
❓在state
里面写了一个全局的数据值name
之后,页面上如何去使用这个全局的数据呢
export default { name: 'HomeView', computed: { name () { return this.$store.state.name } } } 复制代码
- 在
HomeView
页面中,使用computed计算属性
来定义一个name
,并返回全局数据。
- 当我们在
main.js
中引用store
之后,就可以用this.$store
来使用store
仓库中的数据了。
<template> <div class="home"> <img alt="Vue logo" src="../assets/logo.png"> <h1>{{name}}</h1> </div> </template> 复制代码
- 在模板标签下面定义了一个
h1标签
来输出计算属性返回的name
。
- 打开页面之后就会在根路由看到输出的
name
,而About页面
就不会显示name
。
🎁 如果要在About
里面也显示出来就可以把计算属性直接复制过去就可以了。
<template> <div class="about"> <h1>This is an about page</h1> <h1>{{name}}</h1> </div> </template> <script> export default { name: 'AboutView', computed: { name () { return this.$store.state.name } } } </script> 复制代码
修改state中的数据
🌀上面我们定义了数据,也可以在各个页面去使用了,但是想要修改的话,是不是也可以直接用获取name
的方式去修改呢?
<template> <div class="home"> <img alt="Vue logo" src="../assets/logo.png"> <h1>{{name}}</h1> <button @click="handelClick">修改</button> </div> </template> <script> export default { name: 'HomeView', computed: { name () { return this.$store.state.name } }, methods: { handelClick () { this.$store.state.name = '修改后的名字' } } } </script> 复制代码
- 在
HomeView页面
中添加了一个按钮点击事件,用来触发修改name
的数据值。
🚫 虽然这种方式是可以直接修改state中定义的全局数据,但是vuex官方是不建议我们这样修改的。
⭕️ 因为当项目中的页面越来越多的时候,使用某一个全局数据的地方也会越来越多,这时候我们去修改了全局数据之后,vuex是无法追踪到这个变量的,也就无从得知是在何时何地修改的这个全局数据了。
🔆 为了更好的管理全局数据,我们就需要严格遵循官方文档中推荐的方式去处理数据。
mutations
创建仓库的时候,会自动生成一个mutations
的对象,这个对象就是vuex
提供给我们修改state
中的数据的。
mutations: { changeName (state) { state.name = 'mutations - changeName' } } 复制代码
- 在
mutations
中创建一个changeName函数
,接收的参数是存储全局数据的state
,通过这个参数就可以获取到定义的全局数据。
handelClick () { this.$store.commit('changeName') } 复制代码
- 将
HomeView
中的点击事件函数中直接修改全局数据的地方改成commit
的方式。
commit
中定义的是mutations
下面的函数名称。
- 使用
commit
的方式同样可以修改全局数据的值。
🌀 但是这样修改的值是在mutations
中写死的值,那我们是不是可以通过传参的方式让mutations
接收参数之后动态修改state
中的数据呢?
handelClick () { this.$store.commit('changeName', '传递过来的值') } 复制代码
- 在
commit
中第二个参数就是用来传递给仓库中接收的。
mutations: { changeName (state, data) { state.name = data } } 复制代码
mutations
下面的函数中同样也会接收到第二个参数,就是commit
传递过来的数据了。
上面使用的修改全局数据的方式,修改
HomeView页面
的数据之后均可在AboutView
中直接看到效果哦。
actions
🌀 上面使用到的mutations
修改全局数据的方式仅适用于静态数据直接去修改,如果需要异步修改数据或者调用接口来修改数据的话,就要用到actions
了。
actions: { changeName (store, data) { setTimeout (() => { store.commit('changeName', data) }, 2000) } } 复制代码
- 在
actions
中同样定义一个修改name
的方法,接收两个参数。
- 第一个参数表示当前仓库。
- 第二个参数表示接收到的数据值。
- 在
actions
里面使用了一个setTimeout函数
来作为异步执行修改全局数据的方式。
setTimeout函数
中执行的就是mutations
中使用过的commit
方式。
- 通过
commit
方式才能去调用mutations
中的函数。
handelClick () { this.$store.dispatch('changeName', '2秒之后改变数据') } 复制代码
- 在点击事件函数中就不能直接使用
commit
去修改了。
- 就要用到一个新的方式:
dispatch
来调用actions
中的异步函数。
顺带的axios异步修改全局数据
👆 首先需要在当前项目中安装一下axios插件
。
npm install axios --save
✌️ 然后在store仓库
中引用axios
。
import axios from 'axios'
👌 最后我们在actions
中使用axios
调用一个接口并将接口返回的数据赋值给全局数据。
actions: { changeName () { axios.get('API接口').then(response => { console.log(response) }) } } 复制代码
- 点击修改按钮时,接口请求成功了,并返回了
response
数据。
- 那我们就可以将返回数据赋值给
state
中的name
。
actions: { changeName (store) { axios.get('API接口').then(response => { store.commit('changeName', response.data.desc) }) } } 复制代码
🎁 作为一个前端使用ajax
请求接口是最基本的了,所以这里不细讲axios
了,需要学习axios
具体的使用方式大家可以参考axios官方文档进行学习。
compositionAPI中使用vuex
<script> import {toRefs} from 'vue' import {useStore} from 'vuex' export default { name: 'HomeView', setup () { const store = useStore() const { name } = toRefs(store.state) const handelClick = () => { store.commit('changeName', 'compositionAPI中使用vuex') } return { name, handelClick } }, } </script> 复制代码
- 通过
compositionAPI
使用vuex
的时候,需要从vuex
中解构出一个新的方法:useStore
- 除了
useStore
之外,其他的使用方式都和以前compositionAPI
的内容一致。
- 这里我使用的是
commit
方式直接修改全局数据的值,大家可以试试dispatch
的方式去修改哦~
总结
本篇文章内容比较多,对于刚接触vuex
的会比较复杂,所以大家在学习的过程中可以通过各种例子去巩固vuex
的思想。
由于vuex
的内容必须要这样写,也比较绕,只能靠大家死记硬背的方式去熟悉这里面的方法。
vuex
中还有几个方法在本篇文章中没有体现出来,会在后面的实战内容中结合具体项目来实现。