好家伙,

 

1.使用场景

现在来,来想一下,作为一个使用Vue的开发者,假设现在我们要使用created(),我们会如何使用

1.1.  .vue文件中使用

<template>
<div>
<h1>{{ message }}</h1>
</div>
</template> <script>
export default {
created() {
this.message = 'Hello, created() in single file component!';
},
data() {
return {
message: ''
};
}
};
</script>

 

1.2.    Vue实例中使用

<!DOCTYPE html>
<html>
<head>
<title>Vue created() example</title>
</head>
<body>
<div id="app">
<h1>{{ message }}</h1>
</div> <script src="https://cdn.jsdelivr.net/npm/vue@2.6.14"></script>
<script>
new Vue({
el: '#app',
data: {
message: ''
},
created() {
this.message = 'Hello, created() in Vue instance!';
}
});
</script>
</body>
</html>

 

 

1.3.   混入

 Vue.Mixin({ //全局
created:function a(){
console.log('a----1')
}
})

 

那么如果我这样去定义

<script>
Vue.Mixin({ //全局
created:function a(){
console.log('a----1')
}
})
Vue.Mixin({ //全局
created:function b(){
console.log('b----2')
}
})
let vm = new Vue({
el: '#app', //编译模板
// data: {
// },
data() {
// console.log(this)
return {
msg: 'hello',
a: {
b: 99
},
list: [1, 2, 3],
arr: [{
a: 1
}]
}
},
created(){
console.log(555)
}
}) </script>

是否会报错呢?

答案是不会

对于created()钩子函数,在每个Vue实例创建时,会依次执行全局混入函数中定义的created()方法和实例本身定义的created()方法。

当Vue实例被创建时,它会先执行全局混入函数的对应生命周期钩子函数,然后再执行实例本身的生命周期钩子函数。

因此,在你的代码中,全局混入函数中的created()会在实例的created()之前执行,且会按照它们在全局混入函数中的定义顺序执行

这样的设计允许开发者在多个地方定义相同的生命周期钩子函数,以实现不同的功能扩展和逻辑处理。

同时,由于生命周期钩子函数的执行顺序已经确定,开发者可以根据需要合理安排代码逻辑

 

最后,也说明,created()定义的方法被合并处理了,所以我们要把这个"合并"实现

 

 

2.项目上下文

老样子,先看看项目更新了哪些东西

代码已开源https://github.com/Fattiger4399/analytic-vue.git

 

 

2.1.Vue入口文件index.js中

添加全局方法

 

2.2. global-api/index.js

import { mergeOptions } from "../utils/index"

export function initGlobApi(Vue) {
//源码
//Vue.options ={created:[a,b,c],watch:{a,b}}
Vue.options ={}
Vue.Mixin = function (mixin) { // {}
//源码
//{created:[a,b,c],watch:[a,b]}
//对象的合并
console.log(999)
this.options = mergeOptions(this.options,mixin)
console.log(Vue.options,"||this is vue.options")
}
}

此处涉及我们的核心方法mergeOptions

这方法要实现一个怎么样的效果?

 Vue.Mixin({ //全局
created: function a() {
console.log('a----1')
}
})
Vue.Mixin({ //全局
created: function b() {
console.log('b----2')
}
})
let vm = new Vue({
el: '#app', //编译模板
// data: {
// },
data() {
// console.log(this)
return {
msg: 'hello',
a: {
b: 99
},
list: [1, 2, 3],
arr: [{
a: 1
}]
}
},
created() {
console.log(555)
}
})

将上述所有与created()有关的方法

最后合并到一个对象当中去

 

3.核心方法

3.1.utils/index.js

来到我们全篇最核心也是最难的部分

//对象合并 {created:[]}
export const HOOKS =[
"beforeCreated",
"created",
"beforeMount",
"mounted",
"beforeUpdate",
"updated",
"beforeDestory",
"destroyed",
]
// 策略模式
let starts ={}
starts.data =function(parentVal,childVal){
return childVal
} //合并data
starts.computed =function(){} //合并computed
starts.watch =function(){} //合并watch
starts.methods =function(){} //合并methods
//遍历生命周期
HOOKS.forEach(hooks=>{
starts[hooks] = mergeHook
}) function mergeHook(parentVal,childVal){
if(childVal){
if(parentVal){
//把子元素合并进去
return parentVal.concat(childVal)
}else{
return [childVal] //[a]
}
}else{
return parentVal
}
} export function mergeOptions(parent, child) {
console.log(parent,child,'||this is parent and child in mergeOptions()')
const options ={}
//判断父亲
for(let key in parent){
console.log(key,'||this is key') mergeField(key)
}
//判断儿子
for(let key in child){
console.log(key,'||this is key')
mergeField(key)
}
function mergeField(key){
//根据key 策略模式
if(starts[key]){ //created {created:[a]}
options[key] =starts[key](parent[key],child[key])
}else{
options[key] = child[key]
}
}
return options
}

 

前端设计模式之策略模式 - 掘金 (juejin.cn)

这玩意要看懂,必须先把这玩意学了,策略模式

一句话概括策略模式是一种行为型设计模式,它允许在运行时根据不同的情境选择并应用不同的算法或行为(不是条件判断)

挖个坑,后面会补一章策略模式

//对象合并 {created:[]}
export const HOOKS =[
"beforeCreated",
"created",
"beforeMount",
"mounted",
"beforeUpdate",
"updated",
"beforeDestory",
"destroyed",
]
// 策略模式
let starts ={}
starts.data =function(parentVal,childVal){
return childVal
} //合并data
starts.computed =function(){} //合并computed
starts.watch =function(){} //合并watch
starts.methods =function(){} //合并methods
//遍历生命周期
HOOKS.forEach(hooks=>{
starts[hooks] = mergeHook
}) function mergeHook(parentVal,childVal){
if(childVal){
if(parentVal){
//把子元素合并进去
return parentVal.concat(childVal)
}else{
return [childVal] //[a]
}
}else{
return parentVal
}
}

这里定义常量HOOKS包含了一组生命周期钩子的名字

随后创建starts对象,用于存储各个不同属性的不同合并策略

至于mergeHook,这就是个简单的合并方法,不用多解释了


再来看下半部分

export function mergeOptions(parent, child) {
console.log(parent,child,'||this is parent and child in mergeOptions()')
const options ={}
//判断父亲
for(let key in parent){
console.log(key,'||this is key')
mergeField(key)
}
//判断儿子
for(let key in child){
console.log(key,'||this is key')
mergeField(key)
}
function mergeField(key){
//根据key 选择不同策略区处理
if(starts[key]){ //created {created:[a]}
options[key] =starts[key](parent[key],child[key])
}else{
options[key] = child[key]
}
}
return options
}
mergeOptions将父项和子项合并成一个新的对象

这个你真的得亲自上手调试一下

3.2.init.js


这句就是将在option合并Vue.option中并返回给vm.$options
(option为new Vue时带的参数)

最后,看看效果

将方法都合并到了created中

 

 

 

Vue源码学习(七):合并生命周期(混入Vue.Mixin)的更多相关文章

  1. 一起学习vue源码 - Vue2.x的生命周期(初始化阶段)

    作者:小土豆biubiubiu 博客园:https://www.cnblogs.com/HouJiao/ 掘金:https://juejin.im/user/58c61b4361ff4b005d9e8 ...

  2. Vue源码之组件化/生命周期(个人向)

    大致流程 具体流程 组件化 (createComponent) 构造⼦类构造函数 const baseCtor = context.$options._base // plain options ob ...

  3. Vue源码学习1——Vue构造函数

    Vue源码学习1--Vue构造函数 这是我第一次正式阅读大型框架源码,刚开始的时候完全不知道该如何入手.Vue源码clone下来之后这么多文件夹,Vue的这么多方法和概念都在哪,完全没有头绪.现在也只 ...

  4. Vue源码学习三 ———— Vue构造函数包装

    Vue源码学习二 是对Vue的原型对象的包装,最后从Vue的出生文件导出了 Vue这个构造函数 来到 src/core/index.js 代码是: import Vue from './instanc ...

  5. Vue源码学习二 ———— Vue原型对象包装

    Vue原型对象的包装 在Vue官网直接通过 script 标签导入的 Vue包是 umd模块的形式.在使用前都通过 new Vue({}).记录一下 Vue构造函数的包装. 在 src/core/in ...

  6. 最新 Vue 源码学习笔记

    最新 Vue 源码学习笔记 v2.x.x & v3.x.x 框架架构 核心算法 设计模式 编码风格 项目结构 为什么出现 解决了什么问题 有哪些应用场景 v2.x.x & v3.x.x ...

  7. 【Vue源码学习】依赖收集

    前面我们学习了vue的响应式原理,我们知道了vue2底层是通过Object.defineProperty来实现数据响应式的,但是单有这个还不够,我们在data中定义的数据可能没有用于模版渲染,修改这些 ...

  8. Vue 源码学习(1)

    概述 我在闲暇时间学习了一下 Vue 的源码,有一些心得,现在把它们分享给大家. 这个分享只是 Vue源码系列 的第一篇,主要讲述了如下内容: 寻找入口文件 在打包的过程中 Vue 发生了什么变化 在 ...

  9. Vue2.0源码学习(4) - 合并配置

    合并配置 通过之前的源码学习,我们已经了解到了new Vue主要有两种场景,第一种就是在外部主动调用new Vue创建一个实例,第二个就是代码内部创建子组件的时候自行创建一个new Vue实例.但是无 ...

  10. VUE 源码学习01 源码入口

    VUE[version:2.4.1] Vue项目做了不少,最近在学习设计模式与Vue源码,记录一下自己的脚印!共勉!注:此处源码学习方式为先了解其大模块,从宏观再去到微观学习,以免一开始就研究细节然后 ...

随机推荐

  1. CANoe _ Panel面板的创建过程

    在Canoe中创建Panel面板,用于显示和操作CAN网络的数据和信号,遵循以下步骤: 1.打开Canoe 启动Canoe软件. 2.打开项目 在Canoe的菜单栏中,选择"File&quo ...

  2. yolov5实战之模型剪枝

    续yolov5实战之二维码检测 目录 前沿 为什么要做轻量化 什么是剪枝 稀疏化训练 剪枝 微调 结语 模型下载 前沿   在上一篇yolov5的博客中,我们用yolov5训练了一个二维码检测器,可以 ...

  3. 在linux上启动arthas报“Can not find java process”

    发生背景 完整报错信息: [***@localhost ~]$ java -jar arthas-boot.jar [INFO] JAVA_HOME: /usr/lib/jvm/java-1.8.0- ...

  4. 1 opencv-python图像读写模块

    这个分类记录自己学习opencv的随笔文档,方便以后查询和复习.python-opencv环境配置网上教程很多,此处就不做赘述了,该文档记录opencv最基础的图像读写和显示,工具是jupyter n ...

  5. uniapp学习(二)

    easycom自动导入自定义组件 目录下 components / MyItem /MyItem.vue <template> <view> <view class=&q ...

  6. 即构自研海量有序数据网络MSDN,构建全球可靠的多云通讯链路

    2020是实时音视频技术应用大爆发的一年,电商直播.视频会议.在线课堂等多个场景获得了广泛关注.即构科技作为全球领先的云通讯商,截止目前已服务超过4000家企业客户,每日音视频通话时长超过20亿分钟, ...

  7. (内附示例源码)如何通过electron构建桌面跨平台音视频应用

    近年来,视频直播.直播带货.在线教育.在线医疗等音视频领域的相关行业都非常热门,成为大众瞩目的焦点. 在不久的将来,音视频技术渗透于各行各业,无处不在.从IoT网络到个人用户的移动设备,音视频技术以不 ...

  8. 博客代码托管网站个人体会及感受(GitHub、Coding、Netlity、阿里云弹性web托管)

    GitHub 免费 部署 github上,服务器在国外,访问速度一般,稳定性比较好,网站知名,操作方便,部署简单,域名不需要备案. Coding 免费 coding 支持 PHP + mysql 的动 ...

  9. Jedis 参数异常引发服务雪崩案例分析

    作者:vivo 互联网服务器团队 - Wang Zhi Redis 作为互联网业务首选的远程缓存工具而被大面积使用,作为访问客户端的 Jedis 同样被大面积使用.本文主要分析 Redis3.x 版本 ...

  10. 蜂鸟E203 仿真之路

    本文记录自己在学习蜂鸟E203的过程.下面简单介绍一下仿真之路所遇到的困难和走过的坑. 1.环境开发 :一般选择ubuntu 18.04 这个版本,安装这个教程很多,可以自行学习. 2.在Linux中 ...