gpt4 book ai didi

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

转载 作者:我是一只小鸟 更新时间:2023-09-15 15:02:08 30 4
gpt4 key购买 nike

好家伙.

  。

昨天,在学习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等方法执行创建虚拟节点,返回 。

  。

  。

最后此篇关于Vue源码学习(六):(支线)渲染函数中with(),call()的使用以及一些思考的文章就讲到这里了,如果你想了解更多关于Vue源码学习(六):(支线)渲染函数中with(),call()的使用以及一些思考的内容请搜索CFSDN的文章或继续浏览相关文章,希望大家以后支持我的博客! 。

30 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com