// 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. 强连通分量SCC 2-SAT

    强连通分量SCC 2-SAT 部分资料来自: 1.https://blog.csdn.net/whereisherofrom/article/details/79417926 2.https://ba ...

  2. mac redis搭建集群

    1.下载redis客户端 2.修改redis.conf文件 port 6379 //端口 daemonize yes cluster-enabled yes //打开集群 cluster-config ...

  3. MySQL笔记(4)-- 索引优化

    索引失效情况: 最佳左前缀法则:如果索引了多列,要遵循最左前缀法则,指的是查询从索引的最左前列开始并且不跳过索引中的列:[覆盖索引有a,b,c,条件中使用了b或bc都导致该索引失效:如果条件使用了ac ...

  4. spring容器概述

    这篇博客写一下对spring和springmvc父子容器的理解. 一.首先明确: (1)spring是一个大的父容器,springmvc是其中的一个子容器.父容器不能访问子容器对象,但是子容器可以访问 ...

  5. intern()方法的使用

    intern() intern方法的作用是:如果字符串常量池中已经包含一个字符串等于此String对象的字符串,则返回常量池中的这个String对应的对象, 否则将其添加到常量池并返回常量池中的引用. ...

  6. layer弹层插件

      // 使用前需要引入jquery的支持,链接如下:   https://blog-static.cnblogs.com/files/liguanlong/jquery1.9.1.min.js    ...

  7. 3 report formats of SFDC

    Choose one of the following report formats using the Format menu of the report builder. Tabular form ...

  8. Building Applications with Force.com and VisualForce(Dev401)( 八):Designing Applications for Multiple users:Managing your users' experience II

    Dev 401-008: Design Applications for Multiple Users' Experience Part 2Universal Containers Scenario1 ...

  9. “GANs”与“ODEs”:数学建模的终结?

    在本文中,我想将经典数学建模和机器学习之间建立联系,它们以完全不同的方式模拟身边的对象和过程.虽然数学家基于他们的专业知识和对世界的理解来创建模型,而机器学习算法以某种隐蔽的不完全理解的方式描述世界, ...

  10. 超越Mask-RCNN:谷歌大脑的AI,自己写了个目标检测AI

    这是一只AI生出的小AI. 谷歌大脑的Quoc Le团队,用神经网络架构搜索 (NAS) ,发现了一个目标检测模型.长这样: △ 看不清请把手机横过来 它的准确率和速度都超过了大前辈Mask-RCNN ...