资讯专栏INFORMATION COLUMN

Vue模板编译,生成render函数

testbird / 2704人阅读

摘要:模板转换成浏览器认识的过程如下解析方法运行这里总结下第一步模板编译成函数的方式,生成的函数都会加在实例的上或者原型上,调用实例的方法时被调用。

模板转换成浏览器认识的HTML过程如下:

template -> AST render (compiler解析template)

AST render -> vNode (render方法运行)

vNode -> DOM (vdom.patch)

这里总结下第一步模板编译成AST render函数的方式,生成的render函数都会加在vue实例的$options上或者$options原型上,调用实例的_render方法时被调用。可以看vue的源码:

Vue.prototype._render = function () {
    var vm = this;
    var ref = vm.$options;
    var render = ref.render;
    var _parentVnode = ref._parentVnode;

    if (_parentVnode) {
      vm.$scopedSlots = normalizeScopedSlots(
        _parentVnode.data.scopedSlots,
        vm.$slots,
        vm.$scopedSlots
      );
    }

    // set parent vnode. this allows render functions to have access
    // to the data on the placeholder node.
    vm.$vnode = _parentVnode;
    // render self
    var vnode;
    try {
      // There"s no need to maintain a stack becaues all render fns are called
      // separately from one another. Nested component"s render fns are called
      // when parent component is patched.
      currentRenderingInstance = vm;
      vnode = render.call(vm._renderProxy, vm.$createElement);
    } catch (e) {
      handleError(e, vm, "render");
      // return error render result,
      // or previous vnode to prevent render error causing blank component
      /* istanbul ignore else */
      if (process.env.NODE_ENV !== "production" && vm.$options.renderError) {
        try {
          vnode = vm.$options.renderError.call(vm._renderProxy, vm.$createElement, e);
        } catch (e) {
          handleError(e, vm, "renderError");
          vnode = vm._vnode;
        }
      } else {
        vnode = vm._vnode;
      }
    } finally {
      currentRenderingInstance = null;
    }
    // if the returned array contains only a single node, allow it
    if (Array.isArray(vnode) && vnode.length === 1) {
      vnode = vnode[0];
    }
    // return empty vnode in case the render function errored out
    if (!(vnode instanceof VNode)) {
      if (process.env.NODE_ENV !== "production" && Array.isArray(vnode)) {
        warn(
          "Multiple root nodes returned from render function. Render function " +
          "should return a single root node.",
          vm
        );
      }
      vnode = createEmptyVNode();
    }
    // set parent
    vnode.parent = _parentVnode;
    return vnode
  };
}
1. webpack打包工具,引入的"vue-template-compiler"编译生成render函数

这也是在使用打包工具时,只需引入运行时的vue, 如vue/dist/vue.runtime.esm.js

单文件 HelloWorld.vue



测试文件main.js

import HelloWorld from "./components/HelloWorld"
console.log("===========vue-template-compiler===========")
console.log(HelloWorld);

单文件HelloWorld.vue经过vue-loader处理,由vue-template-compiler编译生成的render函数:

详细内容如下图,里面的_h, _c, _v, _s都是vue实例函数的简称

2. vue源码完整版,vue全局API Vue.compile编译生成的render函数
import Vue from "vue"

let templateHelloworld = `
{{ msg }}
` // Vue完整版里的compiler let vueCompilerResult = Vue.compile(templateHelloworld); console.log("===========vue compiler===========") console.log(vueCompilerResult);

这是一个匿名函数,with包裹作用域,_c同上,是vue实例的方法简写

3 用jsx写render函数,经过编译后的结果:
import Vue from "vue"
let jsxHellowWorld = new Vue({
  render: function(h){
    return(
      
{msg}
) } }) console.log("===========jsx===========") console.log(jsxHellowWorld.$options.render);

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/106556.html

相关文章

  • 关于一些Vue的文章。(2)

    摘要:原文链接我的,欢迎。这次想要分享的一篇文章是从一个奇怪的错误出发理解的基本概念。瞬间明白了,原来是函数,一个考验编程能力的函数,比更接近编译器。来看这里有一个小知识点被忽略在实例挂载之后,元素可以用访问脑补会用到的场景中。。。 原文链接我的blog,欢迎STAR。 这次想要分享的一篇文章是:从一个奇怪的错误出发理解Vue的基本概念。 这篇文章以Vue的两种构建方式做为切入点,深入探讨...

    DirtyMind 评论0 收藏0
  • Vue不同编译输出文件的区别

    摘要:源码是选用了作为,看的源码时发现对应了不同的构建选项。这也对应了最后打包构建后产出的不同的包。第四种构建方式对应的构建脚本为不同于前面种构建方式这一构建对应于将关于模板编译的成函数的单独进行打包输出。 Vue源码是选用了rollup作为bundler,看Vue的源码时发现:npm script对应了不同的构建选项。这也对应了最后打包构建后产出的不同的包。 不同于其他的library,V...

    awesome23 评论0 收藏0
  • vue源码阅读之数据渲染过程

    摘要:图在中应用三数据渲染过程数据绑定实现逻辑本节正式分析从到数据渲染到页面的过程,在中定义了一个的构造函数。一、概述 vue已是目前国内前端web端三分天下之一,也是工作中主要技术栈之一。在日常使用中知其然也好奇着所以然,因此尝试阅读vue源码并进行总结。本文旨在梳理初始化页面时data中的数据是如何渲染到页面上的。本文将带着这个疑问一点点追究vue的思路。总体来说vue模版渲染大致流程如图1所...

    AlphaGooo 评论0 收藏0
  • Vue原理】Compile - 源码版 之 从新建实例到 compile结束的主要流程

    摘要:页面这个实例,按理就需要解析两次,但是有缓存之后就不会理清思路也就是说,其实内核就是不过是经过了两波包装的第一波包装在中的内部函数中内部函数的作用是合并公共和自定义,但是相关代码已经省略,另一个就是执行第二波包装在中,目的是进行缓存 写文章不容易,点个赞呗兄弟 专注 Vue 源码分享,文章分为白话版和 源码版,白话版助于理解工作原理,源码版助于了解内部详情,让我们一起学习吧研究基于 ...

    CODING 评论0 收藏0
  • Vue源码探究二】从 $mount 讲起,一起探究Vue的渲染机制

    摘要:的构造函数将自动运行启动函数。我在阅读源码的过程中,发现源码余行,而和模板编译相关的代码,则约有行左右。这个是创建的方法,作为第一个参数传入。最后会返回一个节点。这个时候将赋值为这个节点,挂载完成 mount, 意思为挂载。可以理解为将vue实例(逻辑应用),挂靠在某个dom元素(载体)上的一个过程。 一、创建Vue实例时的渲染过程 上一篇文章我们讲到, 在创建一个vue实例的时候(v...

    LeanCloud 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<