Vite+Vue3+TypeScript學習筆記


1、學習背景
隨着前端web應用的需求不斷發展和變化,vue生態圈也緊跟開發者步伐,不斷演化。盡管vue2.0已經很完善了,很多人掌握的vue2.0,感覺實在學不動了,意料之外的是尤先生繼續更新vue到3.0版本,以補充vue2.0的不足之處。隨着vue3.0問世,vite2.5.1也油然而生,vue始終沒有放棄對項目響應速度和編譯速度的追求,vite的到來,對於前端開發者而言,簡直不要太幸福了。vue3.0不僅全面支持TypeScript語法,還對生命周期鈎子進行了優化和剔除,加上工具setup的語法糖,vue單頁面多個根元素的擴展,代碼精簡不說,還很有條理,vue3.0的出現再次提升了開發者的編碼體驗和幸福感。另外vue3整合typescript語言是前端未來發展的必然趨勢,而生為vue家族的新成員vite也是前端技術愛好者的學習目標,贏在起點,從學習新技術開始。活到老,學到老,是一個合格前端開發者的畢生信仰。
2、vite簡介
vite誕生是為了提升web項目運行性能,以更快的速度將應用頁面展示給用戶。Vite 以 原生 ESM 方式提供源碼。這實際上是讓瀏覽器接管了打包程序的部分工作:Vite 只需要在瀏覽器請求源碼時進行轉換並按需提供源碼。根據情景動態導入代碼,即只在當前屏幕上實際使用時才會被處理。
提供的驅動力:
2.1、優化緩慢的服務器啟動(冷啟動開發服務器和正式環境響應速度);
2.2、優化緩慢的項目更新(vite服務器);

3、vite創建項目
兼容性注意:
Vite 需要 Node.js 版本 >= 12.0.0。
必須安裝Volar插件,用vscode編輯器
// 安裝vite
1、npm init vite@latest

// 安裝vite同時創建vite項目
2、npm init vite@latest my-vue-app --template vue
{
"scripts": {
"dev": "vite", // 啟動開發服務器
"build": "vite build", // 為生產環境構建產物
"serve": "vite preview" // 本地預覽生產構建產物
}
}
4、版本依賴兼容和項目目錄介紹
package.json版本依賴說明, 這里是整個項目依賴版本配置,相關安裝指令后面視頻中會逐個教大家如何安裝。
注意:vuex和router都是4.0及以上版本的,否則用vue3時,找不到暴露的api
{
"name": "vite-ts-vue3-plus-demo",
"version": "0.0.0",
"scripts": {
"dev": "vite",
"build": "vue-tsc --noEmit && vite build",
"serve": "vite preview"
},
"dependencies": {
"@element-plus/icons": "0.0.11",
"dotenv": "^10.0.0",
"element-plus": "^1.1.0-beta.7",
"vue": "^3.0.5",
"vue-router": "^4.0.11",
"vuex": "^4.0.2"
},
"devDependencies": {
"@types/node": "^16.7.1",
"@vitejs/plugin-vue": "^1.3.0",
"@vue/compiler-sfc": "^3.0.5",
"node-sass": "^6.0.1",
"sass": "^1.38.1",
"sass-loader": "^12.1.0",
"typescript": "^4.3.2",
"vite": "^2.4.4",
"vue-tsc": "^0.2.2"
}
}
5、setup語法糖使用
5.1 setup前身組合式API(基礎用法)
注意:在setup()中不能用this
setup 中你應該避免使用 this,因為它不會找到組件實例。setup 的調用發生在 data property、computed property 或 methods 被解析之前,所以它們無法在 setup 中被獲取,這也是為了避免setup()和其他選項式API混淆。
/* 參數說明

  • props 是響應式的,當傳入新的 prop 時,它將被更新
  • context 是一個普通的上下文JavaScript對象,它暴露組件的三個 property(包括屬性,插槽,方法),
  • 如下示例1所示
    */
    // 示例1

5.2 setup后世(高級用法),推薦用法
注意:defineProps不需要引入,vue單文件內部自動暴露的API

// 高級用法

6、defineProps 和 defineEmits
注意:defineProps 和 defineEmits 都是只在 6.2 、父組件vue 溫馨提示:這里介紹一哈volar插件小圖標在vue文件里的作用: 點擊這個三角形圖標,會將文件歸類顯示,方便編寫代碼;

7、正確使用defineExpose
使用

7.2、父組件調用子組件方法和屬性

7.3 在setup如何定義變量(字符串,對象,數組)

{{count}} {{user.name}}


{{item}}
<button @click="setName">點擊我增加

8、Watch和WatchEffect
1、基本使用方法:

{{originData.count}} {{originData.user.name}}


{{item}}


<button @click="incriment">點擊我count增加

2、watch與 watchEffect 比較,推薦watch監聽
watch: 頁面更新后不會立即執行,而watchEffect 它會執行;
如果要實現:watch在頁面更新之后就執行,需要增加立即執行的屬性;
watch([count,originData.user], (n, o)=> {console.log(n[0],n[1].name)}, {deep: true, immediate: true})
1、watch和watchEffect都懶執行副作用,不過watchEffect比較頻繁,在vue組件更新之前執行;
2、watch更具體地說明什么狀態應該觸發偵聽器重新運行,watchEffect就沒有這么友好;
3、watch訪問偵聽狀態變化前后的值。
9、在setup中的生命周期鈎子
因為 setup 是圍繞 beforeCreate 和 created 生命周期鈎子運行的,所以不需要顯式地定義它們。換句話說,在這些鈎子中編寫的任何代碼都應該直接在 setup 函數中編寫。
下表包含如何在 setup () 內部調用生命周期鈎子:
選項式 APIHook inside setup
beforeCreateNot needed* 不需要
createdNot needed* 不需要
beforeMountonBeforeMount 掛載之前
mountedonMounted 頁面加載完成時執行
beforeUpdateonBeforeUpdate
updatedonUpdated
beforeUnmountonBeforeUnmount
unmountedonUnmounted 頁面銷毀時執行
errorCapturedonErrorCaptured
renderTrackedonRenderTracked
renderTriggeredonRenderTriggered
activatedonActivated
deactivatedonDeactivated

10、用Ts限制define(Emits|Props)參數類型
注意:
1、在setup語法糖中引入組件不需要注冊聲明就可以直接用了
2、ts 限制組件傳參類型,默認是必須傳值的,否則控制台出現警告, 引入組件的地方會出現紅色提醒,不想必傳在綁定參數后加?即可
3、ts傳參支持多種類型校驗,一個參數可以傳字符串,數組,Boolean等
4、用ts方式限制defineEmits和defineProps參數類型
1、子組件

{{msg}}


{{title}}


<input v-model="inputValue" type="text" @blur="handleUpdate($event)">

2、父組件

11、遞歸組件
一個單文件組件可以通過它的文件名被其自己所引用。例如:名為 FooBar.vue 的組件可以在其模板中用 引用它自己。
請注意這種方式相比於 import 導入的組件優先級更低。如果有命名的 import 導入和組件的推斷名沖突了,可以使用 import 別名導入:
import { FooBar as FooBarChild } from './components'
注意:這里有小問題,當單文件引入單文件時會出現內存溢出現象
12、component動態組件
由於組件被引用為變量而不是作為字符串鍵來注冊的,在 13、ts限制普通函數/箭頭函數參數類型 13.1 普通函數 13.2 箭頭函數,推薦用法 14、引入vuex配置和使用 14.1 創建項目時我們已經引入了vuex4.0版本,接下來我們就開始配置vuex4.0並測試。 // 注意必須安裝vuex4.0版本及以上 npm install vuex@next --save #or yarn add vuex@next --save 14.2 在src目錄下創建store文件夾,新建文件index.ts, index.ts內容如下所示: import { InjectionKey } from 'vue' /** * 引入 InjectionKey 並將其傳入 useStore 使用過的任何地方, * 很快就會成為一項重復性的工作。為了簡化問題,可以定義自己 * 的組合式函數來檢索類型化的 store */ // 未簡化useStore版 // import { createStore, Store } from 'vuex' // 簡化useStore版 import { useStore as baseUseStore, createStore, Store} from 'vuex'

// 為 store state 聲明類型
export interface State {
username: string,
count: number
}

// 定義 injection key
export const key: InjectionKey<Store > = Symbol()

// 導出store模塊
export const store = createStore ({
state: {
username: "測試store",
count: 0
},
getters:{
getName: state =>{
return state.username
}
},
mutations: {
// 重置名稱
SET_NAME(state, params:string) {
state.username = params
}
},
actions:{}
})

// 定義自己的 useStore 組合式函數
export function useStore () {
return baseUseStore(key)
}
14.3 在根目錄下新建vuex-d.ts文件,內容如下所示:
// 一個聲明文件來聲明 Vue 的自定義類型 ComponentCustomProperties
import { ComponentCustomProperties } from 'vue';
import { Store } from 'vuex';

declare module '@vue/runtime-core' {
// 聲明自己的 store state
interface State {
count: number,
username: string
}
// 為 this.$store 提供類型聲明
interface ComponentCustomProperties {
$store: Store
}
}
14.4 在main.ts中注入store模塊
import { createApp } from 'vue';
import App from './App.vue';
// 導入store模塊, 傳入 injection key
import { store, key } from '@/store';
const app = createApp(App)
app.use(store, key)
app.mount('#app')
14.5 引用測試vuex配置是否正確
<el-button @click="changeName" size="small">點擊修改名稱

15、router配置以及使用詳解
15.1 安裝
創建項目時我們已經引入了router4.0版本,接下來我們就開始配置router4.0並測試。
// 注意:安裝router必須是4.0及以上
npm install vue-router@4
15.2 頁面准備
目錄結構

頁面具體內容:
1、layout/index.vue



2、layout/header/index.vue


<h2 @click="handleClick(1)">首頁
<h2 @click="handleClick(0)">關於

3、pages/home/index.vue

home



4、pages/about/index.vue

15.3 在src目錄下創建router文件夾,然后創建index.ts文件,內容如下所示:
import { createRouter, createWebHashHistory } from "vue-router";
import LayOut from "../components/layout/index.vue";

const routes = [
{
path: '/',
component: LayOut,
redirect: '/home',
children:[
{
path: '/home',
name: 'home',
component: ()=> import("../pages/home/index.vue"),
meta:{
title: '首頁',
icon: ''
}
},
{
path: '/about',
name: 'about',
component: ()=> import("../pages/about/index.vue"),
meta:{
title: '關於',
icon: ''
}
}
]
}
]
const router = createRouter({
history: createWebHashHistory(),
routes
})
export default router
15.4 在main.ts中注入router模塊, 重新啟動項目,訪問路由,看是否正確
import { createApp } from 'vue'
import App from './App.vue'
import { store, key } from './store';
import router from './router';

const app = createApp(App);
app.use(store, key);
app.use(router);
app.mount('#app');
15.5 使用路由


<h2 @click="handleClick(1)">首頁
<h2 @click="handleClick(0)">關於

16、引入element-plus以及注意事項
16.1 安裝
npm install element-plus --save

or

yarn add element-plus

安裝icon圖標依賴庫

npm install @element-plus/icons

or

yarn add @element-plus/icons
16.2 在main.ts 文件中引入配置
import { createApp } from 'vue'
import App from './App.vue'
import { store, key } from './store';
// 注入路由
import router from './router';

// 引入ui組件
import ElementPlus from 'element-plus'
import 'element-plus/dist/index.css'

const app = createApp(App);
app.use(store, key);
app.use(router);
app.use(ElementPlus);
app.mount('#app');
16.3 在vue文件中引用ui組件
1、單個圖標引用

2、全局注冊圖標使用
import { createApp } from 'vue'
import App from './App.vue'

import { Edit,Search } from '@element-plus/icons'

const app = createApp(App);
app.component("edit", Edit)
app.component("search", Search)
app.mount('#app');
2、1 使用圖標

home頁面


主要按鈕
成功按鈕






17、配置vite.config.ts
這里主要配置vite服務器的打包保存地址,打包分解,端口號,是否自動打開瀏覽器,遠程請求地址代理目標,目錄別名,全局樣式配置等。
import { defineConfig } from 'vite';
import vue from '@vitejs/plugin-vue';
import { loadEnv } from 'vite';
// nodejs寫法,獲取項目目錄
import path from 'path';

// https://vitejs.dev/config/
export default({ command, mode }) => {
return defineConfig({
plugins: [vue()],
server:{
host: '127.0.0.1',
port: Number(loadEnv(mode, process.cwd()).VITE_APP_PORT),
strictPort: true, // 端口被占用直接退出
https: false,
open: true,// 在開發服務器啟動時自動在瀏覽器中打開應用程序
proxy: {
// 字符串簡寫寫法
// '/foo': '',
// 選項寫法
'/api': {
target: loadEnv(mode, process.cwd()).VITE_APP_BASE_URL,
changeOrigin: true,
rewrite: (path) => path.replace(/^/api/, '')
},
// 正則表達式寫法
// '^/fallback/.': {
// target: 'http://jsonplaceholder.typicode.com',
// changeOrigin: true,
// rewrite: (path) => path.replace(/^/fallback/, '')
// },
},
hmr:{
overlay: true // 屏蔽服務器報錯
}
},
resolve:{
alias:{
'@': path.resolve(__dirname,'./src')
}
},
css:{
// css預處理器
preprocessorOptions: {
// 引入 var.scss 這樣就可以在全局中使用 var.scss中預定義的變量了
// 給導入的路徑最后加上 ;
scss: {
additionalData: '@import "@/assets/styles/global.scss";'
}
}
},
build:{
chunkSizeWarningLimit: 1500, // 分塊打包,分解塊,將大塊分解成更小的塊
rollupOptions: {
output:{
manualChunks(id) {
if (id.includes('node_modules')) {
return id.toString().split('node_modules/')[1].split('/')[0].toString();
}
}
}
}
}
})
}
18、tsconfig.json 配置
這是typescript的識別配置文件,也是ts向js轉化的中間站,這里配置了許多關於ts的文件類型和策略方法。
{
"compilerOptions": {
"target": "esnext",
"module": "esnext",
"moduleResolution": "node",
"strict": true,
"jsx": "preserve",
"sourceMap": true,
"resolveJsonModule": true,
"esModuleInterop": true,
"lib": ["esnext", "dom"],
"baseUrl": ".",
"paths": {
"@/
":["src/"]
}
},
"include": ["src/**/
.ts", "src//*.d.ts", "src//.tsx", "src/**/.vue"]
}
19、shims-vue.d.ts配置, 聲明vue文件全局模塊
這里是配置聲明,比如css,vue等文件,ts不能識別,需要配置聲明模塊類型。
declare module '*.vue' {
import { DefineComponent } from 'vue'
// eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/ban-types
const component: DefineComponent<{}, {}, any>
export default component
}
20、安裝scss並配置全局樣式文件
// 注意要使用scss,必須安裝依賴,否則報錯
npm install node-sass sass-loader sass -D
20.1 需要在src目錄的assets靜態目錄新增一個全局global.scss文件,其他樣式文件導入到該文件即可全局使用和修改。

或者在global.scss寫一個單獨屬性測試
$color-primary: #007aff;
vue使用全局樣式變量

home頁面


20.2 在vite.config.ts 文件中配置global.scss
css:{
// css預處理器
preprocessorOptions: {
// 引入 var.scss 這樣就可以在全局中使用 var.scss中預定義的變量了
// 給導入的路徑最后加上 ;
scss: {
additionalData: '@import "@/assets/styles/global.scss";'
}
}
}
21、響應式API
響應式狀態需要明確使用響應式 APIs 來創建。和從 setup() 函數中返回值一樣,ref 值在模板中使用的時候會自動解包:

22、.env.環境變量配置和讀取 環境變量建議放到項目根目錄下, 方便vite.config.ts文件讀取和使用 .env.production // 生產環境配置文件 .env.development // 開發環境配置文件 22.1 生產和開發環境配置文件內容如下: 寫變量時一定要以VITE_開頭,才能暴露給外部讀取 # 開發環境 / #生產環境 VITE_APP_TITLE = "前端技術棧" VITE_APP_PORT = 3001

請求接口

VITE_APP_BASE_URL = "http://39.12.29.12:8080"

//env.d.ts文件內進行 環境變量智能提示配置
interface ImportMetaEnv {
VITE_APP_TITLE: string,
VITE_APP_PORT: string,
VITE_APP_BASE_URL: string
}
22.2 vite.config.ts 讀取配置文件
import { defineConfig } from 'vite';
import vue from '@vitejs/plugin-vue';
import { loadEnv } from 'vite';
// nodejs寫法,獲取項目目錄
import path from 'path';

// https://vitejs.dev/config/
export default({ command, mode }) => {
// console.log(command, mode, 5555);
return defineConfig({
plugins: [vue()],
server:{
host: '127.0.0.1',
port: Number(loadEnv(mode, process.cwd()).VITE_APP_PORT),
strictPort: true, // 端口被占用直接退出
https: false,
open: true,// 在開發服務器啟動時自動在瀏覽器中打開應用程序
proxy: {
// 字符串簡寫寫法
// '/foo': '',
// 選項寫法
'/api': {
target: loadEnv(mode, process.cwd()).VITE_APP_BASE_URL,
changeOrigin: true,
rewrite: (path) => path.replace(/^/api/, '')
},
// 正則表達式寫法
// '^/fallback/.*': {
// target: 'http://jsonplaceholder.typicode.com',
// changeOrigin: true,
// rewrite: (path) => path.replace(/^/fallback/, '')
// },
// 使用 proxy 實例
// '/api': {
// target: 'http://jsonplaceholder.typicode.com',
// changeOrigin: true,
// configure: (proxy, options) => {
// // proxy 是 'http-proxy' 的實例
// },
// }
},
hmr:{
overlay: true // 屏蔽服務器報錯
}
},
resolve:{
alias:{
'@': path.resolve(__dirname,'./src')
}
},
css:{
// css預處理器
preprocessorOptions: {
// 引入 var.scss 這樣就可以在全局中使用 var.scss中預定義的變量了
// 給導入的路徑最后加上 ;
scss: {
additionalData: '@import "@/assets/styles/global.scss";'
},
sass: {
additionalData: '@import "@/assets/styles/global.scss";'
}
}
},
build:{
chunkSizeWarningLimit: 1500, // 分塊打包,分解塊,將大塊分解成更小的塊
rollupOptions: {
output:{
manualChunks(id) {
if (id.includes('node_modules')) {
return id.toString().split('node_modules/')[1].split('/')[0].toString();
}
}
}
}
}
})
}
22.3 其他文件讀取環境變量

附上學習視頻:
https://www.bilibili.com/video/BV1QP4y1p748?spm_id_from=333.999.0.0


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM