Vue源码学习(六):(支线)渲染函数中with(),call()的使用以及一些思考
好家伙,
昨天,在学习vue源码的过程中,看到了这个玩意

1.上下文
export function renderMixin(Vue) {
Vue.prototype._c = function () {
//创建标签
return createElement(...arguments)
}
Vue.prototype._v = function (text) { //文本
return createText(text)
}
Vue.prototype._s = function (val) {
return val == null?"":(typeof val ==='object')?JSON.stringify(val):val
}
Vue.prototype._render = function () { //render函数变成 vnode
let vm = this
let render = vm.$options.render
console.log(render,'||this is render')
let vnode = render.call(this)
// console.log(vnode)
return vnode
}
}
//vnode只可以描述节点
//创建元素
function createElement(tag,data={},...children){
return vnode(tag,data,data.key,children)
}
//创建文本
function createText(text){
return vnode(undefined,undefined,undefined,undefined,text)
}
//创建vnode
function vnode(tag,data,key,children,text){
return {
tag,
data,
key,
children,
text
}
}
我实在是看不懂这个_render方法在干什么,所以我们开始研究
2.冻手尝试
2.1.方法返回方法
写一个简易版本,在一个空白页

(显然这会失败,方法返回的方法未定义)
2.2.加上方法定义
_c = function () {
//创建标签
return createElement(...arguments)
}
_v = function (text) { //文本
return createText(text)
}
_s = function (val) {
return val == null ? "" : (typeof val === 'object') ? JSON.stringify(val) : val
}
function createElement(tag, data = {}, ...children) {
return vnode(tag, data, data.key, children)
}
//创建文本
function createText(text) {
return vnode(undefined, undefined, undefined, undefined, text)
}
//创建vnode
function vnode(tag, data, key, children, text) {
return {
tag,
data,
key,
children,
text
}
}
function test() {
return _c('div', _v("张三"))
}
test()
成功执行

2.3.回到项目
现在再回到我们的项目
我们知道,渲染函数的_c,_v,_s等方法被定义在Vue的prototype上的
不可能像上述案例这样直接定义在全局
我们在写一个例子,这里用上with()

同样,执行成功了

所以,我们能看到,正如mdn文档所说,
在这个例子中with()方法拓展了一个test()方法的作用域链
于是,到这里,最难的问题已经解决了
3.代码分析

在这里我们知道this指向Vue实例

来看这串代码
console.log(this,"||this is this")
let vnode = render.call(this)
在 JavaScript 中,.call() 方法可以用于调用函数,并且可以显式地指定函数运行时的作用域(即 this 值)。
于是,一切都通畅了
这一大段的代码无非做了这么几件事
1.在Vue的原型上定义_c,_v等节点处理方法
2.( render.call(this) )将render方法的作用域指定为this,即Vue实例本身
3.( with(this) )此处 with(this) 块中的 this 则指向渲染函数 render 执行时的上下文,也是 Vue 实例
4.随后,_c,_v等方法执行创建虚拟节点,返回
Vue源码学习(六):(支线)渲染函数中with(),call()的使用以及一些思考的更多相关文章
- Vue源码学习二 ———— Vue原型对象包装
Vue原型对象的包装 在Vue官网直接通过 script 标签导入的 Vue包是 umd模块的形式.在使用前都通过 new Vue({}).记录一下 Vue构造函数的包装. 在 src/core/in ...
- 【Vue源码学习】依赖收集
前面我们学习了vue的响应式原理,我们知道了vue2底层是通过Object.defineProperty来实现数据响应式的,但是单有这个还不够,我们在data中定义的数据可能没有用于模版渲染,修改这些 ...
- Vue源码学习1——Vue构造函数
Vue源码学习1--Vue构造函数 这是我第一次正式阅读大型框架源码,刚开始的时候完全不知道该如何入手.Vue源码clone下来之后这么多文件夹,Vue的这么多方法和概念都在哪,完全没有头绪.现在也只 ...
- Vue源码学习三 ———— Vue构造函数包装
Vue源码学习二 是对Vue的原型对象的包装,最后从Vue的出生文件导出了 Vue这个构造函数 来到 src/core/index.js 代码是: import Vue from './instanc ...
- 最新 Vue 源码学习笔记
最新 Vue 源码学习笔记 v2.x.x & v3.x.x 框架架构 核心算法 设计模式 编码风格 项目结构 为什么出现 解决了什么问题 有哪些应用场景 v2.x.x & v3.x.x ...
- VUE 源码学习01 源码入口
VUE[version:2.4.1] Vue项目做了不少,最近在学习设计模式与Vue源码,记录一下自己的脚印!共勉!注:此处源码学习方式为先了解其大模块,从宏观再去到微观学习,以免一开始就研究细节然后 ...
- Vue 源码学习(1)
概述 我在闲暇时间学习了一下 Vue 的源码,有一些心得,现在把它们分享给大家. 这个分享只是 Vue源码系列 的第一篇,主要讲述了如下内容: 寻找入口文件 在打包的过程中 Vue 发生了什么变化 在 ...
- Vue源码学习(一):调试环境搭建
最近开始学习Vue源码,第一步就是要把调试环境搭好,这个过程遇到小坑着实费了点功夫,在这里记下来 一.调试环境搭建过程 1.安装node.js,具体不展开 2.下载vue项目源码,git或svn等均可 ...
- 【Vue源码学习】响应式原理探秘
最近准备开启Vue的源码学习,并且每一个Vue的重要知识点都会记录下来.我们知道Vue的核心理念是数据驱动视图,所有操作都只需要在数据层做处理,不必关心视图层的操作.这里先来学习Vue的响应式原理,V ...
- vue 源码学习(一) 目录结构和构建过程简介
Flow vue框架使用了Flow作为类型检查,来保证项目的可读性和维护性.vue.js的主目录下有Flow的配置.flowconfig文件,还有flow目录,指定了各种自定义类型. 在学习源码前可以 ...
随机推荐
- Spring Boot 3.1中如何整合Spring Security和Keycloak
在今年2月14日的时候,Keycloak 团队宣布他们正在弃用大多数 Keycloak 适配器.其中包括Spring Security和Spring Boot的适配器,这意味着今后Keycloak团队 ...
- Java(命令行传参、可变参数、递归
1.命令行传参 通过命令行传参,main也可以传参 public class Hello { public static void main(String[] args) { for (int i = ...
- 基于 Web 的 Linux 终端 WebTerminal
有时候用公共电脑,或者在没有安装 putty.xshell 之类的终端的电脑上访问或展示服务器上的一些资料数据,甚至是在运维平台开发中想要嵌入 WebTerminal 功能,于是找到了这个项目--基于 ...
- 逍遥自在学C语言 | break-循环的中断与跳转
前言 在C语言中,break语句是一种控制流语句,它用于终止当前所在的循环结构(for.while.do-while)或者switch语句,从而跳出循环或者结束switch语句的执行. 一.人物简介 ...
- OpenSSL 是什么?
OpenSSL 是什么? OpenSSL 是开源的程序套件,该套件由三部分组成: libcrypto:具有通用功能的加密库,里面包含众多加密算法 libssl:实现 SSL/TLS 功能 openss ...
- 6 种方式读取 Springboot 的配置,老鸟都这么玩(原理+实战)
大家好,我是小富- 从配置文件中获取属性应该是SpringBoot开发中最为常用的功能之一,但就是这么常用的功能,仍然有很多开发者在这个方面踩坑. 我整理了几种获取配置属性的方式,目的不仅是要让大家学 ...
- Java打印出所有的"水仙花数",所谓"水仙花数"是指一个三位数,其各位数字立方和等于该数本身。 例如:153是一个"水仙花数",因为153=1的三次方+5的三次方+3的三次方。
代码如下: public static void main(String[] args) { int a,b,c; for(int num = 100;num <= 999;num++) { a ...
- 本地python调试 问题笔记
ImportError: cannot import name 'int_classes' from 'torch._six' 把 "from torch._six import stri ...
- 【笔试实战】LeetCode题单刷题-编程基础 0 到 1【二】
1822. 数组元素积的符号 题目链接 1822. 数组元素积的符号 题目描述 已知函数 signFunc(x) 将会根据 x 的正负返回特定值: 如果 x 是正数,返回 1 . 如果 x 是负数,返 ...
- MODBUS-TCP转Ethernet IP 网关连接空压机配置案例
本案例是工业现场应用捷米特JM-EIP-TCP的Ethernet/IP转Modbus-TCP网关连接欧姆龙PLC与空压机的配置案例.使用设备:欧姆龙PLC,捷米特JM-EIP-TCP网关, ETHER ...