设为首页 加入收藏

TOP

Vue.js 源码分析(三) 基础篇 模板渲染 el、emplate、render属性详解(一)
2019-09-17 19:00:11 】 浏览:61
Tags:Vue.js 源码 分析 基础 模板 渲染 emplate render 属性 详解

Vue有三个属性和模板有关,官网上是这样解释的:

el     ;提供一个在页面上已存在的 DOM 元素作为 Vue 实例的挂载目标

template  ;一个字符串模板作为 Vue 实例的标识使用。模板将会 替换 挂载的元素。挂载元素的内容都将被忽略,除非模板的内容有分发插槽。

render    ;字符串模板的代替方案,允许你发挥 java script 最大的编程能力。该渲染函数接收一个 createElement 方法作为第一个参数用来创建 VNode

 

简单说一下,就是:

  Vue内部会判断如果没有render属性则把template属性的值作为模板,如果template不存在则把el对应的DOM节点的outerHTML属性作为模板,经过一系列正则解析和流程生成一个render函数,最后通过with(this){}来执行。

  也就是说template的优先级大于el。

  render的参数是Vue内部的$createElement函数(位于4486行),它的可扩展性更强一些,在一些项目的需求中,可以用很简单的代码得到一个模板。例如Vue实战9.3里介绍的例子,有兴趣可以看看

render可以带3个参数,分别如下:

    tag          ;元素的标签名,也可以是组件名
    data        ;该VNode的属性,是个对象
    children        ;子节点,是个数组
其中参数2可以省略的,在4335行做了修正,最后执行_createElement()函数,如下:

function createElement (  //第4335行
  context,
  tag,
  data,
  children,
  normalizationType,
  alwaysNormalize
) {
  if (Array.isArray(data) || isPrimitive(data)) {     //如果data是个数组或者是基本类型
    normalizationType = children;
    children = data;                                      //修正data为children
    data = undefined;                                     //修正data为undefined
  }
  if (isTrue(alwaysNormalize)) {
    normalizationType = ALWAYS_NORMALIZE;
  }
  return _createElement(context, tag, data, children, normalizationType)     //最后执行_createElement创建一个虚拟VNode
}

 

例如下面三个Vue实例,分别用el、template和rentder指定模板,它们的输出是一样的

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <script src="https://cdn.bootcss.com/vue/2.5.16/vue.js"></script>
    <title>Document</title>
</head>
<body>
    <div id="app1">{{message}}</div>
    <div id="app2"></div>
    <div id="app3"></div>
    <script>
        var data={message:'you are so annoying'}
        new Vue({el:'#app1',data})                                                          //用el做模板
        new Vue({el:'#app2',data,template:"<div>{{message}}</div>"})                        //用template做模板
        new Vue({el:'#app3',data,render:function(h){return h('div',this.message)}})         //直接用render函数指定模板
    </script>        
</body>
</html>

 、浏览器显示结果:

可以看到输出是一摸一样的

 

  源码分析

Vue实例后会先执行_init()进行初始化,快结束时会判断是否有el属性,如果存在则调用$mount进行挂载,$mount函数如下:

writer by:大沙漠 QQ:22969969

Vue.prototype.$mount = function (    //定义在10861行
  el,
  hydrating
) {
  el = el && query(el);

  /* istanbul ignore if */
  if (el === document.body || el === document.documentElement) {
    "development" !== 'production' && warn(
      "Do not mount Vue to <html> or <body> - mount to normal elements instead."
    );
    return this
  }

  var options = this.$options;
  // resolve template/el and convert to render function
  if (!options.render) {                                            //如果render属性不存在
    var template = options.template;                                //则尝试获取template属性并将其编译成render   
    if (template) {
      if (typeof template === 'string') {                              
        if (template.charAt(0) === '#') {
          template = idToTemplate(template);
          /* istanbul ignore if */
          if ("development" !== 'production' && !template) {
            warn(
              ("Template element not found or is empty: " + (options.template)),
              this
            );
          }
        }
      } else if (template.nodeType) {
        template = template.innerHTML;
      } else {
        {
          warn('invalid template option:' + template,
首页 上一页 1 2 下一页 尾页 1/2/2
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
上一篇Javascript 防扒站,防止镜像网站 下一篇Vue.js 源码分析(一) 代码结构

最新文章

热门文章

Hot 文章

Python

C 语言

C++基础

大数据基础

linux编程基础

C/C++面试题目