前言:今日课程准备
- 1.新建一个脚手架项目: 01-vuex
- 2.添加路由router和vuex
- 如果创建脚手架的时候没有勾选,可以分别在根目录执行两个命令进行安装
- vue add router
- vue add vuex
- 如果创建脚手架的时候没有勾选,可以分别在根目录执行两个命令进行安装
- 3.创建三个页面: home.vue my.vue TodoList.vue , 并且配置好对应路由
- 可以直接从课程资料复制过来
- 4.今日学习路由
- 在home.vue 和 my.vue中我们将会学习vuex几乎所有的语法
- 综合案例:使用vuex重构我们第三天的案例TodoList
01-vuex全局数据管理(vue全家桶04)
vue全家桶 = axios(网络请求) + vueRouter(路由单页面应用) + vueCli(脚手架) + vuex(全局数据管理) + vant移动端布局(PC端elementUI)
- 官网文档:https://vuex.vuejs.org/zh/
- vuex作用:实现
所有组件
间的数据共享
- 本章节学习目标
- 了解vuex的应用场景 (在哪用)
- 掌 么用)
1.1-vuex介绍
回顾组件关系和通信方案
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-AwXB64bq-1664019534533)(day07.assets/image-20210323175925844.png)]
序号 | 组件关系 | 数据通信 |
---|---|---|
1 | 父子关系 | 子传父:$emit ; 父传子:props |
2 | 非父子关系 | eventBus: $on + $emit |
3 | 非父子关系 | vuex |
和我们已经学过的父子通信和兄弟通信类似,vuex也是一种组件通信解决方案
1.1.1-组件传值的几种方式
-
1.在现代化开发中,组件化已经成为主流开发了。
-
2.每一个组件的数据是
独立
的, 每个组件有着自己的状态(数据) -
3.在实际开发中,一个组件需要访问另一个组件中的数据是非常常见的。这时候需要进行组件通讯。
-
常见的组件通讯
- 父传子
props
单向数据流
- 子传父
$emit
事件通知
- 兄弟组件传值(了解即可,现在基本处于废弃状态):event bus 通用组件通讯的解决方案
- 父传子
1.1.2-为什么要有vuex
- 1.vuex的作用是解决多组件状态共享的问题,在大型的项目中,组件通讯会变得很混乱,使用vuex可以统一管理组件之间的通讯
- 它是
独立于组件
而单独存在的,所有的组件都可以把它当作一座桥梁来进行通讯。
- 它是
- 2.使用vuex好处
响应式
: 只要vuex中的数据变化,对应的组件会自动更新(类似于vue数据驱动)- 操作更简洁 : 类似于sessionStorage,只有几个方法
1.1.3-vuex使用场景
实际开发中,组件传值大多数情况下还是使用 父子组件传值
少部分情况下会用vuex. (数据需要在非常多的页面使用,比如用户头像,好几个页面都要显示那种)
- 1.不是所有的场景都适用于vuex,只有在必要的时候才使用vuex,如果
不必要,尽量别用
- 使用了vuex之后,会一定程度上增加了项目的复杂度
- 2.适合使用vuex场景
- 这个数据需要在
很多个地方使用
,如果采用组件传值方式,写起来很麻烦,而且多个地方都要写- 例如:用户信息(姓名,头像),可能会在很多个地方使用(个人页面,评论页面等)
- 这个数据需要在
- 3.不适合使用vuex场景
- 这个数据
不需要多个地方使用
,如果某个数据仅仅只是在两个组件之间通讯
,优先使用props或$emit
- 这个数据
- 4.vuex特点
- (1)所有组件数据共享
- (2)响应式: 一旦vuex数据修改,所有使用的地方都会自动更新
知识点验收
- 1.vuex作用
- 所有组件,共享数据
- 2.vuex场景 : (思考:是不是有了vuex,以前的父子组件传值就没有用呢?)
- vuex会增加项目复杂程度,如果不需要使用,尽量不要用
- vuex使用场景 : (1)多个组件都需要使用的数据:
共享
(2)组件传值比较麻烦(不是父子关系) - vuex不推荐场景 : (1)数据不需要在多个组件使用:
不共享
(2)组件传值比较容易(父子传值)
1.2-vuex使用流程
使用步骤:
vue-cli
中整合==(如果使用vue ui创建创建,直接勾选vuex,会自动帮我们完成配置)==vue add vuex
- 如果提示,选择
y
- 创建了
/src/store/index.js
main.js
导入并挂载到Vue
实例上
- 如果提示,选择
state
中定义数据
- 任意组件中
this.$store.state.xxx
即可取值
和改值
template
中可以不用写this
- 可以通过计算属性简化编码
.js
文件中- 导入
store
对象即可获取属性
- 导入
注意:
- 在
vue-cli
创建的项目中如何整合vuex
vue add vuex
vuex
的数据定义在哪里?state
- 组件中如何获取
vuex
中的数据?this.$store.state.xxx
- html结构中
this
可以省略
1.3-vuex核心概念-state
-
state作用: 存储公共数据
-
./vuex/index.js
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
export default new Vuex.Store({
//1.state作用:存储数据
state: {
user:{
name:'ikun',
age:30
}
},
getters: {
},
mutations: {
},
actions: {
},
modules: {
}
})
- home.vue
- my.vue也可以使用vuex数据哟
<template>
<div>
<h1>首页</h1>
<button>点我修改vuex数据</button><br>
<button>点我发送ajax请求</button>
<div>
<h2>个人信息</h2>
<p>我的名字是:{
{ $store.state.user.name }}</p>
<p>我的年龄是:{
{ $store.state.user.age }}</p>
</div>
<div>
<h2>图书管理信息</h2>
<ul>
<li></li>
</ul>
</div>
</div>
</template>
<script>
export default {
name:'home',
}
</script>
<style scoped>
p{
color:red;
}
</style>
1.4-getters派生状态(计算属性)
-
语法如下
- 1.现在getters中声明一个计算属性
-
new Vuex.store({ // 省略其他... getters: { // state 就是上边定义的公共数据state 计算属性名: function(state) { return 要返回的值 } } })
-
2.使用getter中的计算属性
-
$store.getters.getter的名字
-
-
./vuex/index.js
-
import Vue from 'vue' import Vuex from 'vuex' Vue.use(Vuex) export default new Vuex.Store({ //1.state作用:存储数据 state: { user:{ name:'ikun', age:30 } }, /* 2.2.getter作用: 官方术语:从state中派生状态(使用state中的数据,计算得出一些新数据) 说人话: 相当于state的计算属性 */ getters: { getInfo(state){ //state:就是vuex上面的state return `我是${ state.user.name},我今年${ state.user.age}岁了` } }, //2. mutations: { }, actions: { }, modules: { } })
-
home.vue
-
<div> <h2>个人信息</h2> <p>我的名字是:{ { $store.state.user.name }}</p> <p>我的年龄是:{ { $store.state.user.age }}</p> <p>自我介绍:{ { $store.getters.getInfo }}</p> </div>
1.5-vuex核心概念- Mutations
-
1.Mutation作用:更新state中的数据
- 疑问?: 既然可以直接通过
this.$store.state
来修改,为什么不能这么写呢? - 原因: 在组件中直接state,我们的
vue tools
不会追踪数据的修改,这样不便于维护(不知道这个全局数据什么时候被修改了,再加上vuex是全局响应式的,一旦修改所有使用的地方全部修改。非常不便于维护)- 另外:在严格模式下,直接修改state会报错
- 疑问?: 既然可以直接通过
-
2.Mutation语法如下:
-
分两个格式: 注册的格式,调用的格式
-
定义格式: 如下
new Vue.store({ // 省略其他... mutations:{ // 每一项都是一个函数,可以声明两个形参 mutation名1:function(state [, 载荷]) { }, mutation名2:function(state [, 载荷]) { }, } })
- 每一项都是一个函数,可以声明两个形参:
- 第一个参数是必须的,表示当前的state。在使用时不需要传入
- 第二个参数是可选的,表示载荷,是可选的。在使用时要传入的数据
- 专业术语载荷:表示额外的参数
- 每一项都是一个函数,可以声明两个形参:
-
使用格式
this.$store.commit('mutation名', 载荷实参 )
-
-
./vuex/index.js
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
export default new Vuex.Store({
//1.state作用:存储数据
state: {
user:{
name:'ikun',
age:30
}
},
/* 2.2.getter作用:
官方术语:从state中派生状态(使用state中的数据,计算得出一些新数据)
说人话: 相当于vuex的计算属性
*/
getters: {
getInfo(state){
//state:就是vuex上面的state
return `我是${
state.user.name},我今年${
state.user.age}岁了`
}
},
//3.mutations作用:修改state中的数据
mutations: {
setUser(state,newData){
state.user = newData
}
},
actions