自己写的一个Vue
下面这里是我自己写的一个小型的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的更多相关文章
- 如何写好一个vue组件,老夫的一年经验全在这了【转】 v-bind="$attrs" 和 v-on="$listeners"
如何写好一个vue组件,老夫的一年经验全在这了 一个适用性良好的组件,一种是可配置项很多,另一种就是容易覆写,从而扩展功能 Vue 组件的 API 来自三部分——prop.事件和插槽: prop 允许 ...
- VUE -- 如何快速的写出一个Vue的icon组件?
伴随着Vue的诞生,它似乎就被人寄予厚望,不仅仅是因为其轻量级的MVVM设计方式,而且其实现了组件化开发模式,所以越来越多的人会拿Vue和AngularJS.React Native做比较.具体关于它 ...
- 写了一个vue+antdv的后台管理模板
1,项目简介 写在前面===>这是一个vue+antdv的后台管理模板 项目地址: https://github.com/BaiFangZi/vue-antd-manage 1.1,概述 最 ...
- 写一个vue组件
写一个vue组件 我下面写的是以.vue结尾的单文件组件的写法,是基于webpack构建的项目.如果还不知道怎么用webpack构建一个vue的工程的,可以移步到vue-cli. 一个完整的vue组件 ...
- 如何优雅的写一个Vue 的弹框
写Vue或者是react 都会遇见弹框的问题.也尝试了多种办法来写弹框,一直都不太满意,今天特地看了一下 Element UI 的源码,模仿着写了一个简易版. 大概有一下几个问题: 1.弹框的层级问题 ...
- vue validate多表单验证思考 之前写过一个里外层,现在觉得不合适,应该平行的写,然后都给ret,最后判断ret 再做出反应,这样整体表单的所有验证就都报验证,然后最后提交的时候把组件内的对象合并到总的对象,再提交
vue validate多表单验证思考 之前写过一个里外层,现在觉得不合适,应该平行的写,然后都给ret,最后判断ret 再做出反应,这样整体表单的所有验证就都报验证,然后最后提交的时候把组件内的对象 ...
- 用vue.js写的一个瀑布流的组件
用vue.js写的一个瀑布流的组件:https://segmentfault.com/a/1190000010741319 https://www.jianshu.com/p/db3cadc03402
- 使用 vue 仿写的一个购物商城
在学习了 vue 之后,决定做一个小练习,仿写了一个有关购物商城的小项目.下面就对项目做一个简单的介绍. 项目源码: github 项目的目录结构 -assets 与项目有关的静态资源,包括 css, ...
- 一个 Vue + Node + MongoDB 博客系统
源码 耗时半载(半个月)的大项目终于完成了.这是一个博客系统,使用 Vue 做前端框架,Node + express 做后端,数据库使用的是 MongoDB.实现了用户注册.用户登录.博客管理(文章的 ...
随机推荐
- [JOI2017春季合宿]Port Facility[set、二分图]
题意 你有两个栈,有 \(n\) 个货物,每个货物有一个进栈时间和出栈时间(所有时间的并集是1~2n),问有多少种不同的入栈方案. \(n\le 10^6\) 分析 把每个货物的存在看成区间,相交的区 ...
- Flutter - 创建底部导航栏
之前写过的一篇文章介绍了 Flutter - 创建横跨所有页面的侧滑菜单, 这次就一起来学习一下底部导航栏. 底部导航栏在ios平台上非常常见,app store就是这样的风格.还有就是大家最常用的微 ...
- 通过C#的HttpClient模拟form表单请求
post提交表单一般无非是一般text文本和文件类型,如下 <input type="file"/> <input type="text"/& ...
- nginx 新增域名访问
nginx 新增域名访问 1.申请阿里云域名 2.指向阿里云主机 3.配置nginx文件 server { listen 80; server_name zlx.test.com; set $root ...
- 从头到尾谈一下HTTPS
引言 “你能谈一下HTTPS吗?” “一种比HTTP安全的协议.” “...” 如果面试这样说的话那差不多就gg了,其实HTTPS要展开回答的话内容还挺丰富的.本篇文章详细介绍了HTTPS是什么.为什 ...
- 用IDEA开发简单的Servlet
最近学习java,主要是servlet相关的内容.IDEA和servlet之前都没有碰过,所以做了一下小实验,走了一些弯路:这里把一个完整的步骤写出来,加深一下印象. IDEA创建项目步骤 1. 在i ...
- Yale数据库上的人脸识别
一.问题分析 1. 问题描述 在Yale数据集上完成以下工作:在给定的人脸库中,通过算法完成人脸识别,算法需要做到能判断出测试的人脸是否属于给定的数据集.如果属于,需要判断出测试的人脸属于数据集中的哪 ...
- ubuntu 12.04下 ns3的下载 安装
这个的内容我主要是参考了 http://blog.sina.com.cn/s/blog_7ec2ab360102wwsk.html 这个链接的学习,基本上过程没有出现的问题. 就是这个链接少了测试的一 ...
- VS2013简单的单元测试
安装过程本人在此就不做多余的说明,如果一个程序员连一个软件都无法安装那我也醉了,其次就是希望我们不要为了完成作业而去用VS,下面我具体说一下单元测试. 第一步,文件→新建一个项目,具体操作如下图 打开 ...
- 2-Python3从入门到实战—基础之运算符
Python从入门到实战系列--目录 Python语言支持以下类型的运算符: 算术运算符 比较(关系)运算符 赋值运算符 逻辑运算符 位运算符 成员运算符 身份运算符 运算符优先级 算术运算符 Pyt ...