// 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核心原理的更多相关文章

  1. FinClip 前端之 VUE 核心原理总结

    小程序框架有很多,都是支持前端JavaScript语言的,也是支持 vue.js 框架的.FinClip 小程序是兼容各家平台的.所以在学习了框架使用之后的进阶就要熟悉框架的底层原理. 1.数据响应式 ...

  2. 通过模拟Mybatis动态代理生成Mapper代理类,讲解Mybatis核心原理

    本文将通过模拟Mybatis动态代理生成Mapper代理类,讲解Mybatis原理 1.平常我们是如何使用Mapper的 先写一个简单的UserMapper,它包含一个全表查询的方法,代码如下 pub ...

  3. 「进阶篇」Vue Router 核心原理解析

    前言 此篇为进阶篇,希望读者有 Vue.js,Vue Router 的使用经验,并对 Vue.js 核心原理有简单了解: 不会大篇幅手撕源码,会贴最核心的源码,对应的官方仓库源码地址会放到超上,可以配 ...

  4. 19. vue的原理

    vue:原理1 => Object.defineProperty 当你把一个普通的 JavaScript 对象传给 Vue 实例的 data 选项,Vue 将遍历此对象所有的属性,并使用 Obj ...

  5. SPA 路由三部曲之核心原理

    为了配合单页面 Web 应用快速发展的节奏,近几年,各类前端组件化技术栈层出不穷.通过不断的版本迭代 React.Vue 脱颖而出,成为当下最受欢迎的两大技术栈. 仅 7 个月的时间,两个技术栈的下载 ...

  6. vue - vue基础/vue核心内容(终结篇)

    今天是vue基础.vue核心内容第三天,也是最后一天,后面开始进入组件化学习,整个基础内容以生命周期的结束而结束,不得不说,张天禹把这节课讲活了,开始觉得vue是一个有生命的东西,包括前面所说的很多脏 ...

  7. 模拟Vue之数据驱动2

    一.前言 在随笔“模拟Vue之数据驱动1”结尾处,我们说到如果监听的属性是个对象呢?那么这个对象中的其他属性岂不就是监听不了了吗? 如下: 倘若user中的name.age属性变化,如何知道它们变化了 ...

  8. 模拟Vue之数据驱动4

    一.前言 在"模拟Vue之数据驱动3"中,我们实现了为每个对象扩展一个$set方法,用于新增属性使用,这样就可以监听新增的属性了. 当然,数组也是对象,也可以通过$set方法实现新 ...

  9. Python面向对象篇之元类,附Django Model核心原理

    关于元类,我写过一篇,如果你只是了解元类,看下面这一篇就足够了. Python面向对象之类的方法和属性 本篇是深度解剖,如果你觉得元类用不到,呵呵,那是因为你不了解Django. 在Python中有一 ...

随机推荐

  1. 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 ...

  2. 小白学 Python 数据分析(21):pyecharts 好玩的图表(系列终篇)

    人生苦短,我用 Python 前文传送门: 小白学 Python 数据分析(1):数据分析基础 小白学 Python 数据分析(2):Pandas (一)概述 小白学 Python 数据分析(3):P ...

  3. 基于WxPython的GUI框架toolkit-frame介绍

    源码下载地址:https://download.csdn.net/download/zy0412326/12154342 源码下载地址:https://pan.baidu.com/s/1-s2WaQm ...

  4. django小型数据库

    后端: 序列化组件 from django.core import serializers # django自带的一个小型的序列化工具 def reg(request): user_list = mo ...

  5. 改变Dataframe的列的数据类型

    1.查看DataFrame的数据类型 df.dtypes#查看各列数据类型 df[A].dtypes#查看A列数据类型 2.转换DataFrame的数据类型 df[A].astypes(int)#将A ...

  6. ASP.NET Core Authentication and Authorization

    最近把一个Asp .net core 2.0的项目迁移到Asp .net core 3.1,项目启动的时候直接报错: InvalidOperationException: Endpoint CoreA ...

  7. Python python 数据类型的相互转换

    # number 之间的相互转换 # int <=> float var1 = 1; print(type(var1)) #<class 'int'> res1 = float ...

  8. js Object方法小结

    1. Object.defineProperty(obj,prop,{                 value:...,                 writable:boolean,//可写 ...

  9. Eclipse无法查看第三方jar包源代码解决

    我在csdn写了过了:https://blog.csdn.net/weixin_40404606/article/details/105174820

  10. 在C#MVC三层项目中如何使用SprintNet

    0.添加dll文件 1.首先在根目录下新建一个文件夹[Config],然后新建2两个xml文件. 1-1[controllers.xml]用来配置需要创建的对象 1-2[service.xml]用来配 ...