文件分为html文件和js文件下面贴出代码块:
html文件:

<!DOCTYPE html>
<html lang="en">Ï
<head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>v-if/v-show</title><style>* {padding: 0;margin: 0;}html,body {font-size: 0;}.box-wrapper {width: 800px;height: 200px;}.box {float: left;width: 200px;height: 200px;line-height: 200px;color: #fff;text-align: center;font-size: 40px;}.box1 {background-color: red;}.box2 {background-color: orange;}</style>
</head>
<body><div id="app"><div class="box-wrapper"><div class="box box1" v-if="boxShow1">box 1</div><div class="box box2" v-show="boxShow2">box 2</div></div><button @click="showBox1">box 1</button><button @click="showBox2">box 2</button></div><script src="index.js"></script><script>var vm = new MyVue({el: '#app',data: {boxShow1: false,boxShow2: false},methods: {showBox1() {this.boxShow1 = !this.boxShow1},showBox2() {this.boxShow2 = !this.boxShow2}},})</script>
</body>
</html>

js文件:

class MyVue {constructor(options) {let { el, data, methods } = options;this.el = document.querySelector(el)this._data = data;this.methods = methods;this.showPools = new Map() // show/if 仓库this.eventPools = new Map() // 事件仓库this.init()}init() {this.initData()this.initDom(this.el)this.initView(this.showPools)this.initEvent(this.eventPools)}// 数据劫持initData() {let _this = this;for (let key in _this._data) {Object.defineProperty(_this, key, {get() {return _this._data[key]},set(newValue) {_this._data[key] = newValue_this.changeDom(key, this.showPools)}})}}// 初始dom处理initDom(el) {const _childNodes = el.childNodes;let _this = this// 递归先写结束条件if (!_childNodes.length) {return}_childNodes.forEach(child => {if (child.nodeType === 1) {const vIf = child.getAttribute('v-if')const vShow = child.getAttribute('v-show')const vEvent = child.getAttribute('@click')if (vIf) {_this.showPools.set(child, {type: 'if',key: vIf,value: _this[vIf]})}if (vShow) {_this.showPools.set(child, {type: 'show',key: vShow,value: _this[vShow]})}if (vEvent) {_this.eventPools.set(child, _this.methods[vEvent])}this.initDom(child) // 递归}})}initView(showPools) {this.changeDom(null, showPools)}initEvent(eventPools) {for (let [k, v] of eventPools) {k.addEventListener('click', v.bind(this), false)}}changeDom(key, showPools) {if (!key) {for (let [k, v] of showPools) {switch (v.type) {case 'if':v.comment = document.createComment('v-if')!v.value && k.parentNode.replaceChild(v.comment, k)break;case 'show':!v.value && (k.style.display = 'none')break;default:break;}}} else {for (let [k, v] of showPools) {if (v.key === key) {switch (v.type) {case 'if':v.value? k.parentNode.replaceChild(v.comment, k): v.comment.parentNode.replaceChild(k, v.comment)v.value = !v.valuebreak;case 'show':!v.value? k.style.display = 'block': k.style.display = 'none'v.value = !v.valuebreak;default:break;}}}}}
}Ï```javascript
// 以上代码均来自于b站 小野森森老师
// 鸣谢 小野森森老师

手写vue的v-if和v-show相关推荐

  1. vue filter对象_学习vue源码(3) 手写Vue.directive、Vue.filter、Vue.component方法

    一.Vue.directive Vue.directive(id,[definition]); 1)参数 { string } id{ Function | Object } [ definition ...

  2. Vue 源码之手写Vue Router

    Vue 源码之手写Vue Router 源码地址:https://github.com/CONOR007/Handwritten-routing 一.Vue Router的两种模式 hash模式实现原 ...

  3. vue 多点触控手势_手写 Vue 手势组件__Vue.js

    前言 最近需要使用手指捏合扩大的手势操作,找了几个组件,要么对 Vue 适配不好,要么量级太大,决定自己手写手势操作. 项目与效果预览 思路 直接在 DOM 上绑定 touchstart .touch ...

  4. (精华2020年5月17日更新) vue实战篇 手写vue底层源码

    MYvue.js 主要作用监听属性变化 class MYvue {constructor(options) {this.$options = options;this.$data = options. ...

  5. html手写vue多级选择框,vue + html 编写仿element select 多选组件

    现在做vue项目主要用的ui框架差不多都是elementui,但是每个项目设计的不同难免和element组件产生差异甚至是大不相同,有的时候差异少比如页面样式不太相同,功能使用完全一样的话,这样改改样 ...

  6. 手写Vue 的双向数据绑定

    在目前的前端面试中,vue的双向数据绑定已经成为了一个非常容易考到的点,即使不能当场写出来,至少也要能说出原理. 本篇文章中我将会仿照vue写一个双向数据绑定的实例,名字就叫myVue吧.结合注释,希 ...

  7. html手写vue多级选择框,vue多级多选菜单组件开发

    本文实例为大家分享了vue多级多选菜单组件的制作方法,供大家参考,具体内容如下 要开发一个这样的多级多选菜单组件,功能是: 点击父标题栏可以打开与折叠子列表 点击父标题栏的勾选图标可以全选或取消子列表 ...

  8. 从零开始手写vue项目的webpack基础配置

    一.创建目录结构 执行yarn init, 生成package.json文件; 1.写入文件 建立目录结构可参考vue项目目录结构: 首先建立一个src文件夹,其中包含index.html,App.v ...

  9. Vue源码分析-手写Vue(简易版)

    1.Vue双向绑定/MVVM响应式原理/v-model的原理 vue.js通过数据劫持结合发布订阅者模式,通过Object.defineProperty来劫持各个属性的setter,getter,在数 ...

最新文章

  1. 重磅!公开课|四旋翼飞行器:算法与实战
  2. Oracle实例迁移_真实场景实操
  3. 困扰程序员的30种软件开发问题,你是否时曾相识?
  4. ZOJ 3700 Ever Dream(模拟)
  5. IIS连接数、IIS并发连接数、IIS最大并发工作线程数、应用程序池的队列长度、应用程序池的...
  6. Linux--shell脚本之正则表达式
  7. 附带备忘录的斐波那契(C++)
  8. 规则管理平台系列(二)
  9. properties加载的几种方式
  10. python函数案例名片管理器_python实现名片管理器的示例代码
  11. pandas训练集测试集划分_用pandas划分数据集实现训练集和测试集
  12. react脚手架配置
  13. 重邮学报和计算机工程与应用,重庆邮电大学学报
  14. Qt编写自定义控件68-IP地址输入框
  15. 嵌入式学习:裸机开发_L4_官方SDK开发LED实验
  16. 前端面试题——浏览器原理 高频
  17. keras添加L1正则化,L2正则化和Dropout正则化及其原理
  18. Python3.x爬虫下载网页图片
  19. 马云向约旦王后基金会捐助300万美元,帮助阿拉伯难民儿童获得教育机会
  20. HTMLbutton 标签和input type=button的区别

热门文章

  1. 淤泥管道机器人_淤泥管道机器人
  2. Postgresql杂谈 06—Postgresql中的范围和数组类型
  3. 打造前端MAC工作站(六)MAC上的压缩软件,keka和atool
  4. Re:惠普DJ3836打印机之无法连接wifi
  5. 立波教你做安卓一键锁屏软件
  6. Python 中的 zip()函数
  7. 用ffmpeg在Windows11下的命令行模式推流到B站直播间
  8. java 下拉列表加日期,javascript 下拉框显示当前日期
  9. ubuntu镜像快速下载
  10. 基于matlab数字基带,基于MATLAB的数字基带传输的 FIR滤波器的设计