经验首页 前端设计 程序设计 Java相关 移动开发 数据库/运维 软件/图像 大数据/云计算 其他经验
当前位置:技术经验 » HTML/CSS » HTML5 » 查看文章
Vue.js 源码分析(二十一) 指令篇 v-pre指令详解
来源:cnblogs  作者:大沙漠  时间:2019/7/9 9:34:38  对本文有异议

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

  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="UTF-8">
  5. <title>Document</title>
  6. <script src="https://cdn.jsdelivr.net/npm/vue@2.5.16/dist/vue.js"></script>
  7. </head>
  8. <body>
  9. <div id="app">
  10. <p v-pre :title="message">{{message}}</p>
  11. <p>{{message}}</p>
  12. </div>
  13. <script>
  14. Vue.config.productionTip=false;
  15. Vue.config.devtools=false;
  16. var app = new Vue({
  17. el:'#app',
  18. data:{message:"Hello World"}
  19. })
  20. </script>
  21. </body>
  22. </html>

编译后的结果为:

对应的HTML节点树为:

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

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

 

源码分析


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

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

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

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

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

  1. 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去设置特性

原文链接:http://www.cnblogs.com/greatdesert/p/11153635.html

 友情链接:直通硅谷  点职佳  北美留学生论坛

本站QQ群:前端 618073944 | Java 606181507 | Python 626812652 | C/C++ 612253063 | 微信 634508462 | 苹果 692586424 | C#/.net 182808419 | PHP 305140648 | 运维 608723728

W3xue 的所有内容仅供测试,对任何法律问题及风险不承担任何责任。通过使用本站内容随之而来的风险与本站无关。
关于我们  |  意见建议  |  捐助我们  |  报错有奖  |  广告合作、友情链接(目前9元/月)请联系QQ:27243702 沸活量
皖ICP备17017327号-2 皖公网安备34020702000426号