自己写的一个Vue
Vue 一个 自己
2023-09-14 08:58:55 时间
下面这里是我自己写的一个小型的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-router
- Vue笔记:vue项目引入bootstrap、elementUI、echarts
- Vue笔记:安装配置node.js及使用vue-cli创建项目
- 如何用vue打造一个移动端音乐播放器
- 基于vue-cli搭了一个多页面应用的空脚手架
- 快速构建一个使用axios的vue应用程序(转)
- Vue.js3: 页面打开前实现图片全部预加载(vue@3.2.33)
- vue.js 首屏优化
- 使用vue搭建应用四引入axios
- Vue.js3: 页面打开前实现图片全部预加载(vue@3.2.33)
- vue.js3.2.20: 在打包时取消生成.map文件
- Vue入门教程:node安装vue命令行工具及启动项目
- [FAQ] Vue iframe 的 src 是链接地址却加载了相对路径 ?
- 关于Vue 中v-html 失效的原因
- Vue CLI 4.x安装成功,但是无法运行vue-V等指令。报错vue -V 不是内部或外部命令,也不是可运行的程序或批处理文件解决方案!!!
- amCharts 4.8 Crack JS VUE 图表
- vue 使用 websocket
- Vue学习之--------组件的基本使用(非单文件组件)(代码实现)(2022/7/22)
- vue的手机端框架mint-ui头部header组件实现返回到上一个浏览页面
- 如何运行一个Vue项目
- 222:vue+openlayers 实现云雾缭绕,白鸽飞翔的效果
- 181:vue+openlayers 加载解析geojson文件,给每一个feature(非整体)添加渐变颜色
- Vue中使用 class 类样式的方法详情