Vue3—01.初识Vue3与Vue2的区别 / 响应式原理 / Vue3新推出的组合式API思想

内容分享6天前发布
0 0 0

Vue.js:

渐进式JavaScript框架官方文档点我直达

Vue3—01.初识Vue3与Vue2的区别 / 响应式原理 / Vue3新推出的组合式API思想

Vue它是什么

是一套用于构建用户界面的渐进式框架,在使用Vue的时候,可以只使用Vue里面的一部分去配合其他前端框架一起开发,也可以整个项目从头到尾,从搭建项目,路由系统,全局的状态管理等全部使用Vue,超级灵活。Vue2学习资料可以看历史文章哦

一、初识Vue3

1.引入js文件,以开发版本来学习,下载到本地,第一引入Vue.js文件。

    <!-- Vue2 -->
    <!-- <script src="https://cdn.jsdelivr.net/npm/vue@2.6.14"></script> -->
   <!-- Vue3 -->
    <script src="https://unpkg.com/vue@next"></script>

2.Vue3创建一个Vue实例与Vue2创建一个实例的区别,在Vue3里面Vue是一个对象,通过该对象的createApp()方法,创建一个Vue实例,注意:在Vue3中,撤销了el选项,在Vue3中,无论论是组件和Vue实例,data选项都必须是一个方法,由方法返回对象。

<!DOCTYPE html>
<html>
<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>初识Vue3</title>
    <div id="app">
        <p>name:{{name}}</p>
        <p>age:{{age}}</p>
    </div>
</head>
<body>
    <!-- Vue2 -->
    <!-- <script src="https://cdn.jsdelivr.net/npm/vue@2.6.14"></script> -->
    <!-- Vue3 -->
    <script src="https://unpkg.com/vue@next"></script> 
   <script>
   //    Vue2创建一个Vue实例
    //    在Vue2里面的Vue是一个构造函数,通过该构造函数创建一个Vue实例
    //    new Vue({
    //         //指定当前Vue对象操作的DOM容器
    //         el: #app ,
    //         在Vue2中,data选项可以是对象,也可以是方法返回一个对象
    //         //定义当前Vue对象管理的数据
    //         data:{
    //             name: Vue2 ,
    //             age: 3 
    //         }.$mount( #app )
    //         Vue2可以通过el选项指定一个挂载的容器,也可以通过$mount()方法置顶挂载的容器
    //     })
    // Vue3创建一个Vue实例
    // 在Vue3里面Vue是一个对象,通过该对象的createApp()方法,创建一个Vue实例
      Vue.createApp({

    // 注意:在Vue3中,撤销了el选项
    // 注意:在Vue3中,无论是组件和Vue实例,data选项都必须是一个方法,由方法返回对象    
          data() {
              return {
                  name: Vue3 ,
                  age:2
              }
          },
      }).mount( #app )
   </script>
</body>
</html>

二、响应式

1.Vue3修复了Vue2中响应式的所有缺陷。什么是响应式?当数据变化,页面也会随之变化,例如Vue2的响应式:不能直接给对象添加属性,删除对象的属性,不能直接操作数组的下标,但是,Vue2同时也提供了解决这些问题的方案。

<!DOCTYPE html>
<html>

<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>初识Vue2和Vue3的响应式</title>
    <div id="app">
        <p>{{student}}</p>
        <button @click= reviseName >修改name</button>
        <button @click= reviseAge >修改age</button>
        <button @click= addSex >添加sex</button>
        <button @click= delSex >删除sex</button>
    </div>
</head>
<body>
    <!-- Vue2 -->
    <!-- <script src="https://cdn.jsdelivr.net/npm/vue@2.6.14"></script> -->
    <!-- Vue3 -->
    <script src="https://unpkg.com/vue@next"></script>
    <script>
        //    Vue2
        // new Vue({
        //     el: "#app",
        //     data: {
        //         student: {
        //             name:  萌新 ,
        //             age: 3
        //         }
        //     },
        //     methods: {
        //         reviseName(){
        //             this.student.name =  Vue3 
        //         },
        //         reviseAge(){
        //             this.student.age =  30 
        //         },
        //         addSex(){
        //             // 直接给对象添加的属性,不具备响应式
        //             // this.student.sex =  男 
        //             // 如果要给对象添加属性,并且添加的属性也要具备响应式,要使用$set方法
        //             // 方法的第一个参数是指定的对象,第二个参数是属性名,第三个参数是属性值。
        //             // this.$set(this.student, sex , 男 )
        //             // console.log(this.student);
       //               也可以通过$forceUpdate()强制更新页面一次 不推荐
       //               this.$forceUpdate()
        //         },
        //         delSex(){
        //             // 直接删除对象身上的属性,是不具备响应式的
        //             // delete this.student.sex
        //              // 如果要删除对象身上的属性,并且还要具备响应式,要使用$delete方法
        //              // 方法的第一个参数是指定的对象,第二个参数是属性名
        //             //  this.$delete(this.student, sex )
        //             //  console.log(this.student);
        //         }
        //     },
        // })
        //    Vue3
        Vue.createApp({
            data() {
                return {
                    student:{
                        name: 萌新 ,
                        age:3
                    }
                }
            },
            methods: {
                reviseName(){
                    this.student.name =  Vue3 
                },
                reviseAge(){
                    this.student.age =  30 
                },
                addSex(){
                    // 在Vue3中,直接给对象添加属性,新的属性依然具备响应式
                    this.student.sex =  男 
                },
                delSex(){
                    // 在Vue3中,直接删除对象的属性,依然具备响应式
                    delete this.student.sex
                }
            },
        }).mount( #app )
    </script>
</body>
</html>

三、响应式原理

1.vue2在实例化时,会将data里面的所有数据采用Object.defineProperty进行处理,实现实现响应式功能。
2.但是你之后往data里面添加的数据,由于没有来用 object.defineProperty进行处理,所以不具备响应式。
3.$set()方法,内部就是对单个属性重新采用 0bject.defineProperty进行处理,从而具备响应式。

<!DOCTYPE html>
<html>
<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>Vue2和Vue3的响应式原理</title>
    <div id="app">
        <h2 id="name"></h2>
        <h2 id="age"></h2>
    </div>
</head>
<body>
    <!-- Vue2 -->
    <!-- <script src="https://cdn.jsdelivr.net/npm/vue@2.6.14"></script> -->
    <!-- Vue3 -->
    <!-- <script src="https://unpkg.com/vue@next"></script> -->
    <script>
        // Vue2的响应式原理:
        // 这里的obj是源对象
        let obj = {
            name:  Vue2 ,
            age: 3
        }
        // 在页面中显示姓名和年龄
        document.getElementById( name ).innerText = obj.name
        document.getElementById( age ).innerText = obj.age
        // 这里的obj2代理对象---由obj2代理obj
        let obj2 = {}
        // 通过Object.defineProperty方法,给obj2添加属性
        Object.defineProperty(obj2,  name , {
        // 读取属性的值,调用get方法
            get() {
                return obj.name
            },
        // 设置属性的值,调用set方法    
            set(value) {
                obj.name = value
                document.getElementById( name ).innerText = obj.name
            }
        })
        // 给obj2定义age属性
        Object.defineProperty(obj2,  age , {
            get() {
                return obj.age
            },
            set(value) {
                obj.age = value
                document.getElementById( age ).innerText = obj.age
            }
        }) 
        // vue2在实例化时,会将data里面的所有数据采用Object.defineProperty进行处理,实现实现响应式功能。
        // 但是你之后往data里面添加的数据,由于没有来用 object.defineProperty进行处理,所以不具备响应式。
        // $set()方法,内部就是对单个属性重新采用 0bject.defineProperty进行处理,从而具备响应式。

    </script>
</body>
</html>

2.在Vue3中响应式,无论是代码量还是性能,Proxy更加有优势。

// Vue3的响应式原理:
// 这里的obj是源对象
let obj = {
    name: Vue3 ,
    age:3
}
// 在页面中显示姓名和年龄
document.getElementById( name ).innerText = obj.name
document.getElementById( age ).innerText = obj.age
// 这里的obj2代理对象---由obj2代理obj
// new Proxy(源对象,{...})的方式,创建代理对象
let obj2 = new Proxy(obj,{
    //读取属性,参数分别是:源对象,属性名
    get(target, property){
        // 直接根据源对象返回源对象身上的属性
        // return target[property]
        // 通过发射对象,发射输出源对象身上的属性
        return Reflect.get(target,property)
    },
    //设置属性,参数分别是:源对象,属性名,属性值
    set(target, property,value){
        // target[property] = value
        if(Reflect.has(target,property)){
            Reflect.set(target, property,value)
            document.getElementById(`${property}`).innerText = value
        }
    },
    //删除属性,参数分别是:源对象,属性名
    deleteProperty(target, property){
        // return delete target[property]
 //官方说,用这个方式发射,性能更好,更快
        Reflect.deleteProperty(target, property)
    }
})

四、引出Vue3新推出的组合式API

Vue3引入了全新的功能,叫组合式api,它是什么,可以理解为Vue新推出的一些方法,作用是:讲原来分散开来定义的数据,方法,计算属性,监听器,组合起来定义一个完整的业务,统一在setup中使用,在setup中,直接定义的数据是不具备响应式的,如果要使数据具备响应式,需要使用ref组合式API对数据进行包装,包装后返回的是ref对象。

<div id="app">
    <div>
        <h2>学生信息</h2>
        <!-- 注意:ref对象在模板只不需要.value的方式获取里面的值 -->
        <h4>姓名:{{stuName}}</h4>
        <h4>年龄:{{stuAge}}</h4>
        <button @click="updateStu">修改学生信息</button>
    </div>
    <div>
        <h2>汽车信息</h2>
        <h4>车名:{{carName}}</h4>
        <h4>车价:{{carPrice}}</h4>
        <button @click="updateCar">修改汽车信息</button>
    </div>
    <div>
        <h2>手机信息</h2>
        <h4>名称:{{phoneName}}</h4>
        <h4>颜色:{{phoneColor}}</h4>
        <button @click="updatePhone">修改手机信息</button>
    </div>
    <div>
        <h2>食物信息</h2>
        <h4>名称:{{foodName}}</h4>
        <h4>价格:{{foodPrice}}</h4>
        <button @click="updateFood">修改食物信息</button>
    </div>
</div>
// 什么是组合式API(Composition API),就是Vue推出的一些新的方法,这个方法在setup中使用
// 从Vue身上获取ref组合式API函数
let {ref} = Vue
Vue.createApp({
    // 注意:Vue2中,Vue实例的data选项可以是一个对象,也可以是一个方法,由方法返回一个对象
    // 但是,组件中data选项必须是一个方法。
    // Vue3中,无论是Vue实例,还是组件,data选项都必须是一个方法。
    // 我们之前习惯将所有的数据放在data选项中定义,所有的方法放在methods选项中定义,
    // 所有的计算属性放在computed选项中定义,所有的侦听器放在watch选项中定义,
    // 这样就会导致一个业务的代码会拆分到多个结构中去写,如果一个页面中要操作许多个业务,代码后期维护成本会很高。
    // 所以,Vue3引入了组合式API,简化之前繁琐的过程,将一样业务的代码靠在一起写。
    /* data: function () {
        return {
            //定义学生数据
            stuName:  张三 ,
            stuAge:  20 ,
            //汽车信息
            carName:  奔驰 ,
            carPrice:  50W ,
            //手机信息
            phoneName:  iphone ,
            phoneColor:  白色 ,
            //食物信息
            foodName:  汉堡 ,
            foodPrice:  ¥20 
        }
    }, 
    methods: {
        //修改学生的方法
        updateStu(){
            this.stuName =  李四 
            this.stuAge = 30
        },
        //修改汽车的方法
        updateCar(){
            this.carName =  宝马 
            this.carPrice =  40W 
        },
        //修改手机的方法
        updatePhone(){
            this.phoneName =  华为 
            this.phoneColor =  蓝色 
        },
        updateFood(){
            this.foodName =  蛋糕 
            this.foodPrice =  ¥30 
        }
    }, */
    // setup方法是所有组合式API的入口
    setup() {
        // 定义学生的信息
        // 在setup中,直接定义的数据是不具备响应式的,
        // 如果要使数据具备响应式,需要使用ref组合式API对数据进行包装,包装后返回的是ref对象
        let stuName = ref( 张三 )
        let stuAge = ref( 20 )
        let updateStu = () => {
            //ref对象的value属性保存的是值
            stuName.value =  李四 
            stuAge.value = 30
        }
        // 定义汽车的信息
        let carName = ref( 奔驰 )
        let carPrice = ref( 50W )
        let updateCar = () => {
            carName.value =  宝马 
            carPrice.value =  40W 
        }
        // 定义手机的信息
        let phoneName = ref( iphone )
        let phoneColor = ref( 白色 )
        let updatePhone = () => {
            phoneName.value =  华为 
            phoneColor.value =  蓝色 
        }
        // 定义食物的信息
        let foodName = ref( 汉堡 )
        let foodPrice = ref( ¥20 )
        let updateFood = () => {
            foodName.value =  蛋糕 
            foodPrice.value =  ¥30 
        }

        //返回模板中需要使用的数据
        return{
            stuName,
            stuAge,
            updateStu,
            carName,
            carPrice,
            updateCar,
            phoneName,
            phoneColor,
            updatePhone,
            foodName,
            foodPrice,
            updateFood
        }
    }
}).mount( #app )

Over

© 版权声明

相关文章

暂无评论

none
暂无评论...