首页 > 编程语言 >Vue源码学习(六):(支线)渲染函数中with(),call()的使用以及一些思考

Vue源码学习(六):(支线)渲染函数中with(),call()的使用以及一些思考

时间:2023-09-15 13:33:05浏览次数:46  
标签:function Vue return render text vnode 源码 call

好家伙,

 

昨天,在学习vue源码的过程中,看到了这个玩意

嘶,看不太懂,研究一下  

1.上下文

这段出现vue模板编译的虚拟node部分
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等方法执行创建虚拟节点,返回

 

 

标签:function,Vue,return,render,text,vnode,源码,call
From: https://www.cnblogs.com/FatTiger4399/p/17704272.html

相关文章

  • vue实现请再次输入密码的表单校验
     1、获取第一次输入的密码的值2、比较两次密码的值是否相等3、如果不一致返回错误信息this.userInfo.password2:获取第一次输入的密码;value当前校验值;validator自定义校验规则;constConfirmPassword=(rule,value,callback)=>{if(value!==this.userInfo.password2){......
  • Electron-vue项目打包遇坑
    项目背景一个Electron+vue2的桌面应用项目,进行打包使用了vue-cli-plugin-electron-builder将Electron和vue结合直接使用electron-builder打包问题一:打包后,background.js中会出现模块引入报错。Electron是commonJs规范,但使用了ESM规范import{createProtocol}from'vu......
  • 源码网
    优秀网站源码、编程源码下载网站大集中1.51源码2.源码之家:http://www.codejia.com/3.源码网:http://www.codepub.com/4.虾客源码:http://www.xkxz.com/5.多多源码6.洪越源代码:http://www.softhy.net/7.锋网源码:http://www.fwvv.net/8.代码爱好者:http://www.codefans.com/9.爱源码:http......
  • 问题记录:vue项目中的babel转化器是否可以转换npm install下来的依赖库,使该依赖库也可
    vue项目中的babel转化器是否可以转换npminstall下来的依赖库,使该依赖库也可以兼容es6语法?是的,Babel转换器可以用于转换通过npminstall安装的依赖库,以使其兼容ES6语法。Babel是一个广泛使用的JavaScript编译器,可以将较新版本的JavaScript代码转换为向后兼容的版本,以便在不支持这......
  • 基于python的医疗问诊服务数据采集及可视化分析系统-计算机毕业设计源码+LW文档
    选题的目的、理论与实践意义:选题的目的:随着“互联网+”概念的兴起,有很多传统行业获得了新的发展契机。根据数据统计,用户足不出户就能享受优质的医疗服务,看病贵和看病难这样的问题通过线上医疗问诊得到有效的缓解。系统通过对网站你用户及为平台提供服务的医生,医疗服务数据,评价信息......
  • 低代码开发平台 一款自定义软件开发平台源码
    低代码PaaS平台源码 采用对象方式实现字段、API的字段类型,引入RPA实现表自动化建模;再使用选择方式对地段功能进行选择定义甚至可以插入代码进行自定义。数字化转型的迫切需求随着数字科技的发展,各行各业对于新技术解决方案的需求也在逐日递增,非技术人员也开始被要求在短时间内构建......
  • 【Vue】大悟!模板语法-插值语法&指令语法
    Vue系列持续更新模板语法Vue模板语法包括两大类插值语法插值语法也就是两个大括号,也叫Mustache功能:用于解析标签体内容,可以进行运算、三元表达式等,将最终解析出来的内容插入到标签中写法:{{xxx}},xxx是js表达式,可以直接读取到data中的所有区域插值表达式中只能放置单个表达式,不......
  • uniapp VUE-H5页面微信公众号内使用微信JSAPI支付
    注意看本文主要讲解uniapp打包成h5页面并部署在公众号时使用JSAPI的微信支付问题前期准备工作.首先要有一个开通商户注册的公众号,我们需要他的appid;.其次要开通商户公众号的公众号支付的功能并添加域名,开通完成后就可以基本开始我们的开发了既然是jsapi开发自然是要引入的......
  • 失物招领系统的设计与实现-计算机毕业设计源码+LW文档
    一、课题背景 随着互联网的飞速发展,学校也进入了信息化时代。校园中大学生丢失物品的现象较为普遍,虽然目前国内有一些网上校园寻物平台或者是QQ群之类的,但是都不是很成熟,使得失主不能及时甚至找不到失物,给生活带来了极大的不便。通过互联网为在校师生搭建一个发布信息的平台,可以......
  • 生鲜电商系统的设计与实现-计算机毕业设计源码+LW文档
    一、研究的背景意义随着计算机信息技术和网络化进程的发展,电子商务逐渐成熟,通过信息技术手段把传统的销售活动转移到网络中来,打破了地区之间的限制,使得企业或者个人都可以参与进来。电子商务是一场信息革命,改变了人们的思维,对生产、生活都产生了非常大的影响。网上销售凭借便捷的......