# 依赖注入
场景:属性透传在很多层结构的组件中用起来是很不方便的
- 通过依赖注入,可以跨域多层组件向其他的组件传递数据 —— 前提组件之间一定是父子关系
步骤:
- 设置依赖(
provide
)provide(name, value)
—— 名值对 - 注入数据 (
inject
)const value = inject(name, default)
子组件读取父组件设置的Provide
数据
取谁? —— 谁近取谁的 —— 类似于JS
的作用域
如果是一层结构的话,那用什么都可以,比如
props
,emits
,如果层级很多,好几层的结点,使用依赖注入就方便的多了
inject
如果用解构对象的方式来接收数据的话,那解构的变量名要与provide
中设置的对象名一致。
# 状态管理
状态(state
)
应用中的数据就是状态
- 状态提升 —— 实现兄弟组件或者没有关系的组件数据共享
store
—— 存储state
内容 —— 中央仓库 —— 存储公共状态
优点:不再限制数据(状态)必须在哪儿定义,等于单独把这个状态抽象出来了,在哪儿用就引用该文件即可
# Pinia
是 vue 自带的一个插件 官网 (opens new window) Pinia
就是一个状态管理库,实现了服务器渲染支持和HMR
,而且有更强的团队协作约定,由Vue
核心团队维护,对 vue2
和 vue3
都可以使用
使用pinia
/的步骤
- 安装
pinia
- 在
main.js
中引入createPinia()
- 通过
createPinia()
创建pinia
实例 - 将
pinia
配置为vue
的插件 ——app.use(pinia)
# store
useXxx —— 钩子函数
把其他组件或者插件中的变量,对象,函数钩到我们当前组件中,从而让我们使用
比如defineStore
,它本身是一个函数,我们调用defineStore()
,它会返回一个函数,我们用useXxx
的形式来接收这个函数,用的时候直接去调用useXxx
就可以访问store
中的内容,useXxx
就是一个钩子
pinia
管理的store
的基本结构如下
// 引入函数 defineStore()
import { defineStore } from "pinia";
// 通过函数来创建store —— useCountStore是一个函数
// defineStore("store的id", 配置对象) —— 返回的是一个函数
// 配置对象:state,是一个函数,将需要由pinia维护的数据以对象的形式返回
export const useCountStore = defineStore("count", {
// 数据
// 注意:state是个函数
state: () => ({
count: 100,
name: "猪八戒",
}),
// 计算属性
getters: {
double: (state) => state.count * 2,
},
// 方法属性
actions: {
increment() {
this.count++;
},
},
});
组合式store
类似于组合式api
—— (setup
)的写法 —— 这里就不重复记录了
store
实例本身就是一个reactive
对象,可以通过它直接访问state
中的数据,但是如果直接将state
中数据解构出来,那么数据将会丧失响应性
解决:可以通过storeToRefs()
来对store
进行解构,
storeToRefs()
可以将state
和getters
中的属性解构为ref
属性,从而保留其响应性
但不适用于action
属性
state
的修改:
- 直接修改
- 通过
$patch
(补丁) - 通过
$patch
传函数的形式的修改 - 直接替换
state
——$state
- 重置
state
——$reset
什么是补丁 —— 同时修改多个属性
store
的订阅 —— 当state
发生变化时,进行一些操作 —— 监听 —— $subscribe
stuStore.$subscribe(
(mutation, state) => {
// mutation 表示修改的信息
console.log(mutation.events); // 对象,包含修改前后内容的对比
console.log(mutation.type); // 修改方式的类型
// console.log(mutation.events[0] === mutation.events[1])
// console.log(mutation.payload)
// if(state.token){
// // 登录,向本地存储中添加内容
// }else{
// // 登出,从本地存储中移除内容
// }
// console.log("state发生变化了", state)
// 使用订阅时不要在回调函数中直接修改state
// state.age++
},
{ detached: true }
);
action
的订阅 —— $onAction
stuStore.$onAction(({ name, store, args, after, onError }) => {
/*
name 调用的action的名字
store store的实例
args action接收到的参数
after() 可以设置一个回调函数,函数会在action成功调用后触发
onError() 可以设置一个回调函数,函数会在action调用失败后触发
*/
after(() => {
console.log(name + "成功执行!");
});
onError((err) => {
console.log(name + "执行失败!", err);
});
});
# 杂
为什么要打包?
- 页面多次请求 —— 页面只请求一次,请求一个文件,然后在文件中相互引用
- 编译 ——
ES6
,sass
等高级语法转换为兼容性更强的语法
@
表示是组件的根目录
在HTML5
中,ID
可以以数字开头
rem
替换像素 —— 实现移动端的适配