vue学习记录九

2023/4/27 vuepinia

# 依赖注入

场景:属性透传在很多层结构的组件中用起来是很不方便的

  • 通过依赖注入,可以跨域多层组件向其他的组件传递数据 —— 前提组件之间一定是父子关系

步骤:

  1. 设置依赖(provideprovide(name, value) —— 名值对
  2. 注入数据 (injectconst value = inject(name, default)

子组件读取父组件设置的Provide数据

取谁? —— 谁近取谁的 —— 类似于JS的作用域

如果是一层结构的话,那用什么都可以,比如props, emits,如果层级很多,好几层的结点,使用依赖注入就方便的多了

inject 如果用解构对象的方式来接收数据的话,那解构的变量名要与provide中设置的对象名一致。

# 状态管理

状态(state应用中的数据就是状态

  • 状态提升 —— 实现兄弟组件或者没有关系的组件数据共享
  • store —— 存储state内容 —— 中央仓库 —— 存储公共状态

优点:不再限制数据(状态)必须在哪儿定义,等于单独把这个状态抽象出来了,在哪儿用就引用该文件即可

# Pinia

是 vue 自带的一个插件 官网 (opens new window) Pinia就是一个状态管理库,实现了服务器渲染支持和HMR,而且有更强的团队协作约定,由Vue 核心团队维护,对 vue2vue3都可以使用

使用pinia/的步骤

  1. 安装pinia
  2. main.js中引入createPinia()
  3. 通过createPinia()创建pinia实例
  4. 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()可以将stategetters中的属性解构为ref属性,从而保留其响应性 但不适用于action属性

state的修改:

  1. 直接修改
  2. 通过$patch(补丁)
  3. 通过$patch传函数的形式的修改
  4. 直接替换state ——$state
  5. 重置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);
  });
});

#

为什么要打包?

  1. 页面多次请求 —— 页面只请求一次,请求一个文件,然后在文件中相互引用
  2. 编译 —— ES6,sass 等高级语法转换为兼容性更强的语法

@表示是组件的根目录

HTML5中,ID可以以数字开头

rem替换像素 —— 实现移动端的适配

How to love
Lil Wayne