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

Vue.js:

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

渐进式JavaScript框架

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

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 206,968评论 6 482
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,601评论 2 382
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 153,220评论 0 344
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,416评论 1 279
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,425评论 5 374
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,144评论 1 285
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,432评论 3 401
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,088评论 0 261
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,586评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,028评论 2 325
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,137评论 1 334
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,783评论 4 324
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,343评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,333评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,559评论 1 262
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,595评论 2 355
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,901评论 2 345

推荐阅读更多精彩内容