# 依赖注入
场景:属性透传在很多层结构的组件中用起来是很不方便的
- 通过依赖注入,可以跨域多层组件向其他的组件传递数据 —— 前提组件之间一定是父子关系
步骤:
- 设置依赖(
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替换像素 —— 实现移动端的适配
