经验首页 前端设计 程序设计 Java相关 移动开发 数据库/运维 软件/图像 大数据/云计算 其他经验
当前位置:技术经验 » JS/JS库/框架 » Vue.js » 查看文章
Vue源码学习(六):(支线)渲染函数中with(),call()的使用以及一些思考
来源:cnblogs  作者:养肥胖虎  时间:2023/9/15 13:34:02  对本文有异议

好家伙,

 

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

嘶,看不太懂,研究一下
 

1.上下文

这段出现vue模板编译的虚拟node部分
  1. export function renderMixin(Vue) {
  2. Vue.prototype._c = function () {
  3. //创建标签
  4. return createElement(...arguments)
  5. }
  6. Vue.prototype._v = function (text) { //文本
  7. return createText(text)
  8. }
  9. Vue.prototype._s = function (val) {
  10. return val == null?"":(typeof val ==='object')?JSON.stringify(val):val
  11. }
  12. Vue.prototype._render = function () { //render函数变成 vnode
  13. let vm = this
  14. let render = vm.$options.render
  15. console.log(render,'||this is render')
  16. let vnode = render.call(this)
  17. // console.log(vnode)
  18. return vnode
  19. }
  20. }
  21. //vnode只可以描述节点
  22. //创建元素
  23. function createElement(tag,data={},...children){
  24. return vnode(tag,data,data.key,children)
  25. }
  26. //创建文本
  27. function createText(text){
  28. return vnode(undefined,undefined,undefined,undefined,text)
  29. }
  30. //创建vnode
  31. function vnode(tag,data,key,children,text){
  32. return {
  33. tag,
  34. data,
  35. key,
  36. children,
  37. text
  38. }
  39. }

 

 

我实在是看不懂这个_render方法在干什么,所以我们开始研究

 

2.冻手尝试

2.1.方法返回方法

写一个简易版本,在一个空白页

 (显然这会失败,方法返回的方法未定义)

 

2.2.加上方法定义

  1. _c = function () {
  2. //创建标签
  3. return createElement(...arguments)
  4. }
  5. _v = function (text) { //文本
  6. return createText(text)
  7. }
  8. _s = function (val) {
  9. return val == null ? "" : (typeof val === 'object') ? JSON.stringify(val) : val
  10. }
  11. function createElement(tag, data = {}, ...children) {
  12. return vnode(tag, data, data.key, children)
  13. }
  14. //创建文本
  15. function createText(text) {
  16. return vnode(undefined, undefined, undefined, undefined, text)
  17. }
  18. //创建vnode
  19. function vnode(tag, data, key, children, text) {
  20. return {
  21. tag,
  22. data,
  23. key,
  24. children,
  25. text
  26. }
  27. }
  28. function test() {
  29. return _c('div', _v("张三"))
  30. }
  31. test()

成功执行

 

2.3.回到项目

现在再回到我们的项目
我们知道,渲染函数的_c,_v,_s等方法被定义在Vue的prototype上的

不可能像上述案例这样直接定义在全局

我们在写一个例子,这里用上with()

 

同样,执行成功了

 

 所以,我们能看到,正如mdn文档所说,

在这个例子中with()方法拓展了一个test()方法的作用域链

于是,到这里,最难的问题已经解决了

 

3.代码分析

 

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

 

 来看这串代码

  1. console.log(this,"||this is this")
  2. 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等方法执行创建虚拟节点,返回

 

 

原文链接:https://www.cnblogs.com/FatTiger4399/p/17704272.html

 友情链接:直通硅谷  点职佳  北美留学生论坛

本站QQ群:前端 618073944 | Java 606181507 | Python 626812652 | C/C++ 612253063 | 微信 634508462 | 苹果 692586424 | C#/.net 182808419 | PHP 305140648 | 运维 608723728

W3xue 的所有内容仅供测试,对任何法律问题及风险不承担任何责任。通过使用本站内容随之而来的风险与本站无关。
关于我们  |  意见建议  |  捐助我们  |  报错有奖  |  广告合作、友情链接(目前9元/月)请联系QQ:27243702 沸活量
皖ICP备17017327号-2 皖公网安备34020702000426号