創(chuàng)建你的第一個(gè)Vue 3項(xiàng)目

本文已經(jīng)過原作者 Shadeed 授權(quán)翻譯。
2021年2月15日Vue 3正式發(fā)布!在尤雨溪的聲明中,他宣布了新框架中最大的變化,并談?wù)摿苏麄€(gè)Vue團(tuán)隊(duì)所做的出色工作。
長期以來,開發(fā)者一直在等待Vue 3宣布的真正酷的特性,比如Typescript支持、對(duì)大型項(xiàng)目更好的組織、及使Vue應(yīng)用程序更好的渲染優(yōu)化。
本文中我們要做以下的內(nèi)容,使用組合API構(gòu)建了兩個(gè)組件。

開始
有幾種不同的選項(xiàng)可用于將Vue 3添加到現(xiàn)有項(xiàng)目或創(chuàng)建自己的Vue 3項(xiàng)目。
這里,我用自己最喜歡的兩個(gè)選項(xiàng):
Vue CLI Vite
Vue CLI
如果你用過Vue開發(fā),那么很可能使用了Vue CLI來設(shè)置項(xiàng)目。
首先,我們必須確保擁有Vue CLI的最新版本,可以通過在終端上運(yùn)行 npm update -g @vue/cli 來做到這一點(diǎn)。
接下來,創(chuàng)建項(xiàng)目,運(yùn)行 vue create <項(xiàng)目名>,如果 CLI是最新的,我們就可以選擇Vue 3。

選擇了Vue 3選項(xiàng),我們的應(yīng)用程序便會(huì)構(gòu)建。完成后,我們只需要進(jìn)入我們的項(xiàng)目,然后運(yùn)行我們的Vue應(yīng)用, 該命令是:
cd <項(xiàng)目我>
npm run serve
現(xiàn)在,在瀏覽器中輸入http://localhost:8080/,就會(huì)看到我們的應(yīng)用程序!

Vite
Vite (法語意為 "快速的",發(fā)音 /vit/) 是一種新型前端構(gòu)建工具,能夠顯著提升前端開發(fā)體驗(yàn),它主要由兩部分組成:
一個(gè)開發(fā)服務(wù)器,它利用 原生 ES 模塊 提供了 豐富的內(nèi)建功能,如速度快到驚人的 模塊熱更新(HMR)。
一套構(gòu)建指令,它使用 Rollup 打包你的代碼,預(yù)配置輸出高度優(yōu)化的靜態(tài)資源用于生產(chǎn)。
為什么使用 Vite
你現(xiàn)在可能會(huì)有疑問?,那么 Vite 與現(xiàn)有的vue-cli到底有什么不同呢?
由于@ vue-cli / service是在webpack之上構(gòu)建的,因此它是一個(gè)模塊捆綁程序,它將在啟動(dòng),熱重載和編譯時(shí)捆綁整個(gè)Vue項(xiàng)目。
由于@vue-cli/service是在webpack之上構(gòu)建的,因此它是一個(gè)模塊捆綁程序,它將在啟動(dòng),熱重載和編譯時(shí)捆綁整個(gè)Vue項(xiàng)目。
Webpack 的工作方式是,它通過解析應(yīng)用程序中的每一個(gè) import 和 require ,將整個(gè)應(yīng)用程序構(gòu)建成一個(gè)基于 JavaScript 的捆綁包,并在運(yùn)行時(shí)轉(zhuǎn)換文件(例如 Sass、TypeScript、SFC)。
這都是在服務(wù)器端完成的,依賴的數(shù)量和改變后構(gòu)建/重新構(gòu)建的時(shí)間之間有一個(gè)大致的線性關(guān)系。
相反,Vite 不捆綁應(yīng)用服務(wù)器端。相反,它依賴于瀏覽器對(duì) JavaScript 模塊的原生支持(也就是 ES 模塊,是一個(gè)比較新的功能)。
瀏覽器將在需要時(shí)通過 HTTP 請(qǐng)求任何 JS 模塊,并在運(yùn)行時(shí)進(jìn)行處理。Vite 開發(fā)服務(wù)器將按需轉(zhuǎn)換任何文件(如 Sass、TypeScript、SFC)。
這種架構(gòu)避免了服務(wù)器端對(duì)整個(gè)應(yīng)用的捆綁,并利用瀏覽器高效的模塊處理,提供了一個(gè)明顯更快的開發(fā)服務(wù)器。
提示:當(dāng)你對(duì)應(yīng)用程序進(jìn)行 code-split 和 tree-shake 動(dòng)時(shí),Vite 的速度會(huì)更快,因?yàn)樗患虞d它需要的模塊,即使是在開發(fā)階段。這與 Webpack 不同,在 Webpack 中,代碼拆分只對(duì)生產(chǎn)包有利。
創(chuàng)建第一個(gè)Vite項(xiàng)目
運(yùn)行下面命令即可:
npm init vite-app <項(xiàng)目名>
然后,我們只需進(jìn)入我們的項(xiàng)目文件夾,安裝依賴項(xiàng),然后使用以下命令運(yùn)行我們的應(yīng)用程序:
cd <項(xiàng)目名>
npm install
npm run dev
現(xiàn)在,如果我們導(dǎo)航到http://localhost:3000 –我們應(yīng)該看到以下應(yīng)用程序:

一些你應(yīng)該知道的Vue Vite特性
1.將項(xiàng)目打包到生產(chǎn)中
Vite的一個(gè)目標(biāo)是使Vue的開發(fā)和生產(chǎn)盡可能容易。雖然在開發(fā)過程中沒有捆綁,但是將你的項(xiàng)目捆綁到生產(chǎn)中是非常容易的。
你所要做的就是運(yùn)行npm run build。
如果查看package.json,實(shí)現(xiàn)是運(yùn)行 vite build –與其他構(gòu)建過程一樣,打包后會(huì)放在dist文件中。

2.asset 路徑
與其他Vue項(xiàng)目設(shè)置一樣,Vite 提供了兩種引用`asset``的方法。
絕對(duì)路徑 - 使用公用文件夾。這些資源使用
/file.extension引用,并且在構(gòu)建項(xiàng)目時(shí)將復(fù)制到dist文件夾的根目錄中。相對(duì)路徑 - 例如,根據(jù)文件夾的文件結(jié)構(gòu)來相對(duì)訪問
src/assets文件夾中的文件。構(gòu)建項(xiàng)目時(shí),整個(gè)文件夾都將作為_assets放置在dist文件夾中。

3.內(nèi)置 Typescript 支持
Vue3 最大的變化之一是使用Typescript重寫了核心庫,允許根據(jù)IDE進(jìn)行類型檢查和更好的錯(cuò)誤消息。
通過提供對(duì).ts文件和SFC中的<script lang =“ ts”>的內(nèi)置Typescript支持,Vite再次與Vue 3順利集成。
理解 Vue3 組件
現(xiàn)在我們已經(jīng)設(shè)置好了Vue 3應(yīng)用程序,并且理解了Vue 3 Vite工具,讓我們來看看這些組件是如何工作的。
Vue 3中最大的變化是引入了組合API。在這個(gè)新的結(jié)構(gòu)中,我們能夠根據(jù)特性來組織代碼,而不是僅僅通過data、computed等來分離代碼。
這允許我們創(chuàng)建更多模塊化、可讀性和可伸縮性的代碼,因?yàn)閱蝹€(gè)特性的代碼都可以在代碼的一個(gè)區(qū)域中編寫。

如果打開src/components/HelloWorld.vue文件,我們將看到與我們?cè)赩ue2中編寫的代碼看起來相同的代碼-這稱為Options API。
<script>
export default {
name: 'HelloWorld',
props: {
msg: String
},
data() {
return {
count: 0
}
}
}
</script>
這很棒,因?yàn)樵?Vue3 中,我們?nèi)匀豢梢栽谄渲惺褂?vue2 的語法。
在本教程中,我們將介紹如何在新的Composition API中實(shí)現(xiàn)這一點(diǎn),并從Options API中識(shí)別出這些變化。
組合API中的響應(yīng)性數(shù)據(jù)
我們首先從vue核心庫導(dǎo)入一些東西,以允許我們創(chuàng)建響應(yīng)式變量。
import { ref } from 'vue'
然后,讓我們用如下所示的setup函數(shù)替換data選項(xiàng)。
import { ref } from 'vue'
export default {
setup () {
return {
}
}
}
這個(gè) setup 方法在組件創(chuàng)建時(shí)運(yùn)行,在這里我們可以定義所有需要組件使用的響應(yīng)數(shù)據(jù)、計(jì)算屬性、方法等。
還有,該setup方法返回的任何內(nèi)容都可以在模板中訪問。
使用 ref 創(chuàng)建響應(yīng)式數(shù)據(jù)
為了顯示這一點(diǎn),我們?cè)谀0逯惺褂?code style="margin-right: 2px;margin-left: 2px;padding: 2px 4px;max-width: 100%;font-size: 14px;border-radius: 4px;background-color: rgba(27, 31, 35, 0.05);font-family: "Operator Mono", Consolas, Monaco, Menlo, monospace;word-break: break-all;color: rgb(40, 202, 113);box-sizing: border-box !important;overflow-wrap: break-word !important;">v-model創(chuàng)建一個(gè)文本輸入。
<template>
<div>
<h2> Filter LearnVue Articles </h2>
<input
type='text'
placeholder='Filter Search'
v-model='query'
/>
{{ query }}
</div>
</template>
我們使用ref創(chuàng)建響應(yīng)式query變量,然后從setup方法返回它。
setup () {
const query = ref('')
return {
query
}
}
然后,如返回到應(yīng)用程序,會(huì)看到我們使用Composition API獲得了響應(yīng)式數(shù)據(jù)。

很好!接下來,我們?cè)?code style="margin-right: 2px;margin-left: 2px;padding: 2px 4px;max-width: 100%;font-size: 14px;border-radius: 4px;background-color: rgba(27, 31, 35, 0.05);font-family: "Operator Mono", Consolas, Monaco, Menlo, monospace;word-break: break-all;color: rgb(40, 202, 113);box-sizing: border-box !important;overflow-wrap: break-word !important;">input中添加一個(gè)clear按鈕,看看如何在Composition API中創(chuàng)建一個(gè)方法。
組合API中的方法
在選項(xiàng) API中,Vue對(duì)象中有一個(gè)完整的屬性專門用于方法。對(duì)于較大的文件,這意味著數(shù)據(jù)可能在數(shù)百行之外的方法中聲明,這使得組件更難讀取和維護(hù)。
在組合API中,一切都在 setup 方法中,這意味著我們可以根據(jù)特性組織代碼,甚至將通用特性提取到它們自己的代碼模塊中。
我們創(chuàng)建一個(gè)reset方法,它獲取我們的ref并將其設(shè)置為一個(gè)空字符串。
setup () {
const query = ref('')
const reset = (evt) => {
query.value = '' // clears the query
}
return {
reset,
query
}
}
需要注意的一件事是,我們需要調(diào)用query.value才能訪問數(shù)據(jù)的值。
為什么?
如果我們使用console.log(query),我們看到它不僅僅是一個(gè)字符串值,而是一個(gè) Proxy。使用 Proxy 允許我們輕松地獲取數(shù)據(jù)變化,這也是為什么我們需要在引用上調(diào)用.value的原因。
然后,就像在選項(xiàng)API使用的一樣,我們可以在模板中添加一個(gè)按鈕,在單擊時(shí)調(diào)用這個(gè)reset方法。
<button @click='reset'> Reset </button>

向 Vue3 項(xiàng)目添加第二個(gè)組件
現(xiàn)在我們已經(jīng)有了輸入和查詢數(shù)據(jù),接著,創(chuàng)建一個(gè)組件顯示結(jié)果。
這個(gè)組件取名為SearchResults.vue
要將其添加到我們的HelloWorld.vue組件中,首先必須將其導(dǎo)入并在我們的導(dǎo)出默認(rèn)值中聲明它。
<script>
import { ref } from 'vue'
import SearchResults from './SearchResults.vue'
export default {
components: {
SearchResults
},
// ...
}
</script>
然后,我們可以像這樣將它添加到模板中:
// HelloWorld.vue
<template>
<div>
<h2> Filter LearnVue Articles </h2>
<input
type='text'
placeholder='Filter Search'
v-model='query'
/>
<br>
<button @click='reset'> Reset </button>
<search-results/>
</div>
</template>
傳遞參數(shù)
Vue props 允許父組件將數(shù)據(jù)傳遞給其子組件。對(duì)于我們的例子,我們希望從HelloWorld.vue傳遞query字符串給SearchResults.vue。
// HelloWorld.vue
<search-results :query='query'/>
訪問參數(shù)
在SearchResults.vue內(nèi)部,從 JSON 文件導(dǎo)入所有的文章信息。
import titles from '../post-data.json'
export default {
setup (props, context) {
}
}
然后,我們需要幾個(gè)步驟來訪問 props。
首先,我們必須在 props 選項(xiàng)中聲明它們。這告訴我們的組件需要什么數(shù)據(jù)。
// SearchResults.vue
export default {
props: {
query: String
},
setup (props, context) {
// ...
如果我們仔細(xì)觀察setup方法,就會(huì)發(fā)現(xiàn)它接受兩個(gè)參數(shù)。
props– 包含傳遞給組件的所有 propscontext– 包含attrs,slot和emit
我們將使用 props 在 setup 方法中訪問我們的 props 的值。
我們所需要做的就是使用計(jì)算屬性來過濾使文章列表。
計(jì)算屬性
// SearchResults.vue
import { computed } from 'vue'
然后,我們這樣設(shè)置它,其中我們的computed屬性接受一個(gè)getter方法。每當(dāng)其中一個(gè)依賴項(xiàng)發(fā)生更改時(shí),此方法將更新我們的computed屬性。
// SearchResults.vue
import { computed } from 'vue'
import titles from '../post-data.json'
export default {
props: {
query: String
},
setup (props, context) {
const filteredTitles = computed(() => {
})
return {
filteredTitles
}
}
}
對(duì)于這個(gè)方法,我們希望使用query過濾所有的標(biāo)題。所有內(nèi)容都轉(zhuǎn)換為小寫,所以我們不必?fù)?dān)心大小寫。
// SearchResults.vue
const filteredTitles = computed(() => {
return titles.filter(s => s.Name.toLowerCase().includes(props.query.toLowerCase()))
})
很好~
剩下要做的就是實(shí)際使用我們的模板來顯示數(shù)據(jù)!這是使用v-for循環(huán)完成的。
// SearchResults.vue
<template>
<div class='root'>
<p> Showing {{ filteredTitles.length }} results for "{{ query }}" </p>
<ul>
<li v-for='title in filteredTitles' :key='title.Page'>
{{ title.Name }}
</li>
</ul>
</div>
</template>
就這~

Vue3 生命周期鉤子
在開始使用 Vue3 之前,還需要知道的另一件事是如何使用Vue生命周期鉤子。

像Composition API的其他部分一樣,我們必須導(dǎo)入我們想要使用的生命周期鉤子,并在setup方法中聲明它們。
// Lifecycle Example
import { computed, onMounted } from 'vue'
export default {
setup () {
onMounted(() => {
console.log('mounted')
})
}
}
總結(jié)
Vue 3中有很多很棒的功能,這些功能對(duì)于創(chuàng)建可擴(kuò)展的Vue應(yīng)用程序非常有用。
希望本文本對(duì)你在使用 vue3 時(shí)提供一些幫助。
完~,我是刷碗智,我要去刷碗了,我們下期見~
