Vue相关内容 概述: Vue是前端的一个js库(诞生于2015年 兴起于2016年 尤雨溪 (阿里巴巴)),vue是一个MVVM模式的框架。 MVVM概述 - model 数据 - view 视图 - viewmodel 视图模型(管理 数据驱动视图) Vue的双向数据绑定 双向数据绑定的概述 - 视图变化---数据也会变化 - 数据变化---视图也会变化 双向数据绑定运用表单标签的 代码实现(v-model指令) ```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>Document</title> <script src="./lib/vue.js"></script> </head> <body> <div id="app"> <!-- 视图的渲染的地方 --> <input type="text" v-model="msg"> <!-- 插值表达式 可以获取data里面的数据 --> {{msg}} </div> <script> //这个vue.js文件导出的是一个构造函数 Vue let vm = new Vue({ el:'#app', //你需要将视图挂载到哪 data:{ //放数据的 msg:'你好' } }) console.log(vm) </script> </body> </html> ``` 原生实现vue2的双向数据绑定 流程 - 获取所有的input框 - 过滤哪个input有个属性叫v-model - 遍历所有加了v-model属性的input - 找这个v-model属性的属性值 对应data里面的数据值 - 给对应的input添加监听 监听input的value变化 - 设置给对应的data - 使用Object.defineProperty 的set来监听数据的变化 - 在数据变化的时候 重新渲染对应的input的值 - 渲染应该解析对应{{}} 找到对应的属性名 进行替换 代码实现 ```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>Document</title> </head> <body> <div id="app"> <!-- 视图的渲染的地方 --> <input type="text" v-model="msg"> <!-- 插值表达式 可以获取data里面的数据 --> {{msg}} {{hello}} {{hello}} </div> <script> class Vue{ constructor(option){ this.el = document.querySelector(option.el) //找到对应渲染的元素 this.data = option.data //用于Object.defineProperty的使用 this.model = Object.assign({},option.data) //拿到传入的元素的里面显示的所有的内容 this.template = document.querySelector(option.el).innerHTML this.render() this. _obServer() } //观察者 观察data的数据变化 _obServer(){ let _this = this //遍历所有的属性 for(let key in this.data){ Object.defineProperty(this.data,key,{ get(){ return _this.model[key] }, set(v){ _this.model[key] = v //渲染 _this.render() } }) } } //渲染的方法 render(){ let _this = this //找到所有的{{}} 括起来的内容 进行替换 this.el.innerHTML = this.template.replace(/\{\{\w+\}\}/g,(str)=>{ //str {{msg}} let propertyName = str.substring(2,str.length-2).trim() //msg return _this.data[propertyName] }) //找到对应el里面的input框 Array.from(this.el.querySelectorAll('input')) .filter((input)=>{ //找到input中是否具备v-model属性 return input.getAttribute('v-model') }) .forEach((input)=>{ let _this = this //遍历所有的input框 (都是有v-model属性的) //获取对应的v-model的属性值 let propertyName = input.getAttribute('v-model').trim() //给这个input添加onchange事件或者是oninput input.oninput = function(){ //获取他的value 设置给对应的data里面的属性 _this.data[propertyName] = this.value } //将对应的input的value 进行设置(对应的data里面属性的数据) input.value = this.data[propertyName] }) } } //这个vue.js文件导出的是一个构造函数 Vue let vm = new Vue({ el:'#app', //你需要将视图挂载到哪 data:{ //放数据的 msg:'你好', hello:'hello world' } }) </script> </body> </html> ``` 深拷贝和浅拷贝 浅拷贝 **只拷贝第一层的值 其他拷贝是地址**,相对于你拷贝一个拷贝快捷方式,这个新的快捷方式和原本的快捷方式不是一个,但是点进去的内容是一个。 Object.assign实现浅拷贝 ```js let obj = {name:'jack',list:[1,2,3],params:{data:'ok'}} let copyObj = Object.assign({},obj) console.log(obj == copyObj)//false console.log(obj.list == copyObj.list)//true ``` Array.prototype.concat (数组的浅拷贝) ```js //数组的浅拷贝 let arr = [{ username:'jack', password:'123' }, { username:'tom', password:'456' }] //使用concat连接 let copyArr = [].concat(arr) console.log(copyArr == arr)//false console.log(copyArr[0] == arr[0])//true ``` #### Array.prototype.slice (数组的浅拷贝) ``` //使用数组的截取来实现浅拷贝 let copyArr1 = arr.slice() console.log(copyArr1 == arr)//false console.log(copyArr1[0] == arr[0])//true ``` #### 扩展运算符 ... ```js //使用扩展运算符 let copyArr2 = [...arr] console.log(copyArr2 == arr);//false console.log(copyArr2[0] == arr[0])//true ``` #### 自定义函数实现浅拷贝 ```js //函数实现浅拷贝 function copy(obj){ //创建一个新的对象 let constructor = obj.constructor let copyObj = new constructor() for(let key in obj){ copyObj[key] = obj[key] } return copyObj } let copyArr3 = copy(arr) console.log(copyArr3 == arr);//false console.log(copyArr3[0] == arr[0])//true let copyObj1 = copy(obj) console.log(obj == copyObj1)//false console.log(obj.list == copyObj1.list)//true ``` #### 第三方工具(lodash.js) _.clone ```html <script src="https://cdn.jsdelivr.net/npm/lodash@4.17.21/lodash.min.js"></script> <script> //浅拷贝 拷贝的对象 返回一个新的对象 let obj2 = {name:'jack',list:[1,2,3],params:{data:'ok'}} let copyObj3 = _.clone(obj2) console.log(obj2 == copyObj3)//false console.log(obj2.list == copyObj3.list)//true </script> ``` #### 示例图 <img src="C:\Users\29769\AppData\Roaming\Typora\typora-user-images\image-20221104144437814.png" alt="image-20221104144437814" style="zoom:80%;" /> ### 深拷贝 #### 概述: 深拷贝是拷贝所有的内容,这个俩个内容相同点只在于里面的值是相同的,其他引用地址都不一样。相当于你用u盘拷贝一份资料,那么这份资料跟拷贝那么那份资料是没有任何关系,但是里面显示的内容是一样的。 #### 序列化和反序列化 (JSON.stringify JSON.parse) ```js //使用序列化和反序列化 let obj = { list:[{ name:"苹果" }, { name:"香蕉" }] } //进行深拷贝 let copyObj = JSON.parse(JSON.stringify(obj)) console.log(copyObj == obj);//false console.log(copyObj.list == obj.list);//false console.log(copyObj.list[0] == obj.list[0]);//false ``` #### 使用第三方工具 lodash.js (_.cloneDeep) ```html <script src="https://cdn.jsdelivr.net/npm/lodash@4.17.21/lodash.min.js"></script> <script> let copyObj1 = _.cloneDeep(obj) console.log(copyObj1 == obj);//false console.log(copyObj1.list == obj.list);//false console.log(copyObj1.list[0] == obj.list[0]);//false </script> ``` #### 自定义函数实现深拷贝(递归实现) ```js //自定义函数实现深拷贝(递归) function deepClone(obj) { //判断当前你传入的参数是否是一个对象 if (!(typeof obj == 'object' && obj)) { return obj } //如果他是数组 我就赋值为数组 如果是对象就赋值为 let copyObj = obj instanceof Array ? [] : {} //遍历传入的对象 for (let key in obj) { //将对应的内容进行赋值 copyObj[key] = deepClone(obj[key]) } return copyObj } let copyObj2 = deepClone(obj) console.log(copyObj2); console.log(copyObj2 == obj);//false console.log(copyObj2.list == obj.list);//false console.log(copyObj2.list[0] == obj.list[0]);//false ``` Vue原理介绍 虚拟dom 虚拟dom顾名思义就是虚拟的dom对象(对象),这个虚拟的dom对象跟实体的dom对象没有直接的关系。如果直接操作实体dom会造成大量的重绘和回流(页面渲染次数增加 渲染速度就慢)。所以为了解决这个问题,vue就是先操作对应的虚拟dom,再通过虚拟dom渲染实体dom(只有一次)。虚拟dom存在在内存中的,虚拟dom的形成是抽取对应的实体dom(模仿实体dom创建的对象)。 diff算法(脏检查器) diff算法是用于比对的算法,他是比对虚拟dom,比对虚拟dom的内容的改变,通过虚拟dom比对的内容变化来控制实体内容变化(用于性能优化的)。diff算法是通过对应的节点来进行比对的(元素节点,属性节点,文本节点 vnode)。 节点比对流程 节点比对流程先比key(下标不能作为key(下标会变)),比对对应的节点名,比对属性名,比对子节点。patch的方法来帮你进行分类比较,比较完进行渲染(模板引擎 模板引擎mustache)。 相关优化 生命周期优化(预加载(挂载的时候)、缓存(组件销毁的时候)、回收资源(组件销毁的时候)) 打包优化(webpack/glup(文件流))
【无标题】Vue相关内容及深拷贝和浅拷贝
最新推荐文章于 2023-08-12 09:07:31 发布