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閱讀 228,412評論 6 532
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 98,514評論 3 416
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 176,373評論 0 374
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 62,975評論 1 312
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 71,743評論 6 410
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,199評論 1 324
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,262評論 3 441
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,414評論 0 288
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 48,951評論 1 336
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 40,780評論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 42,983評論 1 369
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,527評論 5 359
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,218評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,649評論 0 26
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,889評論 1 286
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,673評論 3 391
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 47,967評論 2 374

推薦閱讀更多精彩內容