自己写的一个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.实现了用户注册.用户登录.博客管理(文章的 ...
随机推荐
- 蒙特卡罗方法 python 实现2
如果不考虑作图,这里的两个例子可以改写成下面的样子: 求圆周率 import random ''' 蒙特卡罗模拟 投点法计算圆周率 ''' # 投点游戏 def play_game(): # 圆 r ...
- memcached 和redis比较
同属于NOSQL存储,网上流传很多memcached能做的是redis都可以做,为什么基本现在两种都火,原因他们有各自擅长的地方. memcahed内部采用多核模式,单列运行很快.memcached采 ...
- SpringBoot日记——Docker的使用
跟进互联网的浪潮有时候也挺难的,还没学完就出现新技术了…… 今天来说说,如何使用docker吧~ docker的安装配置 Docker是一个容器,我们怎么理解这个概念.我们做windows系统的时候会 ...
- Jmeter+ant+Jenkins构建接口自动化测试
1.已写好jmeter脚本 2.安装ant并将ant-jmeter-1.1.1.jar文件放入ant/lib目录,用于调用jmeter 3.修改jmeter的jmeter.properties文件(将 ...
- Codeforces Round #550 (Div. 3) E. Median String (模拟)
Median String time limit per test 2 seconds memory limit per test 256 megabytes input standard input ...
- hive orc压缩数据异常java.lang.ClassCastException: org.apache.hadoop.io.Text cannot be cast to org.apache.hadoop.hive.ql.io.orc.OrcSerde$OrcSerdeRow
hive表在创建时候指定存储格式 STORED AS ORC tblproperties ('orc.compress'='SNAPPY'); 当insert数据到表时抛出异常 Caused by: ...
- 1090. Highest Price in Supply Chain (25)-dfs求层数
给出一棵树,在树根出货物的价格为p,然后每往下一层,价格增加r%,求所有叶子节点中的最高价格,以及该层叶子结点个数. #include <iostream> #include <cs ...
- PAT甲题题解-1114. Family Property (25)-(并查集模板题)
题意:给出每个人的家庭成员信息和自己的房产个数与房产总面积,让你统计出每个家庭的人口数.人均房产个数和人均房产面积.第一行输出家庭个数,随后每行输出家庭成员的最小编号.家庭人口数.人均房产个数.人均房 ...
- 一些常用SQL语句大全
一.基础 1.说明:创建数据库 CREATE DATABASE database-name 2.说明:删除数据库 drop database dbname 3.说明:备份sql server --- ...
- 蜗牛慢慢爬 LeetCode 22. Generate Parentheses [Difficulty: Medium]
题目 Given n pairs of parentheses, write a function to generate all combinations of well-formed parent ...