手撸一个Vue
				
									
					
					
						 | 
						
							
							freeflydom 
							
							
								2025年8月7日 15:25
								本文热度 1102
							
							 
						 | 
					
					
				 
				背景
vue是啥,有哪些基本功能,模板,script, style, 双向绑定一大堆,太多东西了,太难了,直接开始动手吧
仓库
https://github.com/listen80/two-way-binding
体验一下(pc上使用)
https://listen80.github.io/two-way-binding/public/
单文件
通过ajax获取类似.vue .html .tpl文件
| const parser = new DOMParser(); | 
  | 
| export default (template) => { | 
|     const doc = parser.parseFromString(`<body>${template}</body>`, 'text/html'); | 
|     const body = doc.querySelector('body') | 
|     return { | 
|         template: body.querySelector('template')?.content, | 
|         script: body.querySelector('script'), | 
|         style: body.querySelector('style'), | 
|     } | 
| }; | 
构建vue实例
- 把script文本变成script运行
 - 把原始data变成reactive的形式,增加依赖收集
 - 解析template,扣出来指令,属性,方法,子组件等为了区分指令前缀使用@而不是v-
 - 挂载style样式增加
 - 替换当前实例挂载的元素,目前为止所有的元素(html, script, style)都已经使用上来了
 
|    | 
|    | 
 | 
 | 
|   create() { | 
|      | 
|     const { el, props = {} } = this.options | 
|      | 
|     const { script, template, style } = this.componentProperties | 
|      | 
|      | 
|     const es6ModuleCode = script.textContent; | 
  | 
|      | 
|      | 
|     const blob = new Blob([es6ModuleCode], { type: 'text/javascript' }); | 
|      | 
|     const url = URL.createObjectURL(blob); | 
  | 
|      | 
|      | 
|     import(url).then(module => { | 
|        | 
|       document.head.append(style) | 
|        | 
|        | 
|       const data = module.default.data || {}; | 
|        | 
|       const methods = module.default.methods || {}; | 
|        | 
|       const components = module.default.components || {}; | 
|        | 
|       Object.assign(this, props, data); | 
|        | 
|       observe(this); | 
|        | 
|        | 
|       compile(template, this, methods, components); | 
|        | 
|        | 
|       el.replaceWith(template) | 
|     }).catch(err => { | 
|        | 
|       console.error('加载模块失败', err); | 
|     }); | 
|   } | 
总结
就这么结束了,是不是很简单,当然其中的细节很多,上文主要是描述核心思想点
本demo是没有使用虚拟dom,是dom跟数据直接绑定的,跟进vue3.6 vapor
水平有限,本文只是为了学习分享简单的示例,目的是为了了解运作机制
转自https://www.cnblogs.com/listen80/p/19026582
该文章在 2025/8/7 15:25:02 编辑过