【vue】 runtime-compiler和runtime-only的区别

我们在利用脚手架创建项目时,在一个环节中会让我们选择runtime-compiler或runtime-only,这两者到底有什么区别呢?

文章目录

        • 一、两者的比较
        • 二、render()函数讲解
          • 1. render()函数的介绍
          • 2.render()的使用

一、两者的比较

1.下面我们来创建两个项目,分别选中runtime-compiler和runtime-only:

项目一:

【vue】 runtime-compiler和runtime-only的区别_第1张图片
项目二:
【vue】 runtime-compiler和runtime-only的区别_第2张图片
2.我们先来查看这两个项目main.js文件的差别:
【vue】 runtime-compiler和runtime-only的区别_第3张图片
首先我们先看看vue实例是如何使用App这个模块的:

  • runtime-compiler:使用components属性注册App组件,在template属性是使用App组件。
  • runtime-only:直接使用render属性调用h()函数使用App组件。

runtime-only没有使用template属性,且当项目的vue实例中出现template,则运行会出错。

3.我们看看Vue实例中template属性运行过程:
【vue】 runtime-compiler和runtime-only的区别_第4张图片
上面很明显能看出runtime-compiler和runtime-only的执行区别:

  • runtime-compiler需从第一步运行到最后一步。
  • runtime-only则直接从第三步的render()开始执行。

1.性能上:明显runtime-only少了解析以及编译步骤,runtime-only性能更高。
2.项目代码量:由于runtime-only不用解析以及编译,则生成项目时就少了处理template的源码,则runtime-only的项目代码量更少。

二、render()函数讲解

1. render()函数的介绍

在Vue中,我们使用模板HTML来组建页面,使用render()我们就可以在逻辑行为中使用JS来构建DOM。

Vue的核心技术使用了虚拟DOM,所以在项目中的template模板是需要解析编译成虚拟DOM的,而转化为虚拟DOM的过程就需要用到render()函数。

当使用render()描述虚拟DOM时,Vue提供一个函数,这个函数就是构建虚拟DOM所需要的工具,官网上给它起了个名字createElement(),但通常简写为h()。

例如上面使用runtime-only创建的项目:

new Vue({
  el: "#app",
  render: h => h(App)
});

先来看看官网对createElement()的介绍:

// @returns {VNode}
createElement(
  // {String | Object | Function}
  // 一个 HTML 标签字符串,组件选项对象,或者
  // 解析上述任何一种的一个 async 异步函数,必要参数。
  'div',

  // {Object}
  // 一个包含模板相关属性的数据对象
  // 这样,您可以在 template 中使用这些属性。可选参数。
  {
    // (详情见下一节)
  },

  // {String | Array}
  // 子节点 (VNodes),由 `createElement()` 构建而成,
  // 或使用字符串来生成“文本节点”。可选参数。
  [
    '先写一些文字',
    createElement('h1', '一则头条'),
    createElement(MyComponent, {
      props: {
        someProp: 'foobar'
      }
    })
  ]
)

createElement(params1,params2,params3)有三个参数:

  • 必选参数1:标签名字符串、组件对象、或者解析(标签或组件对象)的异步函数。
  • 可选参数2:一个包含标签相关属性的数据对象。
  • 可选参数3:字符串或者数组,如果是字符串则是标签元素的内容;如果是数组,则是参数一标签元素的子元素,也就是嵌套元素。
  • 返回值:虚拟DOM。
2.render()的使用

1.简单的实例:

import Vue from "vue";

Vue.config.productionTip = false;

/* eslint-disable no-new */
new Vue({
  el: "#app",
  render: createElement => {
    return createElement(
      //参数一
      "div",
      //参数二
      {
        props: {
          value: ""
        },
        style: {
          width: "100px",
          height: "100px",
          backgroundColor: "yellow",
          color: "red"
        },
        on: {
          click: () => {
            console.log("点击了div");
          }
        }
      },
      //参数三
      "我是来自render的div容器"
    );
  }
});

【vue】 runtime-compiler和runtime-only的区别_第5张图片

  • 参数1:字符串,定义了div。
  • 参数2:对象,定义了关于div的属性数据。
  • 参数3:字符串,定义了div的内容。

我们来看看Vue项目的index.html:


<html>
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width,initial-scale=1.0">
    <title>myobj2title>
  head>
  <body>
    <div id="app">div>
    
  body>
html>

在前面Vue实例中,el="#app"就是获取index.html中的< div id=“app” > < /div >。

这里需要我们注意的是,render渲染出来的元素是直接覆盖掉< div id=“app” > < /div >的,而不是作为它的子元素。

看图证明:
【vue】 runtime-compiler和runtime-only的区别_第6张图片
2.深入看看参数2

 {
  // 和`v-bind:class`一样的 API
   'class': {
   foo: true,
    bar: false
   },
   // 和`v-bind:style`一样的 API
   style: {
    color: 'red',
   fontSize: '14px'
  },
  // 正常的 HTML 特性
  attrs: {
   id: 'foo'
  },
  // 组件 props
  props: {
   myProp: 'bar'
  },
  // DOM 属性
  domProps: {
   innerHTML: 'baz'
  },
  // 事件监听器基于 `on`
  // 所以不再支持如 `v-on:keyup.enter` 修饰器
  // 需要手动匹配 keyCode。
  on: {
   click: this.clickHandler
  },
  // 仅对于组件,用于监听原生事件,而不是组件内部使用
  // `vm.$emit` 触发的事件。
  nativeOn: {
   click: this.nativeClickHandler
  },
  // 自定义指令。注意,你无法对 `binding` 中的 `oldValue`
  // 赋值,因为 Vue 已经自动为你进行了同步。
  directives: [
   {
    name: 'my-custom-directive',
    value: '2',
    expression: '1 + 1',
    arg: 'foo',
    modifiers: {
     bar: true
   }
   }
  ],
  // Scoped slots in the form of
  // { name: props => VNode | Array }
  scopedSlots: {
   default: props => createElement('span', props.text)
  },
  // 如果组件是其他组件的子组件,需为插槽指定名称
  slot: 'name-of-slot',
  // 其他特殊顶层属性
  key: 'myKey',
  ref: 'myRef'
 }

你可能感兴趣的:(vue,vue,前端)