如果你需要在客户端编译模板 (比如传入一个字符串给 template 选项,或挂载到一个元素上并以其 DOM 内部的 HTML 作为模板),就将需要加上编译器,即完整版

当使用 vue-loader 或 vueify 的时候,*.vue 文件内部的模板会在构建时预编译成 JavaScript。你在最终打好的包里实际上是不需要编译器的,所以只用运行时版本即可— 官方文档

客户端编译模板

   <script src="https://cdn.jsdelivr.net/npm/vue@2.5.17/dist/vue.js"></script>

   <div id="app"></div>

   <script>
new Vue({
el: '#app',
data: {
message: 'Hello Vue!'
},
template: '<div>{{ message }}</div>'
})
</script>

这种用法就需要在客户端(即浏览器中)编译模板,模版的内容是 <div>{{ message }}</div> ,模版的数据是 message: 'Hello Vue!' 。

因此,如果使用 script 引入只有运行时版本的vue.js vue.runtime.js ,就会报错:

vue.runtime.js:593 [Vue warn]: You are using the runtime-only build of Vue where the template compiler is not available. Either pre-compile the templates into render functions, or use the compiler-included build.

使用渲染函数

   <script src="https://cdn.jsdelivr.net/npm/vue@2.5.17/dist/vue.runtime.js"></script>

   <div id="app"></div>

   <script>
new Vue({
el: '#app',
data: {
message: 'Hello Vue!'
},
render (createElement) {
return createElement('div', this.message)
}
})
</script>

这种用法就是直接给出渲染函数来进行内容输出(具体 createElement 语法后面再讲),这种情况下不需要进行客户端渲染,直接引用运行时版本的vue.js即可,并不会报错。

预编译模板

简单的页面结构我们可以直接通过 createElement 函数来手动编写,但是对于复杂的页面结构呢?vue提供了 Vue.compile 函数用于将模版编译成 render 函数,示例如下:

 <script src="https://cdn.jsdelivr.net/npm/vue@2.5.17/dist/vue.js"></script>

   <script>
const result = Vue.compile('<div>{{ message }}</div>');
console.log(result.render);
</script>

注意:只有 Runtime + Compiler 版本的vuejs才有 Vue.compile 函数,运行时版本的vue.js是没有这个函数的,所以这里也就是所谓的预编译。

输出的结果如下:

 ƒ anonymous(
) {
with(this){return _c('div',[_v(_s(message))])}
}

我们用预编译生成的render函数替代上一章的 render 函数:

  <script src="https://cdn.jsdelivr.net/npm/vue@2.5.17/dist/vue.runtime.js"></script>

   <div id="app"></div>

   <script>
new Vue({
el: '#app',
data: {
message: 'Hello Vue!'
},
render (createElement) {
with(this){return _c('div',[_v(_s(message))])}
}
})
</script>

可以看到这种“开发时预编译,上线使用运行时”的方式既满足了开发需要又减少了线上文件的大小。

注:通过打印,可以看到 createElement 以及 this._c ,  this._v  和  this._s 的值:

  render (createElement) {
console.log(createElement, this._c, this._v, this._s)
with(this){return _c('div',[_v(_s(message))])}
}
ƒ (a, b, c, d) { return createElement(vm, a, b, c, d, true); }
ƒ (a, b, c, d) { return createElement(vm, a, b, c, d, false); }
ƒ createTextVNode (val) {...}
ƒ toString (val) {...}

所以可以看出,我们最开始手写的渲染函数 return createElement('div', this.message) 只是上面预编译生成的一个简版。

基于 HTML 的模板语法

除了上面几种基于js代码的形式来创建模版,vuejs也支持基于 HTML 的模板语法,用法如下:

   <script src="https://cdn.jsdelivr.net/npm/vue@2.5.17/dist/vue.js"></script>
</head>
<body>
<div id="app"><div>{{ message }}</div></div> <script>
new Vue({
el: '#app',
data: {
message: 'Hello Vue!'
}
})
</script>

注意,这种写法也必须要使用 Runtime + Compiler 版本的vuejs才可以允许,因为其实质上还是在客户端进行模版编译,因为上面的写法实质上等同于下面的写法:

   <div id="app"></div>
<template id="tpl">
<div>{{ message }}</div>
</template> <script>
new Vue({
el: '#app',
data: {
message: 'Hello Vue!'
},
template: '#tpl'
})
</script>

vuejs源码中的 template 解析

在vuejs源码中,关于获取 template 的关键代码如下:

    var template = options.template;
if (template) {
if (typeof template === 'string') {
if (template.charAt(0) === '#') {
template = idToTemplate(template);
}
} else if (template.nodeType) {
template = template.innerHTML;
} else {
{
warn('invalid template option:' + template, this);
}
return this
}
} else if (el) {
template = getOuterHTML(el);
}

逻辑主要步骤如下:

  • 先判断是否有 template 属性
  • 如果没有,则直接通过 el 中的 html 代码作为模版
  • 如果有,判断是否是字符串(非字符串的形式暂不讨论)
  • 是字符串的情况下,是否以#字符开头
  • 如果是,则获取对应id的 innerHTML 作为模版
  • 如果不是以#字符开头,则直接作为作为模版

总结

一句话来讲就是:如果有 render 函数就可以使用运行时版本的vuejs,否则必须使用 Runtime + Compiler 版本的vuejs。

原文地址

Runtime Only和Runtime + Compiler的更多相关文章

  1. 了解vue里的Runtime Only和Runtime+Compiler

    转自:了解vue里的Runtime Only和Runtime+Compiler 扩展文章:Vue 2.0如何仅使用Runtime-only Build构建项目? 可以看到有两种版本: Runtime ...

  2. Target runtime com.genuitec.runtime.generic.jee60 is not defined

    转载自:http://jingyan.baidu.com/article/d7130635338e3f13fdf47518.html 用eclipse加载别人的工程,报错Target runtime ...

  3. Target runtime com.genuitec.runtime.generic.jee50 is not defined

    导入别人的工程,发现报错Target runtime com.genuitec.runtime.generic.jee50 is not defined   解决方法:1. 找到工程目录的.setti ...

  4. 用eclipse加载别人的工程,报错Target runtime com.genuitec.runtime.generic.jee60 is not defined

    系统加载工程后,报错Target runtime com.genuitec.runtime.generic.jee60 is not defined,在发布工程的同事电脑上正常 新导入的工程,出问题很 ...

  5. bug4 导入新工程时报 Target runtime com.genuitec.runtime.generic.jee60 is not defined

    系统加载工程后,报错Target runtime com.genuitec.runtime.generic.jee60 is not defined,在发布工程的同事电脑上正常.新导入的工程,出问题很 ...

  6. eclipse里error报错Target runtime com.genuitec.runtime.generic.jee60 is not defined.

    eclipse里error报错Target runtime com.genuitec.runtime.generic.jee60 is not defined. eclipse里error报错解决办法 ...

  7. Docker系列之AspNetCore Runtime VS .NetCore Runtime VS .NET Core SDK(四)

    前言 接下来我们就要慢慢步入在.NET Core中使用Docker的殿堂了,在开始之前如题,我们需要搞清楚一些概念,要不然看到官方提供如下一系列镜像,我们会一脸懵逼,不知道到底要使用哪一个. AspN ...

  8. Mac下 eclipse target runtime com.genuitec.runtime 解决方法

    Mac下 eclipse target runtime com.genuitec.runtime 解决方法 解决步骤如下: 首先是找到工程项目一个名叫.settings的文件夹,里面有个叫 org.e ...

  9. bug8 eclipse项目导入到myeclipse时 Target runtime com.genuitec.runtime.generic

    1.新导入的工程,出问题很大可能是jdk的版本问题导致,检查一下,发现jdk果然不一致,修改了jdk版本,但异常没有消除 2.网上查询下解决方案,原来在工程目录下的settings,有个文件也需要修改 ...

随机推荐

  1. ES6数组方法总结

    关于数组中forEach() .map().filter().reduce().some().every()的总结 1. forEach() let array = [1,2,3,4]; array. ...

  2. git拉取单个子目录

    初始化一个目录cron(需要拉取的的是code下的cron目录) git init cron 进入目录cd cron/ git remote add -f code ssh://git@192.168 ...

  3. slf4j的正确使用

    头两天领导分配个任务是要把项目中所有try catch里的异常处理收集到elk中,由于之前的处理方式五花八门,就集中处理了下, 事后还被批评了. 不是所有的异常信息都需要被记录到log中 使用SLF4 ...

  4. spring 中的 bean 是线程安全的吗?

    spring 中的 bean 是线程安全的吗? Spring 不保证 bean 的线程安全. 默认 spring 容器中的 bean 是单例的.当单例中存在竞态条件,即有线程安全问题.如下面的例子 计 ...

  5. Jmeter学习笔记(十九)——后置处理器之正则表达式的使用

    一.正则表达式提取器的作用 允许用户从服务器的响应中通过使用perl的正则表达式提取值.作为一个后置处理器,该元素会作用在指定范围的取样器,应用正则表达式,提取所需要的值,生成模板字符串,并将结果存储 ...

  6. Node: 模块

    我们知道,Node.js 选用 JavaScript 语言来编写代码.JavaScript 这门语言呢,之前主要用于前端应用,并没有相应的模块管理功能,而是以 script 标签为单位,直接引入即可运 ...

  7. 改变默认的多选框 checkbox 样式~

    效果图: HTML代码: <label for="Checkbox1" style="display:none;"></label> & ...

  8. 10 分钟上手 Vue 组件 Vue-Draggable

    Vue 综合了 Angualr 和 React 的优点,因其易上手,轻量级,受到了广泛应用.成为了是时下火热的前端框架,吸引着越来越多的前端开发者! 本文将通过一个最简单的拖拽例子带领大家快速上手 V ...

  9. 树莓派安装系统+ssh登录

    一.准备工作: (1)树莓派3b (2)官网下载系统 (3)SD卡 (4)网线 (5)SDFormatter.exe (6)win32diskimager.exe (7)putty (7)笔记本 二. ...

  10. Django-视图函数view

    目录 1.Django的视图函数view 1.1一个简单的视图 2.CBV和FBV 3.使用Mixin(了解) 4.给视图加装饰器 4.1使用装饰器装饰FBV 4.2使用装饰器装饰CBV 5.requ ...