vue3.0 -初探 -持續(xù)更新中

一.創(chuàng)建vue工程方式有兩種

  • 傳統(tǒng)的 vue-cli 方式
##首先保證本地的vue-cli版本在4.5.0以上
vue --version
##如果不是,先升級(jí)最新的vue-cli工具
npm i -g @vue\vue-cli
## 然后和之前的創(chuàng)建vue2的方式一樣。
vue init webapack <project-name> ## 打包工具指定的是webpack
## 在后續(xù)list中,選擇[vue3]即可。

傳統(tǒng)的方式創(chuàng)建vue3,也沒(méi)問(wèn)題,但是這樣一來(lái)的打包工具仍然是webpack。

  • 使用 vite 創(chuàng)建
## 創(chuàng)建工程
npm init vite-app <project-name> # 指定了腳手架為vite 以及項(xiàng)目框架是vue3.x [為什么是vue3.0框架?因?yàn)檫@個(gè)vite工具就是vue3開(kāi)發(fā)團(tuán)隊(duì)寫(xiě)的,所以人家直接默認(rèn)就用 vite-app 創(chuàng)建的項(xiàng)目就是基于 vue3.0]

## 進(jìn)入功能目錄
cd <project-name>
## 安裝依賴
npm install
## 運(yùn)行 
npm run dev

使用 vite 方式創(chuàng)建,打包工具就是 vite 了,項(xiàng)目也沒(méi)有什么 build 文件夾,以及一堆 webpack.config.js webpack.base.js xxxxxx

二、 vue3.0中main.js文件

在 vue2.x 中,我們的 main.js 是這么寫(xiě)的。

import Vue from 'vue'
import App from './App'

const vm = new Vue({
    render(h) => h(App)
})
vm.$mount('#app')

在 vue3.0中是這么寫(xiě)的。

import { createApp } from 'vue'
import App from './App'

const app = createApp(App)
app.mount('#app')

在vue2.0中,我們直接調(diào)用 new Vue 構(gòu)造函數(shù)創(chuàng)建一個(gè)vm實(shí)例。在v3.0中,我們使用 createApp函數(shù),傳遞進(jìn)去一個(gè)options對(duì)象,來(lái)創(chuàng)建一個(gè)app實(shí)例。 后面的掛載都是一樣的。

你把 app 和 vm 打印到控制臺(tái)查看一下,就會(huì)發(fā)現(xiàn) app 比 vm 屬性少很多,也就是說(shuō) vue3.0 里的 app 更為輕量。

三、 Vue3.0中的 setup 函數(shù)

在 vue2.x 中,我們定義組件的數(shù)據(jù),方法,計(jì)算屬性,watch等都是以配置選項(xiàng)的方式來(lái)進(jìn)行的。

export default {
    name: 'App',
    data () {
        return {
            num:1
        }
    },
    methods: {},
    computed: {},
    watch: {}
}

在 vue3.0 中,所有需要的上述組件配置,都應(yīng)該定義在 setup 函數(shù)里,并返回。(為什么要返回?返回才會(huì)掛載在當(dāng)前組件實(shí)例上,才能在模板中使用。)

export default {
    name: 'App',
    setup () {
        // 我定義的函數(shù)
        // 我定義的數(shù)據(jù)
        // 我定義的watch
        // 我定義的計(jì)算屬性
        // .....
        return {
            我定義的函數(shù),
            我定義的數(shù)據(jù),
            我定義的,
            我定義的計(jì)算屬性
        }
    }
    
}

四、vue3.0中的ref函數(shù)

vue2.0 和 vue3.0 配置數(shù)據(jù)響應(yīng)式也有區(qū)別。

在 vue2.0中,我們把數(shù)據(jù)放在 data 選項(xiàng)里,就可以完成響應(yīng)式的配置了。

在vue3.0中,提供了更精細(xì)化的響應(yīng)式數(shù)據(jù)配置。

// vue3.0 ref 函數(shù)功能說(shuō)明
import { ref } from 'vue'
export default {
    name: 'App',
    setup () {
        // 定義一個(gè)基本數(shù)據(jù)類型響應(yīng)式
        let num = ref(100)
        // 返回的是一個(gè) RefImpl 的對(duì)象 RefImpl { ......}
        // 使用num
        num.value = 100  // 觸發(fā)setter
        console.log(num.value) // 觸發(fā)getter
        // 定義一個(gè)對(duì)象類型數(shù)
        let obj = ref({
            name: '張三-老工具人了',
            job: {
                detail: {
                    title: '前端開(kāi)發(fā)',
                    salary: 30
                }
            }
        })
        
        // 修改name屬性
        obj.value.name = '李四' //
        obj.value.job.detail.title = 'python開(kāi)發(fā)' 
        // tips: 可能有人覺(jué)得,obj.value.xxx 不如 obj.xxx 直接來(lái)的直觀,但是 ref 定義數(shù)據(jù)響應(yīng)式就是有這么一個(gè)特點(diǎn)。
        
        return {
            num, // 在模板中,使用num,不需要加.value
            obj
        }   
    }
}

// ref 函數(shù)內(nèi)部邏輯
// 1. 如果你傳遞的參數(shù)是基本數(shù)據(jù)類型,那么內(nèi)部直接使用Object.defineProperty來(lái)定義一個(gè)新屬性叫.value來(lái)實(shí)現(xiàn)響應(yīng)式。
// 2. 如果你傳遞的是一個(gè)對(duì)象數(shù)據(jù)類型,那么內(nèi)部使用 new Proxy 來(lái)定義數(shù)據(jù)的響應(yīng)式。
// 所以,對(duì)于ref來(lái)說(shuō),內(nèi)部選擇使用 Object.defineProperty 還是 new Proxy 取決于你傳遞進(jìn)來(lái)的數(shù)據(jù).
// 大概邏輯如下.
function ref (value) {
    return new RefImpl(value)
}

function RefImpl (value) {
    this.__v_Ref = true
    this.__rawValue = value
    this.__newValue = value
    // this.__shallowRef = fasle
    if (typeof value !== 'object') {
        Object.define(this,'value', {
            get () {
                return this.__newValue
            },
            set (newVal) {
                this.__newValue = newVal
            }
        })
    } else {
        this.value = new Proxy (this,{
            get (target,propertyName) {
                return Reflect.get(target,propertyName)
            },
             set (target,propertyName,value) {
                Reflect.set(target,proeprtyName,value)
             },
            deleteProperty (target,propertyName) {
                //...監(jiān)聽(tīng)delete屬性操作...
                Reflect.delete(target,propertyName)
            },
        })
    }
}

如果你給 ref 傳遞的是基本數(shù)據(jù)類型,那么 .value 拿到的就是由 Object.defineProperty定義的那個(gè) .value 屬性。

如果你給 ref 傳遞的是對(duì)象數(shù)據(jù)類型,那么 .value 拿到的就是有 new Proxy 定義的那個(gè)對(duì)象。

五、 vue3.0 中的 reactive 函數(shù)

在ref函數(shù)介紹里,我們有這么一段代碼

let obj = ref({
    name: '張三-老工具人了',
    job: {
        detail: {
            title: '前端開(kāi)發(fā)',
            salary: 30
        }
    }
})
obj.value.name = '李四' //
obj.value.job.detail.title = 'python開(kāi)發(fā)' 
// 可能有人覺(jué)得,obj.value.xxx 不如 obj.xxx 直接來(lái)的直觀,但是 ref 定義數(shù)據(jù)響應(yīng)式就是有這么一個(gè)特點(diǎn)。

可能有人覺(jué)得,obj.value.xxx 不如 obj.xxx 直接來(lái)的直觀,但是 ref 定義數(shù)據(jù)響應(yīng)式就是有這么一個(gè)特點(diǎn)。

所以,使用 ref 定義對(duì)象類型數(shù)據(jù),并不是很好的方式。

于是就有了 reactive 函數(shù)。

import { reactive } from 'vue'
export default {
    name:'App',
    setup () {
        let person = reactive({
             name: '張三-老工具人了',
            job: {
                    detail: {
                        title: '前端開(kāi)發(fā)',
                        salary: 30
                    }
                }
        })
        
        /// 訪問(wèn)數(shù)據(jù)
        console.log(person.name)
        // 修改屬性
        person.job.detail.title = 'python開(kāi)發(fā)' // 就沒(méi)有煩人的.value了。
        
        return {
            person
        }
    }
    
}

所以,對(duì)于對(duì)象數(shù)據(jù)類型,使用 reactive 比 ref 更為合適。

建議: 基本數(shù)據(jù)類型,使用 ref, 對(duì)象類型使用 reactive

注意:不要給基本數(shù)據(jù)類型使用reactive做響應(yīng)式,否則被報(bào)錯(cuò)

let num = reactive(0)

value cannot be made reactive: 0

總結(jié)ref和reactive

  • ref 可以定義基本數(shù)據(jù)類型響應(yīng)式,也可以定義對(duì)象類型數(shù)據(jù)響應(yīng)式
    • 當(dāng)你給 ref 傳遞基本數(shù)據(jù)類型時(shí),其內(nèi)部的.value是使用的Object.defineProperty來(lái)實(shí)現(xiàn)響應(yīng)式。
    • 當(dāng)給你ref傳遞對(duì)象類型數(shù)據(jù)是,其內(nèi)部的.value是使用的 new Proxy 來(lái)實(shí)現(xiàn)響應(yīng)式。
    • 使用 ref 定義響應(yīng)式,想訪問(wèn)到真實(shí)的數(shù)據(jù),必須加一個(gè) .value
  • reactive 只能定義對(duì)象類型數(shù)據(jù)響應(yīng)式

持續(xù)更新中......

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容