vue3-声明周期

生命周期

  • beforeCreate、created 可以被setup取代掉
  • onMounted onBeforeMount 都变成了函数式API onMounted(()=>{})
  • onBeforeUpdate onUpdated

Vue3 Vue有些什么内容

vue3 = 【runtime-dom】+【runtime-core】+【reactivity】

  • 【compiler-dom】 + 【compiler-core】

组件嵌套,每个组件都有setup如何知道 setup里面的生命周期是隶属于哪个setup的 (闭包+科礼化)

让每个组件实例收集对应的钩子,这些钩子可以收集多个。一个实例可以收集多个钩子。

javascript 复制代码
runtime-core
    component.ts
        // 对外暴露的当前组件的实例
        export let currentInstance = null;
        // 设置当前组件的实例
        export let setCurrentInstance = (instance) => {
            currentInstance = instance;
        };
        // 获取当前组件的实例
        export let getCurrentInstance = () => { // 在setup期中获取到当前组件的实例的句柄
            return currentInstance;
        }
        setupStatefulComponent(instance){
            // 组件初始化的时候会调用setup
            // 在调用setup之前就知道当前是哪个组件把instance保留一下【组件实例】
            currentInstance = instance;
            const setupReult = xxxxx
            // 初始化完了清空
            currentInstance = null;
        }

创建自己的生命周期

为生命周期创建钩子

创建apishengmingzhouqi.ts

typescript 复制代码
// 定义一个enum
const enum shengming  {
    BEFORE_MOUNT = 'bm',
    MOUNTED = 'm',
    BEFORE_UPDATE='bu',
    UPDATED='u'
}
// 生成这些方法
import {currentInstance} from "./component.ts" 
// 上面定义的那个全局的currentInstance 这个可能不存在为啥因为有些钩子可能要在字组件执行完毕后才有,那个时候instance=null了;

// 比如onMounted 应该是拿自己的 instance因为有子组件所以就被充掉了 怎么解决用闭合包  target = instance

// 通过科礼化函数创建
export const onBeforeMount = createHook(shengming.BEFORE_MOUNT)
export const onMounted = createHook(shengming.MOUNTED)
export const onBeforeupdate = createHook(shengming.BEFORE_UPDATE)
export const onUpdated = createHook(shengming.UPDATED)

export const createHook = (type = '') => {
    return (hook = () => {}, target = instance) => { // target 用来标识它是哪个实例的,哪个组件的。闭包准确的知道当前组件的实例。
        // 给当前实例增加对应的生命周期
        // 给type这个生命周期,注入hook这个钩子,注入到target这个对象上
        injectHook(type, hook, target)
    }
}




const injectHook = (hookName = '', userFunc = () => {}, target = null) => {
    if(target) {

        // 给当前的实例上挂上这么个钩子
        // 因为可能重复写都要放到数组里面去
        const funcs = target[hookName] || (target[hookName] = []);

        const wrap = () => { // 为了用闭包数据
            setCurrentInstance(target); // currentInstace就变成当前这个的了。每次调用钩子只用当前闭包里面的这个当前实例
            // 在这里改了
            userFunc.call(target); // 在这里用 getCurrentInstance 就可以拿到当前组件实例。
            setCurrentInstance(null); // 调用完了在复位。
            // 在components 内部执行完了setup就清空了 currentInstance 
        }

        funcs.push(wrap); 

    } else {
        // 抛出异常
        console.warn("error.......")
    }
}


// 父的
import {getCurrentInstance} = vue;
onMounted(()=>{
    // 这里的这个实例是谁?
    // 在这里拿到的currentInstance对不对如果有子组件就不对了被充了。这里也没有闭包。这里的是儿子。
    // 为了解决这个问题需要在component.ts在提供2个方法转到上面get set

    // 拿到了组件的实例
    const ci = getCurrentInstance();
})

// vue的代码用科礼化用的多
javascript 复制代码
// 都绑定在组件了该如何调用他们?
apishengmingzhouqi.ts
// 执行该声明周期上的所有钩子函数。
export const invokeArrayFns = (fns) => {
    fns.forEach(item => {
        item();
    })
}

在哪里用?

scss 复制代码
// renderer.ts
setupRenderEffect 中用 // 第一次渲染。
if(!instance.isMounted){
    const {bm, m} =  instance // 因为初始化的时候已经在setup执行了

    if(bm) {
        invokeArrayFns(bm);
    }
    
    patch完毕了 // 这里不能保证子组件的执行完毕
    // 这里会有问题
    // 啥问题?

    if(m) { // mounted要求子组件都执行完毕。 这个玩意需要延迟到子组件执行完毕了。
        invokeArrayFns(m);
    }
    
} else {
    
    const {bu, u} =  instance
    if(bu){
        invokeArrayFns(bu);
    }

    patch(...)更新
    // 更新也是这么个事如果更新怎么知道子组件也完成了。
    if(u){
        invokeArrayFns(u);
    }
}

// 这里没有考虑子组件
相关推荐
蜗牛快跑2135 分钟前
面向对象编程 vs 函数式编程
前端·函数式编程·面向对象编程
Dread_lxy6 分钟前
vue 依赖注入(Provide、Inject )和混入(mixins)
前端·javascript·vue.js
涔溪1 小时前
Ecmascript(ES)标准
前端·elasticsearch·ecmascript
榴莲千丞1 小时前
第8章利用CSS制作导航菜单
前端·css
奔跑草-1 小时前
【前端】深入浅出 - TypeScript 的详细讲解
前端·javascript·react.js·typescript
羡与1 小时前
echarts-gl 3D柱状图配置
前端·javascript·echarts
guokanglun1 小时前
CSS样式实现3D效果
前端·css·3d
咔咔库奇1 小时前
ES6进阶知识一
前端·ecmascript·es6
渗透测试老鸟-九青2 小时前
通过投毒Bingbot索引挖掘必应中的存储型XSS
服务器·前端·javascript·安全·web安全·缓存·xss
龙猫蓝图2 小时前
vue el-date-picker 日期选择器禁用失效问题
前端·javascript·vue.js