首页 > 其他分享 >day26 Vue相关内容及深拷贝和浅拷贝

day26 Vue相关内容及深拷贝和浅拷贝

时间:2022-11-07 21:45:19浏览次数:63  
标签:arr Vue console log day26 let obj 拷贝

Vue相关内容

概述 :

Vue是前端的一个Js库 ( 诞生于2015年 , 兴起于2016年 , 尤雨溪写的(目前是阿里巴巴在维护) ) , vue是MVVM模式的框架 .

MVVM概述 :

  • model 数据

  • view 视图

  • viewmodel 视图模型 ( 管理 , 数据驱动视图 )

Vue的双向数据绑定

  • 视图变化 --- 数据也会变化

  • 数据变化 --- 视图也会变化

双向数据绑定 运用在表单标签 ( input )

代码实现 ( v-model指令 )
<!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>

原生Js实现vue2的双向数据绑定

流程 :

  • 获取所有的input框

  • 过滤出有v-model属性的input框并返回

  • 遍历所有加了v-model属性的input框

  • 找这个v-model属性的值 , 设置给data里面的msg

  • 给input添加监听 , 监听input的value变化 设置给data

  • 使用Object.defineProperty的set来监听数据的变化

  • 在数据变化的时候 , 重新渲染input的值

  • 渲染应该解析对应的{{}} , 找到对应的属性名进行替换

代码实现

<!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 class="box">
    <input type="text" v-model="msg">
    {{msg}}
    </div>
    <script>
    class Vue {
        constructor(option) {
            //获取需要渲染的元素
            this.el = document.querySelector(option.el)
               //获取要渲染的数据
            this.data = option.data
            //拷贝一个渲染的数据,以便后续defineProerty的使用
            this.model = Object.assign({}, option.data)
            //拿到页面上的显示的内容,后面需要做替换
            this.template = this.el.innerHTML
            this.render()
            this._obServer()
        }
        //观察数据的变化
        _obServer() {
            let self = this
            //遍历所有数据的属性
            for (let key in this.data) {
                // 定义属性的get和set方法(需定义的对象,需定义对象的属性,处理方法)
                Object.defineProperty(this.data, key, {
                //获取就直接返回数据的属性
                get() {
                   return self.model[key]
                },
                //把数据的属性赋给传进来的对象
                set(v) {
                    self.model[key] = v
                    // 渲染
                    self.render()
                }
                 })
             }
         }
         // 渲染的方法
         render() {
             let self = this
             // 获得页面上的数据并进行替换({{msg}}换成msg),然后再渲染到页面上 
             this.el.innerHTML = this.template.replace(/\{\{\w+\}\}/g,(str)=> {
                 let property = str.substring(2, str.length - 2).trim()
                 return self.data[property]
             })
             // 获取页面上的input框,再过滤除带有v-model属性的input,并把它们返回出去
             Array.from(this.el.querySelectorAll('input')).filter((item) => {
                return item.getAttribute('v-model')
             }).forEach((item) => {
                    let self = this
                    //遍历带有v-model属性的input框,再给他们设置oninput事件
                    let attributeName = item.getAttribute('v-model')
                    item.oninput = function () {
                        //获取input的value并设置给data里面的属性msg
                        self.data[attributeName] = this.value
                    }
                    //将input的value设置给data的属性msg
                    item.value = this.data[attributeName]
                 })
              }
         }
         //调用vue方法
         new Vue({
            el: '.box',
            data: {
               msg: 'aloha'
            }
         })
    </script>
</body>
</html>

深拷贝和浅拷贝

浅拷贝

概述 :

第一层拷贝它的值 , 第二层及之后拷贝的都是地址 , 相当于你拷贝的是一个快捷方式 , 这个快捷方式跟原本的不是一个 , 但里面的内容是一样的

  • Object.assign 实现浅拷贝

let obj = {name:'jack',list:[1,2,3],params:{'ok'}}
let copyObj = Object.assign({},obj)
console.log(obj == copyObj) //false
console.log(obj.list==copyObj.list)//true
  • Array.prototype.concat ( 数组的浅拷贝 )
//数组的浅拷贝 concat
let arr = [1, 3, 5, 7, { username: 'alex' }]
let copyArr = [].concat(arr)
console.log(arr == copyArr) //false
console.log(arr.username == copyArr.username) //true
  • Array.prototype.slice ( 数组的浅拷贝 )

 

// 3.数组的浅拷贝 slice
let copyArr1 = arr.slice() //截取全部
console.log(arr == copyArr1) //false
console.log(arr.username == copyArr1.username) //true
  • 扩展运算符
console.log('------扩展运算符--------');
let copyArr2 = [...arr]
console.log(arr == copyArr2) //false
console.log(arr.username == copyArr2.username) //true
  • 自定义函数实现浅拷贝
console.log('------函数--------');
function copy(obj) {
    //先用一个变量接收obj的构造函数
    let constructor = obj.constructor
    //再拷贝一下这个变量
    let copyObj1 = new constructor()
    //变量传入的obj
    for (let key in obj) {
        //拷贝的obj1里的地址=传入的obj的地址
        copyObj1[key] = obj[key]
    }
    //返回拷贝的obj1
    return copyObj1
}
let copyArr4 = copy(arr)
console.log(arr == copyArr4) //false
console.log(arr.username == copyArr4.username) //true
let copyObj2 = copy(obj)
console.log(obj == copyObj2) //false
console.log(obj.family == copyObj2.family) //true
  • _.clone () ( 第三方工具 ( lodash .js ) )
console.log('------lodash--------');
let copyArr3 = _.clone(arr)
console.log(arr == copyArr3) //false
console.log(arr.username == copyArr3.username) //true

深拷贝

概述 :

深拷贝是拷贝所有的内容 , 这两个内容相同的点只有值是一样的 , 引用地址都不一样

深拷贝的实现
  • 序列化和反序列化 ( JSON.stringify , JSON.parse )

// 1.序列化和反序列化
let obj = {
    list: [{
        name: '西瓜'
    }, {
        name: '椪柑'
    }, {
        name: '猕猴桃'
    }],
    price: 20,
    user: {
        userName: '张三'
    }
}
let copyObj = JSON.parse(JSON.stringify(obj))
console.log('-------序列化和反序列化---------')
console.log(obj == copyObj)
console.log(obj.list == copyObj.list)
console.log(obj.price == copyObj.price)
console.log(obj.user == copyObj.user)
  • _.cloneDeep ( 使用第三方工具 lodash.js )
<script src="https://cdn.jsdelivr.net/npm/[email protected]/lodash.min.js"></script>
<script>
    let copyObj2 = _.cloneDeep(obj)
    console.log('-------lodash---------')
    console.log(obj == copyObj2)
    console.log(obj.list == copyObj2.list)
    console.log(obj.price == copyObj2.price)
    console.log(obj.user == copyObj2.user)
</script>
  • 自定义函数实现深拷贝 ( 递归实现 )
function cloneDeep(obj) {
    //判断传入的obj是否为对象或者空,不是就返回值
    if (!(typeof obj == 'object' && obj)) {
        return obj
    }
    // 判断传入的obj是对象还是数组
    let copyObj1 = obj instanceof Array ? [] : {}
    // 遍历
    for (let key in obj) {
        copyObj1[key] = cloneDeep(obj[key])
    }
    return copyObj1
}
let copyObj1 = cloneDeep(obj)
console.log(copyObj1)
console.log(obj == copyObj1) //false
console.log(obj.list == copyObj1.list) //false
console.log(obj.price == copyObj1.price) //true
console.log(obj.user == copyObj1.user) //false

Vue原理介绍

虚拟dom

概述 : 虚拟dom顾名思义 就是虚拟的don对象 ( 对象 ) , 这个虚拟的dom对象跟实体的dom对象没有直接的关系 , 因为操作实体dom会造成大量的重绘和回流 ( 页面渲染次数增加 , 渲染速度变慢 ) . 为了解决这个问题 , vue就是先操作虚拟dom , 再通过虚拟dom渲染实体dom ( 只有一次 ) . 虚拟dom是存储在内存中的 , 它的形成是抽取了实体dom ( 模仿实体dom创建的对象 )

diff算法 ( 可用于性能优化 )

是用于比对的算法 , 它是比对虚拟dom内容的改变 , 然后通过这个改变来控制实体dom的内容变化

通过节点来进行对比的 ( 元素节点 , 属性节点 , 文本节点 )

节点比对流程

节点比对流程先比key ( 下标不能作为key ( 下标会变 ) ) , 然后比节点名 , 再比属性名 , 比对子节点

vue中有个patch的方法来帮助我们进行分类比较 , 比较完就进行渲染 ( 模板引擎mustache )

相关优化

生命周期优化 ( 预编译(挂载的时候) 、缓存(组件销毁的时候) 、回收资源 (组件销毁的时候))

打包优化 ( webpack / glup(核心 : 文件流))

标签:arr,Vue,console,log,day26,let,obj,拷贝
From: https://www.cnblogs.com/itlulu/p/16867585.html

相关文章

  • Vue路由实现的底层原理
    在Vue中利用数据劫持defineProperty在原型prototype上初始化了一些getter,分别是router代表当前Router的实例、router代表当前Router的实例、router代表当前Router的实例......
  • vue共享屏幕功能
    参考文档:https://developer.mozilla.org/zh-CN/docs/Web/API/MediaDevices/getDisplayMedia使用方法:https://developer.mozilla.org/zh-CN/docs/Web/API/Screen_Capture_A......
  • vue实现展开收起
    通过设置css超出换行,监听是否超出所设置的值,重新对数据插入标识,并刷新dom树实现。<divclass="class-datas"> <pclass="datas-title">可排课专业:</p> <p:class="`${......
  • 拖拽功能 vue + 移动端
    1.  在components里面创建一个公共组件,dragMove.vue<!--拖拽滑动效果--><template><divid="item_box"@click="goMove"@touchstart="down"@touchmove="move"......
  • vue2.0引入css文件后报错
    vue2.0的main.js中引入css文件后报错。报错示例:UncaughtError:Moduleparsefailed:/Users/**/Desktop/vue2/node_modules/.1.0.0-rc.5@element-ui/lib/theme-default/i......
  • vue项目中定义全局变量、全局函数
    在vue项目中,我们经常会遇到要在多个页面组件中都要使用的一个变量或者函数,比如说需要配置的ip地址,在生产环境和测试环境不一样就需要修改。因此我们可以定义一个全局变量来......
  • Vue构建一个项目
    vue2.0推荐开发环境Homebrew1.0.6(Mac)Node.js6.7.0npm3.10.3webpack1.13.2vue-cli2.4.0Atom1.10.2构建vue项目1、下载node.js下载地址:https://nodejs.org/en/检查是......
  • Vue 3.x 的 script setup 语法糖用法详解
    由于原来vue3中的setupCompositionAPI语法太过于冗长麻烦,官方又出了这么个语法糖,非常的好用了。这里介绍一些常用的语法:一、如何开始使用?1、需要关闭vetur插件,安装Vol......
  • 创建型设计模式-原型模式(深拷贝,浅拷贝)
    Person类:publicclassPerson{publicstringName{get;set;}publicintAge{get;set;}publicAddressAddress{get;set;......
  • vue组件间的通讯(10种方法)【重要】(待补充。。。)
    1.props/$emitprops主要用于父组件传递数据给子组件,父==>子。Vue自定义事件父组件可以在使用子组件的地方直接用v-on来监听子组件触发的事件。即父组件中使用v-on绑定自......