下面这里是我自己写的一个小型的vue,原理就是proxy:

//Proxy天生没有prototype,因此要加上,不然extends会报错
Proxy.prototype = Proxy.prototype || Object.prototype class myVue extends Proxy {
constructor(options) {
let data = options.data || {} super(data, {
get(target, name, proxy) {
if(name in target) {
return target[name]
} else {
throw new Error(`不存在data'${name}'`)
}
},
set(target, name, value, proxy) {
target[name] = value
_container.render()
}
})
// 不能够在constructor里面设置data的值,因此公共变量只能在constructor里面定义,通过函数调用传递
// this.$el = document.querySelector(options.el) //data被类本身代理,而其他options经过初步处理后我们保存在一个变量对象_container中
let _container = {}
window.onload = function() {
_container.data = data
_container.el = document.querySelector(options.el)
_container.oldEl = document.querySelector(options.el).cloneNode(true)
_container.methods = options.methods || {}
//特殊地我们需要一个重新渲染el的内部方法也要存在_container里面
//绑定_container本身是为了render函数能够使用存在_container里面的options的内容
_container.render = render.bind(_container)
_container.render()
}
}
//get只能get到data对象里面的值,所以在内部定义的函数也没办法用
// zzz(){
// alert(123)
// }
} function render() {
let _computer = (e) => {
let val = ''
with(this.data){
val = eval(e)
}
return val
} //先把dom上的替换成“备份”
this.el.parentNode.replaceChild(this.oldEl, this.el);
//"备份"切换到this.el上等待被渲染
this.el = this.oldEl
//再复制一份留“备份”
this.oldEl = this.oldEl.cloneNode(true) //处理花括号
this.el.innerHTML = this.el.innerHTML.replace(/\{\{[^\{\}]+\}\}/, (str) =>{
let e = str.substring(2,str.length-2)
return _computer(e)
}) //处理:属性
let nodes = this.el.getElementsByTagName('*')
Array.from(nodes).forEach(node => {
Array.from(node.attributes).forEach(attr => {
if(attr.nodeName.startsWith(':')){
node.setAttribute(attr.nodeName.substring(1),_computer(attr.value))
node.removeAttribute(attr.nodeName)
} else if (attr.nodeName.startsWith('@')) {
if(!this.methods[attr.value]) {
throw new Error(`methods里面没有方法'${attr.value}'`)
}
node.addEventListener(attr.nodeName.substring(1),function(){
this.methods[attr.value]()
}.bind(this),false)
node.removeAttribute(attr.nodeName)
}
})
})
}

对应调用的HTML:

<!DOCTYPE html>
<html>
<head>
<title>myVue</title>
<script src="my-vue.js"></script>
<script>
let vm = new myVue({
el: '#app',
data: {
aaa: 123,
bbb: '你好啊,张啊咩'
},
methods:{
sayHello() {
alert('hello')
}
}
})
console.log(vm.aaa)
</script>
</head>
<body>
<div id="app">
{{aaa}}
<span :title="bbb" @click="sayHello">
hahaha
</span>
</div>
</body>
</html>

自己写的一个Vue的更多相关文章

  1. 如何写好一个vue组件,老夫的一年经验全在这了【转】 v-bind="$attrs" 和 v-on="$listeners"

    如何写好一个vue组件,老夫的一年经验全在这了 一个适用性良好的组件,一种是可配置项很多,另一种就是容易覆写,从而扩展功能 Vue 组件的 API 来自三部分——prop.事件和插槽: prop 允许 ...

  2. VUE -- 如何快速的写出一个Vue的icon组件?

    伴随着Vue的诞生,它似乎就被人寄予厚望,不仅仅是因为其轻量级的MVVM设计方式,而且其实现了组件化开发模式,所以越来越多的人会拿Vue和AngularJS.React Native做比较.具体关于它 ...

  3. 写了一个vue+antdv的后台管理模板

    1,项目简介 写在前面===>这是一个vue+antdv的后台管理模板 项目地址: https://github.com/BaiFangZi/vue-antd-manage 1.1,概述 ​ 最 ...

  4. 写一个vue组件

    写一个vue组件 我下面写的是以.vue结尾的单文件组件的写法,是基于webpack构建的项目.如果还不知道怎么用webpack构建一个vue的工程的,可以移步到vue-cli. 一个完整的vue组件 ...

  5. 如何优雅的写一个Vue 的弹框

    写Vue或者是react 都会遇见弹框的问题.也尝试了多种办法来写弹框,一直都不太满意,今天特地看了一下 Element UI 的源码,模仿着写了一个简易版. 大概有一下几个问题: 1.弹框的层级问题 ...

  6. vue validate多表单验证思考 之前写过一个里外层,现在觉得不合适,应该平行的写,然后都给ret,最后判断ret 再做出反应,这样整体表单的所有验证就都报验证,然后最后提交的时候把组件内的对象合并到总的对象,再提交

    vue validate多表单验证思考 之前写过一个里外层,现在觉得不合适,应该平行的写,然后都给ret,最后判断ret 再做出反应,这样整体表单的所有验证就都报验证,然后最后提交的时候把组件内的对象 ...

  7. 用vue.js写的一个瀑布流的组件

    用vue.js写的一个瀑布流的组件:https://segmentfault.com/a/1190000010741319 https://www.jianshu.com/p/db3cadc03402

  8. 使用 vue 仿写的一个购物商城

    在学习了 vue 之后,决定做一个小练习,仿写了一个有关购物商城的小项目.下面就对项目做一个简单的介绍. 项目源码: github 项目的目录结构 -assets 与项目有关的静态资源,包括 css, ...

  9. 一个 Vue + Node + MongoDB 博客系统

    源码 耗时半载(半个月)的大项目终于完成了.这是一个博客系统,使用 Vue 做前端框架,Node + express 做后端,数据库使用的是 MongoDB.实现了用户注册.用户登录.博客管理(文章的 ...

随机推荐

  1. 【第十一课】Tomcat原理解析【转】

    目录 一.Tomcat顶层架构 二.Tomcat顶层架构小结: 三.Connector和Container的微妙关系 四.Connector架构分析 五.Container架构分析 六.Contain ...

  2. pip virtualenv requirement

    原文:https://blog.csdn.net/u011860731/article/details/46561513 pip可以很方便的安装.卸载和管理Python的包.virtualenv则可以 ...

  3. 新手向:从不同的角度来详细分析Redis

    最近对华为云分布式缓存产品Redis做了一些研究,于是整理了一些基本的知识拿出来与大家分享,首先跟大家分享的是,如何从不同的角度来详细使用Redis. 小编将从以下9个角度来进行详细分析,希望可以帮到 ...

  4. 1085. Perfect Sequence (25)-水题

    #include <iostream> #include <cstdio> #include <algorithm> #include <string.h&g ...

  5. 【Beta阶段】第一次Scrum Meeting!

    本次会议为第一次Scrum Meeting会议~ 会议时长:20分 会议地点:依旧是7公寓1楼会客室   昨日任务一览 明日任务一览 刘乾 预定任务:(未完成)#128 学习如何在Github上自动构 ...

  6. 20135337朱荟潼 Linux第八周学习总结——进程的切换和系统的一般执行过程

    第八周 进程的切换和系统的一般执行过程 一.进程切换关键代码switch_to 1.不同类型进程有不同调度需求--两种分类 2.调度策略--规则 Linux中进程优先级是动态的,周期性调整. 3.时机 ...

  7. 第二个Sprint ------第七天、第八天、第九天、第十天,第十一天

    这几天我们主要讨论界面的设计,也终于有了个初步的界面: 主界面截图

  8. beta4

    吴晓晖(组长) 过去两天完成了哪些任务 昨天FloatingActionButton和权限获取调整 今天复习,没写东西,晚点有空了写 展示GitHub当日代码/文档签入记录 接下来的计划 推荐算法 还 ...

  9. DEP

    DEP(Data execution protect)数据执行保护,这个功能需要操作系统和硬件的共同支持才可以生效.DEP的原理就是在系统的内存页中设置了一个标志位,标示这个内存页的属性(可执行). ...

  10. ElasticSearch 2 (15) - 深入搜索系列之多字段搜索

    ElasticSearch 2 (15) - 深入搜索系列之多字段搜索 摘要 查询很少是简单的一句话匹配(one-clause match)查询.很多时候,我们需要用相同或不同的字符串查询1个或多个字 ...