// 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. Natas19 Writeup(Session登录,常见编码,暴力破解)

    Natas19: 提示,与上一题源码类似,只是PHPSESSID不连续.随便输入username和password,抓包观察PHPSESSID,发现是输入的信息,按照id-username的格式,由a ...

  2. K:剑指offer-56 题解 谁说数字电路的知识不能用到算法中?从次数统计到数字电路公式推导,一文包你全懂

    前言: 本题解整理了一位大佬在leetcode中的代码的方法,该博文致力于让所有人都能够能够看懂该方法.为此,本题解将从统计数字出现次数的解题方式开始讲起,再推导出逐位统计的解题方式,期望以循序渐进的 ...

  3. JS三个事件绑定方法

    1. JS三个事件绑定方法 1.1. 使用html进行事件绑定 1.直接在html标签上写入事件类型和事件处理方法. <button onclick = "alert('hello w ...

  4. [简单路径] Useful Decomposition

    Ramesses knows a lot about problems involving trees (undirected connected graphs without cycles)! He ...

  5. 采用vue编写的功能强大的swagger-ui页面

    think-swagger-ui-vuele swagger-ui有非常多的版本,觉得不太好用,用postman,每个接口都要自己进行录入.所以在基于think-vuele进行了swagger格式js ...

  6. 编译原理-第三章 词法分析-3.7 从正则表达式到自动机-DFA最简化

    DFA最简化 一.构造最简DFA 1.输入输出 2.步骤 3.注意点 4.代码 二.示例 例1: 例2: 参考--慕课-苏州大学

  7. Mock测试,结合Fiddler轻松搞定不同场景

    在平时测试过程中,总会遇到一些比较难构造的场景.比如不同平台间的同步,异常场景的构造.遇到难构造的场景时,就可以引用Mock来进行单元测试.简言之:mock测试就是在测试过程中,对于某些不容易构造或者 ...

  8. TensorFlow v2.0的基本张量操作

    使用TensorFlow v2.0的基本张量操作 from __future__ import print_function import tensorflow as tf # 定义张量常量 a = ...

  9. 探索学习率设置技巧以提高Keras中模型性能 | 炼丹技巧

      学习率是一个控制每次更新模型权重时响应估计误差而调整模型程度的超参数.学习率选取是一项具有挑战性的工作,学习率设置的非常小可能导致训练过程过长甚至训练进程被卡住,而设置的非常大可能会导致过快学习到 ...

  10. Git 处理换行符的配置方法

    core.autocrlf If you're programming on Windows and working with people who are not (or vice-versa), ...