文章目录
vuex
vuex是vue的状态管理工具,状态即数据。状态管理就是集中管理vue中通用的一些数据
注意:
不是所有的场景都适用于vuex,只有在必要的时候才使用vuex
使用了vuex之后,会附加更多的框架中的概念进来,增加了项目的复杂度(数据的操作更便捷,数据的流动更清晰)
总结:
1、vuex 能解决 多组件共享数据 的问题, 非常方便便捷
2、什么样的数据, 适合存放到vuex? 多组件的 通用 的共用数据, 适合存到 vuex
优势:
响应式变化
操作简洁 (vuex提供了一些简化语法的辅助函数, 这些辅助函数, 需要熟练掌握)
创建空仓库
新建store/index.js,用来写仓库相关的逻辑
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
// 创建仓库实例
const store = new Vuex.Store()
export default store
main.js中引入store,并使用
import store from '@/store'
state 状态 存放数据
State提供唯一的公共数据源,所有共享的数据都要统一放到Store中的State中存储。
const store = new Vuex.Store({
// state 状态,可以用于提供数据,类似vue组件中的data(data是组件自己的私有数据,state是整个项目组件的共享数据)
state: {
count: 100
}
})
拿数据方法:
组件实例范围,this指向vue实例的情况 => this.$store
普通js环境,this不指向vue实例 => 引包,store
<h1>根组件-{{ $store.state.count }}</h1>
推荐写在计算属性中:
computed: {
count () {
return this.$store.state.count
}
},
辅助函数 - mapState
只能在组件内,没有computed的话就不能用
帮助我们把store中的数据映射到 组件的计算属性中, 它属于一种方便的用法
<h1>根组件-{{ count }}</h1>
import { mapState } from 'vuex'
computed: {
title () {
return '标题'
},
// 将mapState生成的对象展开,作为computed的子属性
...mapState(['count'])
},
mutations 存放操作数据的方法(改数据) 同步更新数据
vuex的数据只有vuex能改,不要在vuex mutation之外修改数据
vuex同样遵循单向数据流
不可以直接在组件中直接修改(this.$store.state.count++)
在store中可以开启严格模式:strict : true
,直接修改会报错
(规范化代码操作,对于不规范的vuex数据操作,会报错;默认不开启,会消耗监听性能)
定义mutations
// addOne就是一个mutation函数,修改数据的方法
// mutation函数的第一个形参是state状态
// 第二个参数 payload,可以接收到提交时携带的参数,但只能携带一个参数
mutations: {
addOne (state) {
state.count++
},
addN (state, payload) {
state.count += payload
}
}
修改数据
methods: {
add () {
// 提交调用mutation函数的语法
// this.$store.commit('mutation名字',额外传参)
this.$store.commit('addOne')
},
addN (value) {
this.$store.commit('addN', value)
}
}
辅助函数 - mapMutation
<button @click="addOne">值+1</button>
<button @click="addN(2)">值+2</button>
methods: {
...mapMutations(['addOne', 'addN']) //相当于往methods里面新增一个函数addOne
}
文本框-同步数据并支持文本框内修改值
v-model等同于 :value + @input
changeCount (state, payload) {
state.count = payload
}
<input type="text" :value="count" @input="handleInput">
handleInput (e) {
this.$store.commit('changeCount', +e.target.value)
}
//或者
...mapMutations(['changeCount']),
handleInput (e) {
this.changeCount(+e.target.value)
}
actions
只能提交mutation,不能直接修改数据,它负责异步更新数据
// 在所有actions函数中,第一个参数是ctx 上下文对象 (指代仓库)
actions: {
addWaitTime (ctx, payload) {
setTimeout(() => {
ctx.commit('addN', payload) //利用mutations的addN方法修改
}, 3000)
}
}
<button @click="addWaitTime(5)">值+5 -- 3s后</button>
...mapActions(['addWaitTime'])
或
<button @click="fn(5)">值+5 -- 3s后</button>
fn () {
this.$store.dispatch('addWaitTime', 5)
}
getters
存放基于state的一些计算属性
getters: {
listLength (state) {
return state.list.length
}
}
<p>listLength: {{listLength}}</p>
...mapGetters(['listLength'])
//或
<p>listLength: {{$store.getters.listLength}}</p>
模块 module 拆分不同模块
新建文件 store/modules/user.js
// user模块 => 导出一个对象,对象包含user模块的所有配置
export default {
namespaced: true,
state: { //子模块推荐,使用工厂函数,返回一个对象数据(类似data)
username: '张三',
gender: '男',
token: 'abacdsdgfad'
},
mutations: {
setUserName (state, payload) {
state.username = payload
}
},
actions: {},
getters: {
bigName (state) {
return '法外狂徒' + state.username
}
}
}
在index.js中导入使用
import user from './modules/user'
modules: {
user
}
使用state: 数据在user.username
<p>{{$store.state.user.username}}</p>
//或
<p>{{username}}</p>
// ...mapState(模块名, ['属性名'])
...mapState('user', ['username'])
使用getters: 数据在user/bigName
<p>{{bigName}}</p>
...mapGetters('user', ['bigName'])
//或
<p>{{$store.getters['user/bigName']}}</p>
使用mutations
<button @click="changeFn">修改user/username</button>
changeFn () {
this.$store.commit('user/setUserName', '李四')
}
//或
...mapMutations('user', ['setUserName']),
changeFn () {
this.setUserName('李四')
}
准备后端接口服务环境(了解)
在项目根目录yarn serve启动的是前端代码,在db中启动的是后端代码,这两个窗口都不能关
1、安装全局工具 json-server (全局工具仅需要安装一次)
yarn global add json-server 或 npm i json-server -g
2、代码根目录新建一个 db 目录
3、将 index.json 移入 db 目录
4、进入 db 目录,执行命令,启动后端接口服务
json-server index.json
查询:
接口地址:http://localhost:3000/cart
请求方式:get
修改(部分)
接口地址:http://localhost:3000/cart/:id
请求方式:patch
请求参数:传个对象,对象的键,就是要修改的键