nodeType属性在vue源码中的使用
每个节点都有一个 nodeType 属性,用于表明节点的类型,节点类型由 Node 类型中定义12个常量表示:

nodeType在vue中的应用
在vue编译的过程中需要查找html结构中的双大括号,或者@事件等代表vue中的数据及方法的属性值,通过编译将查找到的部分使用vue实例中的属性或方法替换
class Compile {
// el是宿主元素选择器
// vm是KVue实例
constructor(el, vm) {
this.$vm = vm;
this.$el = document.querySelector(el);
// 先把模板移动到fragment标签中,更新完成后在追加回来
this.$fragment = this.node2Fragment(this.$el);
// 执行编译
this.compile(this.$fragment);
// 追加
this.$el.appendChild(this.$fragment);
}
node2Fragment(el) {
// 移动操作
const fragment = document.createDocumentFragment();
let child;
while(child = el.firstChild) {
// 移动操作
fragment.appendChild(child);
}
return fragment
}
// 递归el,分别处理文本节点和元素节点
compile(el) {
const childNodes = el.childNodes;
Array.from(childNodes).forEach(node => {
if (node.nodeType == 1) {
// 元素节点 <p k-text="abc" @click="onClick"></p>
// console.log('元素节点:'+node.nodeName);
this.compileElement(node);
} else if (this.isInter(node)) {
// 文本节点,且内容是{{xxx}}实行
// console.log('插值文本:'+node.textContent);
this.compileText(node);
}
// 递归子节点
if (node.childNodes && node.childNodes.length > 0) {
this.compile(node);
}
})
}
// 文本节点,且内容是{{xxx}}实行
isInter(node) {
return node.nodeType == 3 && /\{\{(.*)\}\}/.test(node.textContent)
}
// 编译元素节点
compileElement(node) {
// 遍历所有属性
const nodeAttrs = node.attributes;
Array.from(nodeAttrs).forEach(attr => {
// 规定:指令以k-xxx="yyy"命名
const attrName = attr.name; // 属性名称 k-xxx
const exp = attr.value;// 属性值 yyy
if (attrName.indexOf('k-') == 0) {
const dir = attrName.substring(2);
// 执行指令解析
this[dir] && this[dir](node, exp)
}
})
}
compileText(node) {
const exp = RegExp.$1;
this.update(node, exp, 'text');
}
// 通用update方法
update(node, exp, dir) {
// 获取更新函数
let updator = this[dir + 'Updator'];
// 初始化,首次页面赋值
updator && updator(node, this.$vm[exp]);
// 创建Watcher
new Watcher(this.$vm, exp, function(value) {
updator && updator(node, value);
})
}
textUpdator(node, value) {
node.textContent = value;
}
text(node, exp) {
this.update(node, exp, 'text')
}
html(node, exp) {
this.update(node, exp, 'html')
}
htmlUpdator(node, value) {
node.innerHTML = value;
}
}
以上是简单的进行属性查找的示例,通过nodeType为1来判断是元素节点,还是文本节点并进行相应的操作。
nodeType属性在vue源码中的使用的更多相关文章
- 【Vue】VUE源码中的一些工具函数
Vue源码-工具方法 /* */ //Object.freeze()阻止修改现有属性的特性和值,并阻止添加新属性. var emptyObject = Object.freeze({}); // th ...
- vue源码中computed和watch的解读
computed 会基于其内部的 响应式依赖 进行缓存. 只在相关 响应式依赖发生改变 时 它们才会重新求值. 可以在将模板中使用的常量放在计算属性中. watch 监听数据变化,并在监听回调函数中返 ...
- 了解一下vue源码中vue 的由来
我们之前提到过 Vue.js 构建过程,在 web 应用下,我们来分析 Runtime + Compiler 构建出来的 Vue.js,它的入口是 src/platforms/web/entry-r ...
- Vue源码中compiler部分逻辑梳理(内有彩蛋)
目录 一. 简述 二. 编译流程 三. 彩蛋环节 示例代码托管在:http://www.github.com/dashnowords/blogs 博客园地址:<大史住在大前端>原创博文目录 ...
- 从Vue源码中我学到了几点精妙方法
话不多说,赶快试试这几个精妙方法吧!在工作中肯定会用得到. 立即执行函数 页面加载完成后只执行一次的设置函数. (function (a, b) { console.log(a, b); // 1,2 ...
- Vue源码解析---数据的双向绑定
本文主要抽离Vue源码中数据双向绑定的核心代码,解析Vue是如何实现数据的双向绑定 核心思想是ES5的Object.defineProperty()和发布-订阅模式 整体结构 改造Vue实例中的dat ...
- Vue源码学习(一):调试环境搭建
最近开始学习Vue源码,第一步就是要把调试环境搭好,这个过程遇到小坑着实费了点功夫,在这里记下来 一.调试环境搭建过程 1.安装node.js,具体不展开 2.下载vue项目源码,git或svn等均可 ...
- 【Vuejs】350- 学习 Vue 源码的必要知识储备
前言 我最近在写 Vue 进阶的内容.在这个过程中,有些人问我看 Vue 源码需要有哪些准备吗?所以也就有了这篇计划之外的文章. 当你想学习 Vue 源码的时候,需要有扎实的 JavaScript 基 ...
- vue源码解析之observe
一. vue文档中有"由于 JavaScript 的限制,Vue 不能检测以下数组的变动",是否真是由于JavaScript的限制,还是出于其他原因考虑 当你利用索引直接设置一个数 ...
随机推荐
- 小人大作战v0.02原型(单机)发布
运行环境,pc,windows 链接:https://pan.baidu.com/s/1X5XR0flRAVuinnydNyRNng 提取码:cp9q 复制这段内容后打开百度网盘手机App,操作更方便 ...
- HDU2650 A math problem——高斯素数
题意 给你一个数 $a+bj, \ j=\sqrt {-2}$,如果它只能被1.-1.本身和本身的相反数整除,则输出Yes,否则输出No. 分析 高斯整数 $a+bi$ 是素数当且仅当: (1)$a, ...
- redis缓存, 缓存击穿,缓存雪崩,缓存穿透
在实际项目中,MySQL数据库服务器有时会位于另外一台主机,需要通过网络来访问数据库:即使应用程序与MySQL数据库在同一个主机中,访问MySQL也涉及到磁盘IO操作(MySQL也有一些数据预读技术, ...
- 1. Spring Cloud Greenwich SR2 概览
Spring Cloud provides tools for developers to quickly build some of the common patterns in distribut ...
- 请描述一下cookies、sessionStorage、localStorage、session四者的区别?
存储大小: cookie在4K以内. sessionStorage和localStorage在5M以内. 有效时间: cookie:如果未设置过期时间,关闭浏览器时清空:如果设置了有效时间则在到期后清 ...
- 网络协议 19 - RPC协议综述
这几年微服务很火,想必各位博友或多或少的都接触过.微服务概念中, 各服务间的相互调用是不可或缺的一环.你知道微服务之间是通过什么方式相互调用的吗? 你可能说,这还不简单,用 socket 呗. ...
- python: 添加自定义模块路径 —— 可以使用相对路径
自定义模块时,添加模块路径: sys.path.append('..')
- word2vec学习总结
目录 1.简介 2.从统计语言模型开始 2.1序列概率模型 2.2 N元统计模型 3.深度序列模型 3.1神经概率模型 3.2 one-hot向量表示法 3.3 word2vec 3.4word2ve ...
- 解决mybatis中#{}导致的The error may involve defaultParameterMap的问题
今天想实现给指定表插入数据,出现了 ### Error updating database. Cause: java.sql.SQLSyntaxErrorException: You have an ...
- c#比较器辅助类
/// <summary> /// 比较器帮助类 /// 创建人:苏本东 :: /// </summary> public class ComparerHelper<T& ...