Vue源码解析-简单实现文本插值并且简单封装(三)

Vue中最基本的数据绑定形式是文本插值,它使用的是“Mustache”语法 (即双大括号){ {}}的形式来进行数据的绑定,我们这里来进行一个简单的复刻,并且用字符串路径来访问对象成员,完成一个简单的封装。

<div id="root">
	<div>
		<div>
			<div>
				{
    {name}}{
    {message}}
			</div>
		</div>
	</div>
	<p>{
    {name}}</p>
	<p>{
    {message}}</p>
	<p>{
    {frit.fritOne}}</p>
	<p>{
    {frit.fritTwo}}</p>
</div>
<script type="text/javascript">
	let rkuohao = /\{\{(.+?)\}\}/g; //正则表达式

	function compiler(template, data) {
		let childNodes = template.childNodes; //取出子元素
		console.log(template)
		for (let i = 0; i < childNodes.length; i++) {
			let type = childNodes[i].nodeType; //nodeType用来描述节点的类型,当值为1时表示元素,为3时表示文本节点
			if (type === 3) {
				//当为文本节点的时候可以判断里面是否有{
    {}}的插值
				let txt = childNodes[i].nodeValue; //取出文本|nodeValue该属性只有文本节点有意义
				//判断文本里面有没有{
    {}}
				txt = txt.replace(rkuohao, function(_, g) { //使用正则表达式匹配一次,函数就会调用一次(函数第0个参数表示匹配到的内容,第n个参数表示正则表达式的第n组)
					let path = g.trim(); //得到{
    {}}里面的东西


					let value = getValueByPath(data, path);

					//将{
    {***}}用取到的值进行替换
					return value;
				})

				//注意现在txt和Dom元素是没有关系的

				childNodes[i].nodeValue = txt; //现在将元素重新加回去
			} else if (type === 1) {
				//当为元素的时候,需要考虑里面是否有子元素,需要对子元素进行判断是否插值
				compiler(childNodes[i], data);
			}
		}
	}

	function Vuew(options) {
		//定义数据
		this._data = options.data;
		this._el = options.el;

		//定义模板
		this._templateDOM = document.querySelector(this._el);
		this._parent = this._templateDOM.parentNode;

		//开始渲染
		this.render()
	}

	//将模板和数据结合得到HTML加入到页面
	Vuew.prototype.render = function() {
		this.compiler();
	}
	//将模板与数据结合得到DOM元素
	Vuew.prototype.compiler = function(tmpNode) {
		let realHTMLDOM = this._templateDOM.cloneNode(true); //用模板拷贝一个准DOM
		compiler(realHTMLDOM, this._data);
		this.update(realHTMLDOM);
	}
	//将DOM元素放到页面中
	Vuew.prototype.update = function(real) {
		this._parent.replaceChild(real, document.querySelector('#root'))
	}

	//用字符串路径来访问对象成员
	function getValueByPath(obj, path) {
		let paths = path.split('.') //分割获取到数组
		let res = obj;
		let prop;
		while (prop = paths.shift()) {
			res = res[prop];
		}
		return res;
	}

	let app = new Vuew({
		el: '#root',
		data: {
			name: '一个name',
			message: '一个message',
			frit: {
				fritOne: '一个fritOne',
				fritTwo: '一个fritTwo'
			}
		}
	})
</script>

最后我们完成的效果为这样

 

 

相关推荐

  1. vue3基于elementplus 简单实现表格二次封装

    2023-12-22 01:18:02       7 阅读
  2. flink分析 - 简单解析命令行参数

    2023-12-22 01:18:02       32 阅读
  3. Vue简单实例

    2023-12-22 01:18:02       13 阅读
  4. 手动实现 Vue 3的简易双向数据绑定(模仿

    2023-12-22 01:18:02       39 阅读

最近更新

  1. TCP协议是安全的吗?

    2023-12-22 01:18:02       18 阅读
  2. 阿里云服务器执行yum,一直下载docker-ce-stable失败

    2023-12-22 01:18:02       19 阅读
  3. 【Python教程】压缩PDF文件大小

    2023-12-22 01:18:02       18 阅读
  4. 通过文章id递归查询所有评论(xml)

    2023-12-22 01:18:02       20 阅读

热门阅读

  1. RHCE8 资料整理(十二)

    2023-12-22 01:18:02       41 阅读
  2. Issues about Ubuntu & ROS

    2023-12-22 01:18:02       32 阅读
  3. 【版本管理】git stash用法

    2023-12-22 01:18:02       30 阅读
  4. vue跳转方式

    2023-12-22 01:18:02       38 阅读
  5. HarmonyOS开发(十二):ArkTS组件通用事件

    2023-12-22 01:18:02       28 阅读
  6. LeetCode解法汇总2866. 美丽塔 II

    2023-12-22 01:18:02       45 阅读
  7. armv8-a 介绍

    2023-12-22 01:18:02       30 阅读
  8. 肺癌相关知识

    2023-12-22 01:18:02       30 阅读
  9. 解决MyBatis-Plus 更新字段为null 不生效

    2023-12-22 01:18:02       36 阅读
  10. QT计算时间差 秒 毫秒 (另附c++版本)

    2023-12-22 01:18:02       35 阅读
  11. 在 Mac 上使用 Python

    2023-12-22 01:18:02       42 阅读