该指令会跳过所在元素和它的子元素的编译过程,也就是把这个节点及其子节点当作一个静态节点来处理,例如:

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
<script src="https://cdn.jsdelivr.net/npm/vue@2.5.16/dist/vue.js"></script>
</head>
<body>
<div id="app">
<p v-pre :title="message">{{message}}</p>
<p>{{message}}</p>
</div>
<script>
Vue.config.productionTip=false;
Vue.config.devtools=false;
var app = new Vue({
el:'#app',
data:{message:"Hello World"}
})
</script>
</body>
</html>

编译后的结果为:

对应的HTML节点树为:

可以看到:title属性也被当成了特性来处理了,我们在控制台输入app.message="Hello Vue!"看看渲染变化:

可以看到对于v-pre对应的DOM节点,数据变化时也不会触发渲染的

源码分析


解析模板时如果遇到标签开始,会执行start函数,对于 <p v-pre :title="message">{{message}}</p>来说

start: function start (tag, attrs, unary) {   //第9136行  解析到标签开始时执行到这里
/*略*/ if (!inVPre) { //如果inVPre为false inVPre是个全局,用于判断当前是否在v-pre属性的环境之下,比如<p v-pre><span>123</span></p>解析到span标签时可以通过该属性来判断当前在v-pre内
processPre(element); //尝试解析v-pre属性
if (element.pre) { //如果element有v-pre属性
inVPre = true; //则设置inVPre为true
}
}
if (platformIsPreTag(element.tag)) {
inPre = true;
}
if (inVPre) { //如果当前为pre标签
processRawAttrs(element); //则设置inPre为true
} else if (!element.processed) {
// structural directives
processFor(element); //对于v-pre特性标记的节点来说,不会进行这里面的分支,也就不会处理Vue指令了
processIf(element);
processOnce(element);
// element-scope stuff
processElement(element, options);
} /*略*/
},

processRawAttrs用于将特性保存到AST对象的attrs属性上,如下:

function processRawAttrs (el) {     //第9317行 如果设置了v-pre特性,则执行到这里
var l = el.attrsList.length;
if (l) {
var attrs = el.attrs = new Array(l);
for (var i = 0; i < l; i++) { //遍历当前所有的特性,依次保存到e.attrs上面
attrs[i] = {
name: el.attrsList[i].name,
value: JSON.stringify(el.attrsList[i].value)
};
}
} else if (!el.pre) {
// non root node in pre blocks with no attributes
el.plain = true;
}
}

writer by:大沙漠 QQ:22969969

后面在gendata()函数执行时就会拼凑成attr属性里,最后render渲染成相应的DOM节点后就会将该attr属性保存到对应的节点上了,例子里的模板渲染成render函数如下:

with(this){return _c('div',{attrs:{"id":"app"}},[_c('p',{pre:true,attrs:{":title":"message"}},[_v("{{message}}")]),_v(" "),_c('p',[_v(_s(message))])])}

红色标记的就是v-pre编译后的模板,等到p元素渲染成真实DOM节点的时候,就会触发Vue内部attrs模块的updateAttrs方法进行初始化,之后就和v-bind指令里的后部分流程时一样的,最后会调用原生的DOM函数setAttribute去设置特性

Vue.js 源码分析(二十一) 指令篇 v-pre指令详解的更多相关文章

  1. Vue.js 源码分析(二十六) 高级应用 作用域插槽 详解

    普通的插槽里面的数据是在父组件里定义的,而作用域插槽里的数据是在子组件定义的. 有时候作用域插槽很有用,比如使用Element-ui表格自定义模板时就用到了作用域插槽,Element-ui定义了每个单 ...

  2. Vue.js 源码分析(二十八) 高级应用 transition组件 详解

    transition组件可以给任何元素和组件添加进入/离开过渡,但只能给单个组件实行过渡效果(多个元素可以用transition-group组件,下一节再讲),调用该内置组件时,可以传入如下特性: n ...

  3. Vue.js 源码分析(二十九) 高级应用 transition-group组件 详解

    对于过度动画如果要同时渲染整个列表时,可以使用transition-group组件. transition-group组件的props和transition组件类似,不同点是transition-gr ...

  4. Vue.js 源码分析(十四) 基础篇 组件 自定义事件详解

    我们在开发组件时有时需要和父组件沟通,此时可以用自定义事件来实现 组件的事件分为自定义事件和原生事件,前者用于子组件给父组件发送消息的,后者用于在组件的根元素上直接监听一个原生事件,区别就是绑定原生事 ...

  5. Vue.js 源码分析(二十四) 高级应用 自定义指令详解

    除了核心功能默认内置的指令 (v-model 和 v-show),Vue 也允许注册自定义指令. 官网介绍的比较抽象,显得很高大上,我个人对自定义指令的理解是:当自定义指令作用在一些DOM元素或组件上 ...

  6. jQuery 源码分析(二十一) DOM操作模块 删除元素 详解

    本节说一下DOM操作模块里的删除元素模块,该模块用于删除DOM里的某个节点,也可以理解为将该节点从DOM树中卸载掉,如果该节点有绑定事件,我们可以选择保留或删除这些事件,删除元素的接口有如下三个: e ...

  7. Vue.js 源码分析(二十三) 指令篇 v-show指令详解

    v-show的作用是将表达式值转换为布尔值,根据该布尔值的真假来显示/隐藏切换元素,它是通过切换元素的display这个css属性值来实现的,例如: <!DOCTYPE html> < ...

  8. Vue.js 源码分析(二十二) 指令篇 v-model指令详解

    Vue.js提供了v-model指令用于双向数据绑定,比如在输入框上使用时,输入的内容会事实映射到绑定的数据上,绑定的数据又可以显示在页面里,数据显示的过程是自动完成的. v-model本质上不过是语 ...

  9. Vue.js 源码分析(二十) 指令篇 v-once指令详解

    数据绑定最常见的形式就是使用“Mustache”语法 (双大括号) 的文本插值,例如:<p>Message: {{ msg }}</p>以后每当msg属性发生了改变,插值处的内 ...

随机推荐

  1. .net core event bus

    NServiceBus (收费) https://docs.particular.net/tutorials/quickstart/ MassTransit http://masstransit-pr ...

  2. php中搭建Web服务器和服务器配置

    1.搭建Web服务器     1.1目录结构 1.2访问服务器 访问规则:http://服务器ip地址/php页面 比如: http://localhost/demo.php http://127.0 ...

  3. Java入门——编写并运行第一个程序

    Java入门——编写并运行第一个程序 摘要:本文主要介绍如何使用Java语言编写并通过DOS运行简单的程序. 编写简单的程序 在D盘新建一个文本文档,输入如下代码: class Hello { pub ...

  4. 一则SQL优化案例

    原始sql: select CASE ) counts ,) else deadline end as deadline from t_product_credit) c group by sort ...

  5. UIImageView三种方式 和 位置分布

    typedef NS_ENUM(NSInteger, UIViewContentMode) { UIViewContentModeScaleToFill, //为将图片按照整个区域进行拉伸(会破坏图片 ...

  6. 【JavaScript】使用document.write输出覆盖HTML问题

    您只能在 HTML 输出中使用 document.write.如果您在文档加载后使用该方法,会覆盖整个文档. 分析 HTML输出流是指当前数据形式是HTML格式的数据,这部分数据正在被导出.传输或显示 ...

  7. win10安装ubuntu系统出现的一些问题以及解决方案

    前言 在win10系统进行安装新的ubuntu环境的时候遇到的一些问题,以及解决方案,供以后参考. 准备 从ubuntu官网下载最近版本的ubuntu系统,Ubuntu最新版本下载地址 操作系统:wi ...

  8. 6-SQL子查询

    (1) 什么是关联子查询,什么是非关联子查询 (嵌套查询) 子查询从数据表中查询了数据结果,如果这个数据结果只执行一次,然后这个数据结果作为主查询的条件进行执行,那么这样的子查询叫做非关联子查询. 如 ...

  9. RAID 独立磁盘冗余阵列 - redundant array of independent disks

    RAID:  RAID全称是独立磁盘冗余阵列(Redundant Array of Independent Disks),基本思想是把多个磁盘组合起来,组合一个磁盘阵列组,使得性能大幅提高. RAID ...

  10. java面试填坑解惑篇

    感谢原文出处:https://www.cnblogs.com/javazhiyin/ NO1.请简单描述JDK和JRE的区别? NO1.回答JDK和JRE的区别这道题,首先要回答两个名次的概念,JDK ...