myvue 模拟vue核心原理
// js部分index.js
class Myvue{
constructor(options){
this.data = options.data;
this.dep = new Dep();
var id = options.el;
this.observe();
var Dom = this.VnodeContainer(document.querySelector(id));
document.querySelector(id).appendChild(Dom);
}
VnodeContainer(node,flag){ // 虚拟DOM容器
var flag = flag || document.createDocumentFragment();
var child;
while(child = node.firstChild){
this.compile(child);
flag.appendChild(child);
this.VnodeContainer(child,flag);
}
return flag;
}
compile(node){ // 编译DOM
let reg = /\{\{(.*)\}\}/g;
if(node.nodeType === ){ // 元素类型
let attr = node.attributes;
for(let i=;i<attr.length;i++){
if(attr[i].nodeName === 'v-model'){
let name = attr[i].nodeValue;
node.addEventListener('input',(e)=>{
this.data[name] = e.target.value;
});
node.value = this.data[name]; this.dep.add(new Watcher(this.data,node,name));
}
}
}
if(node.nodeType === ){ // text类型节点
if(reg.test(node.nodeValue)){
let name = RegExp.$; // 匹配到的字符串
name = name.trim();
node.nodeValue = this.data[name]; this.dep.add(new Watcher(this.data,node,name));
}
}
}
observe(){
Object.keys(this.data).forEach((el)=>{
this.definePropertyInit(this.data,el,this.data[el]);
});
}
definePropertyInit(target,key,value){ // 将data做成响应式的 Object.defineProperty(target,key,{
get:()=>{
return value;
},
set:(newVal)=>{
if(newVal === value) return;
value = newVal;
this.dep.notify(); // 更新
}
});
}
}
class Dep{ // 发布者
constructor(){
this.subs = [];
}
add(sub){
this.subs.push(sub);
}
notify(){
this.subs.forEach((el)=>{
el.update();
});
}
}
class Watcher{ // 观察者(订阅者)
constructor(vm,node,name){
Dep.global = this;
this.vm = vm;
this.node = node;
this.name = name;
this.update();
}
update(){
this.get();
switch (this.node.nodeType) {
case : // 标签元素
this.node.value = this.value;
break;
case : // 文本
this.node.nodeValue = this.value;
break;
default: break;
}
}
get(){
this.value = this.vm[this.name];
}
} let vm = new Myvue({
el: '#app',
data: {
msg: 'hello'
}
})
html部分
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body> <div id="app">
<input type="text" id="input" v-model='msg'>
<div id="box">{{msg}}</div>
</div> <script src='./index.js'></script>
</body>
</html>
myvue 模拟vue核心原理的更多相关文章
- FinClip 前端之 VUE 核心原理总结
小程序框架有很多,都是支持前端JavaScript语言的,也是支持 vue.js 框架的.FinClip 小程序是兼容各家平台的.所以在学习了框架使用之后的进阶就要熟悉框架的底层原理. 1.数据响应式 ...
- 通过模拟Mybatis动态代理生成Mapper代理类,讲解Mybatis核心原理
本文将通过模拟Mybatis动态代理生成Mapper代理类,讲解Mybatis原理 1.平常我们是如何使用Mapper的 先写一个简单的UserMapper,它包含一个全表查询的方法,代码如下 pub ...
- 「进阶篇」Vue Router 核心原理解析
前言 此篇为进阶篇,希望读者有 Vue.js,Vue Router 的使用经验,并对 Vue.js 核心原理有简单了解: 不会大篇幅手撕源码,会贴最核心的源码,对应的官方仓库源码地址会放到超上,可以配 ...
- 19. vue的原理
vue:原理1 => Object.defineProperty 当你把一个普通的 JavaScript 对象传给 Vue 实例的 data 选项,Vue 将遍历此对象所有的属性,并使用 Obj ...
- SPA 路由三部曲之核心原理
为了配合单页面 Web 应用快速发展的节奏,近几年,各类前端组件化技术栈层出不穷.通过不断的版本迭代 React.Vue 脱颖而出,成为当下最受欢迎的两大技术栈. 仅 7 个月的时间,两个技术栈的下载 ...
- vue - vue基础/vue核心内容(终结篇)
今天是vue基础.vue核心内容第三天,也是最后一天,后面开始进入组件化学习,整个基础内容以生命周期的结束而结束,不得不说,张天禹把这节课讲活了,开始觉得vue是一个有生命的东西,包括前面所说的很多脏 ...
- 模拟Vue之数据驱动2
一.前言 在随笔“模拟Vue之数据驱动1”结尾处,我们说到如果监听的属性是个对象呢?那么这个对象中的其他属性岂不就是监听不了了吗? 如下: 倘若user中的name.age属性变化,如何知道它们变化了 ...
- 模拟Vue之数据驱动4
一.前言 在"模拟Vue之数据驱动3"中,我们实现了为每个对象扩展一个$set方法,用于新增属性使用,这样就可以监听新增的属性了. 当然,数组也是对象,也可以通过$set方法实现新 ...
- Python面向对象篇之元类,附Django Model核心原理
关于元类,我写过一篇,如果你只是了解元类,看下面这一篇就足够了. Python面向对象之类的方法和属性 本篇是深度解剖,如果你觉得元类用不到,呵呵,那是因为你不了解Django. 在Python中有一 ...
随机推荐
- Journal of Proteome Research | Quantifying Protein-Specific N-Glycome Profiles by Focused Protein and Immunoprecipitation Glycomics (分享人:潘火珍)
文献名:Quantifying Protein-Specific N-Glycome Profiles by Focused Protein and Immunoprecipitation Glyco ...
- 小白学 Python 数据分析(21):pyecharts 好玩的图表(系列终篇)
人生苦短,我用 Python 前文传送门: 小白学 Python 数据分析(1):数据分析基础 小白学 Python 数据分析(2):Pandas (一)概述 小白学 Python 数据分析(3):P ...
- 基于WxPython的GUI框架toolkit-frame介绍
源码下载地址:https://download.csdn.net/download/zy0412326/12154342 源码下载地址:https://pan.baidu.com/s/1-s2WaQm ...
- django小型数据库
后端: 序列化组件 from django.core import serializers # django自带的一个小型的序列化工具 def reg(request): user_list = mo ...
- 改变Dataframe的列的数据类型
1.查看DataFrame的数据类型 df.dtypes#查看各列数据类型 df[A].dtypes#查看A列数据类型 2.转换DataFrame的数据类型 df[A].astypes(int)#将A ...
- ASP.NET Core Authentication and Authorization
最近把一个Asp .net core 2.0的项目迁移到Asp .net core 3.1,项目启动的时候直接报错: InvalidOperationException: Endpoint CoreA ...
- Python python 数据类型的相互转换
# number 之间的相互转换 # int <=> float var1 = 1; print(type(var1)) #<class 'int'> res1 = float ...
- js Object方法小结
1. Object.defineProperty(obj,prop,{ value:..., writable:boolean,//可写 ...
- Eclipse无法查看第三方jar包源代码解决
我在csdn写了过了:https://blog.csdn.net/weixin_40404606/article/details/105174820
- 在C#MVC三层项目中如何使用SprintNet
0.添加dll文件 1.首先在根目录下新建一个文件夹[Config],然后新建2两个xml文件. 1-1[controllers.xml]用来配置需要创建的对象 1-2[service.xml]用来配 ...