前言:
從今天開始來和大家一起學習 vue3 相信大家都不陌生,已經火了一段時間了,但是還是有不少人沒有學習,那就跟著六扇老師來簡單的入個門
廢話不多說,來開始今天的學習
Vue3 簡介:
2020年,9月,18日,Vue.js釋出3.0版本,耗時兩年多,2600+次提交,99位貢獻值
github 上的 tags 地址 :https://github.com/vuejs/core/releases/tag/v3.0.0
Vue3 帶來了什麼:
- 效能的提升,更快,更小,打包大小減少,初次渲染,更新渲染更快,記憶體減小
- 原始碼的升級,使用 Proxy 代替 defineProperty 實現響應式,重新寫了虛擬 DOM 的實現 - 讓虛擬DO M 更快了 和 Tree-Shaking - 術語 幹掉了沒有使用的程式碼,讓打包體積更小
- 擁抱了 TS ,vue3 更好的支援 TypeScript
- 增加了新特性
Composltlon API (組合 API)
- setup 配置
- ref 、 reactive
- watch 、watchEffect
- provide 、 inject
新的內建元件
- Fragment
- Teleport
- Suspense
其他
新的生命週期鉤子
data 不再是物件,始終是一個函式
......
上邊的東西只是一個瞭解,混一個臉熟,不會,看不懂也沒有關係,後邊我們會一個個講,看一遍就會的,尤其是有 vue2 基礎的
說了怎麼,不如上手寫寫一遍,下面我們就開始建立我們的 vue3
vue3 的建立:
建立 vue3 專案有兩種方式,一種是 vue 傳統的建立方式 一種是 vite 建立
- 使用 vue-cli 建立
vue create vue3專案的name
- 使用 vite 建立
當然這裡插一個題外話,什麼是 vite ----- 下一代前端構建工具差不多也是新一代了,現一代是webpack
vite 官網 :https://cn.vitejs.dev/
vite 有什麼優勢呢?
- 開發環境中,無需打包操作,快速的冷啟動
- 熱過載(HMR) 更輕量,快 (區域性重新整理)
- 按需編譯,不用再等待整個應用的編譯
vite 優勢也差不多就是特點
傳統的構建相信用過 webpack 都知道,他是透過入口檔案然後分析路由,再去分析模組,都分析完了進行打包,然後告訴你伺服器準備好了
vite 構建的工作模式,一上來就給使用者準備好伺服器,然後等待使用者請求,假如你發起了一個請求,然後 vite 會根據你的路徑 進入 入口檔案然後找到 你的路由,分析該路由的模組,然後給你 (動態的引入和程式碼分割)
用 vite 建立 vue3
npm init vite-app vue3專案的name
當然 vite 建立是沒有依賴的,需要進入專案自己在 npm i
而且 vite 自配置的啟動 是 npm run dev
vite 會更快,不信你就都下載然後對比一下,實踐出真理
分析工程結構圖:
接下來讓我們分析一下 vue3 的工程結構 看看和 vue2 到底有什麼區別,我們以 vue-cli 下載好的 vue3 專案為例
開啟檔案,我們發現 vue3 的目錄結構和擺放位置都和 vue2 一樣沒什麼區別
只不過 vue3 檔案裡面的一些語法和 vue2 不同
接下來我們來分析吧,如何分析?
main.js
首先我們開啟專案的入口檔案 main.js,一共寫了三行程式碼,和 vue2 不同了吧
import { createApp } from 'vue'
import App from './App.vue'
createApp(App).mount('#app')
其中 import App from './App.vue' 我們見過在 vue2 中也有 意思是 引入所有元件的外殼元件,也就是所有元件的父親
import { createApp } from 'vue' 引入的不再是 Vue 建構函式了 是有一個 createApp 應用的例項物件,工廠函式
vue2 裡面 我們是 new 一個 vue 是一個建構函式
vue3 createApp 直接是 一個工廠函式 ,可以直接呼叫
有什麼不同呢?
來我們先回憶一下 vue2 中的寫法,
new Vue({
render:(h)=>{
return h(app)
}
}).$mount('#app')
我們拆解一下
const vm = new vue({render:h => h(app)})
vm.$mount('#app')
這是之前的寫法,接下來我們再把 createApp(App).mount('#app') 拆解
const app = createApp(App)
app.mount('#app')
這樣一對比是不是明白了
const app = createApp(App) 其實就是 建立例項應用物件 (和 vue2 裡面的 vm 類似 但 app 更輕)
app本質就是一個物件,裡面好多東西,vm裡面很多需要的不需要的都放在裡面,但 app 更精,減少了不需要的東西,所以“輕”了
App.vue
入口檔案分析完了,我們按照程式碼執行的方式,接下來分析 App.vue
進入 App.vue 和 vue2 一樣 template script style 沒區別
但是有一個地方發生變化了,那就是 template 裡邊沒有 div 了
vue3 元件中的模板結構可以沒有根標籤了(可以有,可以沒有)寫不寫都行了
Composition Api 初識:
composition 組合式 API 這概念有點長,有點多,不太好理解,先不講,暫時知道 composition 是組合式 AIP 就行
setup:
想玩 vue3 最好就是先學 setup,因為 setup 是 所有組合式API(comosition)的大舞臺
setup是什麼?
是 vue3 中一個新的配置項,一個函式,新增
頁面中需要的資料,也就是元件中所應用的資料,方法,生命週期,計算屬性等等等,都要配置寫在 setup 中
那怎麼配置呢,直接上手,寫程式碼
export default {
name: 'App',
setup(){
let name = '六扇老師'
let age = '18'
// 方法
function sayHello(){ alert(`你們好,我是${name},今年${age}`) }
},
}
和 vue2 不一樣了,我們 vue3 需要資料不用 data 了 直接寫就行了
setup 的返回值
寫完問題也就來了,誒六扇老師,我光寫完資料和方法了,我在元件中怎麼使用呢?
這裡就要說 setup 的返回值了,它有兩種一種是返回物件,一種是渲染函式
- 若 setup 返回的是一個物件,則物件中的屬性,方法,直接就可以在模板中使用,和 vue2 一樣 (主要的內容)
setup(){
let name = '六扇老師'
let age = '18'
function sayHello(){ alert(`你們好,我是${name},今年${age}`) }
return { name, age, sayHello, }
},
我們直接在 setup 最後加一個 return 返回我們的 資料
然後再模板中和 vue2 一樣去引用,啟動專案
接下來我們再看 setup 的另一種返回值
- 返回一個渲染函式,可以自定義渲染內容(瞭解就行,不常用)
可以看到我們上邊寫的也不生效了,setup 返回的渲染函式為主了
當然返回的渲染函式前提需要引入 h ,渲染函式
題外話:vue3 是向下相容的,你可以在 vue3 中寫 vue2 語法的程式碼,如果都寫一起得話,在 vue2 的方法中能獲取到 vue3 裡面 setup 的值
但是 在 vue3 中 不能獲取到 vue2 中 data 的值,而且如果有同名的,setup 優先
不建議與 vue2 配置混用,因為不知道什麼時候就不相容了,要不還學 vue3 幹嘛
setup 不能是一個 async 函式,因為返回值不再是 return 的物件,而是 promise, 模板看不到 retuen 裡面的資料物件
ref 函式
ref初識
我們在 vue2 的時候學過 ref ,是一個標籤屬性,給一個元素打標識,方便我們拿到,然後使用
但 vue3 裡面多了一個名為 ref 的函式
在學習 ref 函式之前我們先思考一個問題,上邊我們已經寫了資料,那如何修改呢?
老師我知道,直接寫一個函式,然後呼叫,讓 name 等於別的就修改了
我們可以看到,這樣寫了之後,資料是修改了,但是頁面卻沒有修改,也就是 vue 沒有發現
vue 不認識,也就是說你這樣定義的資料它只是普通的資料,根本不是響應式資料
那如何把普通的資料變成 vue 可以監測到的響應式資料呢,這就用到了 ref 函式
首先我們要先引入我們的 ref 函式
import {ref} from 'vue'
export default {
setup(){
let name = ref('六扇老師')
let age = ref('18')
function changeInfo(){
console.log(name,age)
}
return { name, age, changeInfo, }
}
我們看用 ref 函式更改完的資料,它是一個 RefImpl 的例項物件,那什麼是 RefImpl 物件?
我們拆開來看,Ref ---> reference 引用,Impl implement 實現
那 RefImpl 標準的稱呼就是"引用實現的例項物件",簡稱引用物件
然後我們看裡面,其他的值我們不看,就看一個 value 和 原型物件裡面的 set 和 get
熟悉吧,和 vue2 一樣,拿到你的資料,然後透過 set 和 get 修改,然後頁面等等等
那怎麼修改呢,直接在你要修改的值後邊加上 .value 就修改完成了
小知識:template 元件裡面的發現 ref 物件會自動獲取到 value 值,所以直接寫就能獲取到值
ref 複雜物件
弄完基本型別資料,我們用 ref 寫一個物件型別
資料有了,那我們怎麼更改呢,其實也簡單,看圖我也經把 job.value 列印出來了
直接 job.value.type = 什麼值,就可以更改了
那問題來了 ref 加工之後不是都 RefImpl 物件嗎,為什麼 job.value 變成 Proxy 物件了呢,帶著這個問題,往下看 reactive 函式
總結:
ref 的作用,定義了一個響應式資料。建立了一個包含響應式資料的引用物件(reference物件,簡稱 ref 物件)
接受的資料可以是:基本型別,也可以是:物件型別
基本型別的資料:和 vue2 一樣響應式依然是靠 Object.defineProperty() 的 get 與 set 完成的
物件型別的資料:內部 求助 了 vue3 中的一個新函式 reactive 函式
題外話:vue3 接受到 物件型別的資料,底層就是 用 ES6 新語法 Proxy 來處理的,但是在 vue3 中並沒有直接使用,而是被封裝到 reactive 函式里面
reactive 函式
reactive 只能定義物件型別和陣列的響應式資料 (基本型別用 ref ),之所以 ref 可以是因為 ref 內部求助了 reactive
用完 reactive 之後就和正常使用一樣了,直接點就行
當然陣列也是同理,直接放在裡面寫就行了,物件怎麼用他怎麼用,而且還能直接透過索引去改,這是 vue2 辦不到的
let arr = reactive(["學習","喝酒","燙頭"])
function changeInfo(){
arr[0] = "抽菸"
}
reactive 的語法:
const 代理物件 = reactive(原物件),接受到一個物件或陣列,返回一個代理物件(Proxy的例項物件)
reactive 定義的響應式資料是更深層次的,不管有多深都能點出來
內部是透過 ES6 的 Proxy 實現,透過代理物件操作原對內部資料進行操作,並且這種操作是可以被 vue 所捕獲到的,也就是我們說的資料劫持
題外話:
學到這裡有同學該問了,那老師這樣寫太墨跡了,一會 ref . vaule 一會 reactive 不點咋解決呢
還是那句話,程式碼是死的人是活的,就像我們這幾個資料,你可以直接這樣去寫
這樣是不是語法語義都正確了,而且還省事了,但是我還是覺得有點麻煩,不想點來點去的,別急留一個問題,我們下章再講