day26Vue相关内容及深拷贝和浅拷贝

Vue相关内容

概述:

Vue是前端的一个js库(诞生于2015年 兴起于2016年 尤雨溪(阿里巴巴)),Vue是一个MVVM模式的框架

MVVM概述

  • model 数据

  • view 视图

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

Vue的双向数据绑定

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

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

双向数据绑定运用表单标签的

代码实现(v-model指令)

 

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

流程

  • 获取所有的input框

  • 过滤哪个input有个属性叫v-model

  • 遍历所有加了v-model属性的属性值 对应data里面的数据值

  • 给对应的input添加监听事件 监听input的value变化

  • <!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="../js文件/myvue.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>

    设置给对应的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 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实现浅拷贝

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(数据的浅拷贝)

//数组的浅拷贝
let arr =[{
    username:'jack',
    password:'123'
},{
    usename:'tom'
    password:'456'
}]
//使用concat连接
let copyArr = [].concat(arr)
console.log(copyArr==arr)//fasle
cosnole.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

扩展运算符...

//使用扩展运算符
let copyArr2 = [...arr]
console.log(copyArr==arr)//false
console.log(copyArr[0]==arr[0])//true

自定义函数实现浅拷贝

//函数实现浅拷贝
funvtion copy(obj){
    //创建一个新的对象
    let constructor = obj.constructor
    let copyObj = new constructor()
    for(let key in obj){
        copyObj[key]==obj[key]
    }
    return
}
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

<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>

示例图

深拷贝

概述:

深拷贝是拷贝所有的内容,这两个相同点只在于里面的值相同,其他引用地址都不一样。相当于你用u盘拷贝一份资料,那么这份磁疗跟拷贝那份资料是没有任何关系,但是里面显示的内容是一样的

序列化和反序列化(JSON.stringty JSON.parase)

//使用序列化和反序列化
let obj = {
    list:[{
        name:'苹果'
    },{
          name:'香蕉'
          }]
}
//进行深拷贝
let copyObj = JSON.parase(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)

<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>

自定义函数实现深拷贝(递归实现)

//自定义函数实现深拷贝(递归)
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==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(下标会变)),比对对应的节点名,比对属性名,比对子节点。path的方法来帮你进行分类比较,比较进行渲染(模板引擎 模板引擎mustache)

相关优化

生命周期优化(预加载(挂载的时候)、缓存(组件销毁的时候)、回收资源(组件销毁的时候)、打包优化(webpack/glup)(文件流))

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Vue 中的拷贝拷贝是在处理对象和数组时常用的两种复制方式。下面是它们的简要介绍: 1. 拷贝拷贝是创建一个新对象或数组,将原始对象或数组的引用复制给新对象或数组,新旧对象或数组共享同一块内存空间。当修改其中一个对象或数组时,另一个也会受到影响。在 Vue 中,可以使用`Object.assign()`或解构赋值来实现拷贝。 示例代码: ```javascript // 对象拷贝 let obj = { a: 1, b: 2 }; let newObj = Object.assign({}, obj); console.log(newObj); // { a: 1, b: 2 } // 数组拷贝 let arr = [1, 2, 3]; let newArr = [...arr]; console.log(newArr); // [1, 2, 3] ``` 2. 拷贝拷贝是创建一个新对象或数组,并将原始对象或数组的所有属性值递归地复制给新对象或数组,新旧对象或数组不共享内存空间。当修改其中一个对象或数组时,另一个不会受到影响。在 Vue 中,可以使用`JSON.parse(JSON.stringify())`或第三方库(如 lodash 的`cloneDeep()`方法)来实现拷贝。 示例代码: ```javascript // 对象拷贝 let obj = { a: 1, b: { c: 2 } }; let newObj = JSON.parse(JSON.stringify(obj)); console.log(newObj); // { a: 1, b: { c: 2 } } // 数组拷贝 let arr = [1, [2, 3], { a: 4 }]; let newArr = JSON.parse(JSON.stringify(arr)); console.log(newArr); // [1, [2, 3], { a: 4 }] ``` 需要注意的是,使用 `JSON.parse(JSON.stringify())` 进行拷贝时,会忽略 undefined、symbol、函数等特殊值,并且无法处理引用循环的情况。在处理复杂对象或数组时,建议使用专门的拷贝库来确保拷贝的完整性和准确性。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值