如果你需要在客户端编译模板 (比如传入一个字符串给 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. Vue v-bind与v-model的区别

    v-bind    缩写 : 动态地绑定一个或多个特性,或一个组件 prop 到表达式. 官网举例   <!-- 绑定一个属性 -->   <img v-bind:src=" ...

  2. 又一个秘密如何让浏览器访问最新的js,css等外部引用

    在引用文件末尾加上一个参数,让浏览器知道这个文件跟上一个文件是不同的,让浏览器去服务器重新加载最新的,例如:<script type="text/javascript" sr ...

  3. 使用 Create-React-App 开发 Chrome 扩展

    整理 Kindle 标注.书签和笔记从未如此简单! Kindle 标注管理应用 Kindle Mate 只支持 Windows,不支持 Mac.标注只是解析我的剪贴文本文件,配合 FileReader ...

  4. VLC祥解

    功能部份:   VLC媒體播放器的核心是libvlc ,它提供了界面,應用處理功能,如播放列表管理,音頻和視頻解碼和輸出,線程系統.所有libvlc源文件設在的/src目錄及其子目錄:   # con ...

  5. Windows上安装ElasticSearch7的IK分词器

    首先IK分词器和ES版本一定要严格对应,下面是版本对照表 IK分词器下载地址 https://github.com/medcl/elasticsearch-analysis-ik/releases 我 ...

  6. 基于Text-CNN模型的中文文本分类实战 流川枫 发表于AI星球订阅

    Text-CNN 1.文本分类 转眼学生生涯就结束了,在家待就业期间正好有一段空闲期,可以对曾经感兴趣的一些知识点进行总结. 本文介绍NLP中文本分类任务中核心流程进行了系统的介绍,文末给出一个基于T ...

  7. https://www.runoob.com/linux/mysql-install-setup.html

    https://www.runoob.com/linux/mysql-install-setup.html

  8. python2和python3切换

    (1)需要将python2和python3的环境变量设置好 (2)重命名主程序 然后我们分别把两个版本的 Python 主程序 exe 改下名,3.6 版本的改名为 python3.exe,2.7 版 ...

  9. jmeter设置代理服务器录制脚本

    新建测试计划之后: 1.添加非测试元件:HTTP代理服务器 a.其中目标控制器可以控制选哪个线程放录制的脚本: b.将端口设置为8888或者其他不常用的端口,保持跟其他应用的端口不一致,否则被占用导致 ...

  10. 常用conda命令【转载】

    转载地址:https://haoyu.love/blog900.html 一直在用 Conda,很多东西记不住,每次都要查 Doc.那好,就写在这里做个备忘好了. 在 bash 里面自动加载 cond ...