從一個工做多年的Vue初學者角度學習Vue3:初識Vue組件

本文字數:4708,閱讀徹底文大約要花費30分鐘。css

一直以爲框架只是工具,工做中用不上就不必去學,要用的時候再去學習便可。html

因此對國內很是火爆的Vue框架也只有一個初淺的印象:前端

  • Vue是一個漸進式的JavaScript框架
  • Vue2經過defineProperty攔截對象實現響應式,而Vue3則改爲了Proxy實現響應式
  • Vue3增長了Composite API以解決代碼複用和可維護性問題

爲了拓展DevUI的生態,讓DevUI的最佳實踐可以服務更多的開發者,今年3月份咱們在社區正式發起了Vue DevUI開源項目,吸引了不少社區小夥伴們的加入。vue

目前已經有35+位組件田主認領了60+個組件👏🎉🥳react

如下是貢獻者花名冊:git

gitee.com/devui/vue-d…github

我正好也利用這個契機,系統地學習了一遍Vue3,趁着剛學完,從初學者的角度總結Vue3的關鍵特性(只是從我我的的角度,不必定徹底按照文檔來)。typescript

本文從如下技術棧的角度進行闡述:api

💡提示:截止到2021年8月7日,以上庫/框架的版本都是最新版本。瀏覽器

文章較長,若是想直接看小結,能夠跳轉到如下章節: 6 小結

1 先跑起來再說

對於一個小白來講,要學習一門新技術,最快的方式就是:

先跑起來再說

跑起來以後,咱們會對這門新技術有一個直觀的印象,後續看文檔也會更清晰。

另外就是要多思考,帶着問題去學習,記憶會更深入,也更容易理解其中的原理。

後續咱們學習過程當中學到的新知識點,我都會加上官網的連接,不過這些官網資料只是一個進一步學習的參考,關鍵是咱們本身要有思考,並帶着問題去學習。

Vite是尤大大比較推薦的開發Vue3的工具,據說很是絲滑,因此第一步先建一個Vite的工程跑起來。

直接參考官網的開始章節,一個命令就搞定啦:

yarn create vite learning-vue3 --template vue-ts
複製代碼

--template這個參數是選擇一個工程模板,咱們選擇的是vue-tsVue 3 + Typescript + Vite

Vite除了建立Vue的工程,還能夠建立React/Preact/Svelte等多種框架的工程。

Vite果真很是快,不到3s就建立了一個基本的腳手架工程。

$ yarn create vite learning-vue3 --template vue-ts
yarn create v1.22.10
[1/4] 🔍  Resolving packages...
[2/4] 🚚  Fetching packages...
[3/4] 🔗  Linking dependencies...
[4/4] 🔨  Building fresh packages...

success Installed "create-vite@2.5.4" with binaries:
      - create-vite
      - cva
[###########################################################################################################################################################################################################] 232/232
Scaffolding project in /devui/kagol/learning-vue3...

Done. Now run:

  cd learning-vue3
  yarn
  yarn dev

✨  Done in 2.69s.
複製代碼

並且很是友好地提示咱們下一步要執行的命令:

Done. Now run:

  cd learning-vue3
  yarn
  yarn dev
複製代碼

按照提示操做,咱們很快就能將項目跑起來了!

vite.png

2 Vue組件初步印象

啓動畫面最底下,有一個指引,讓咱們編輯components/HelloWorld.vue這個文件,測試下熱更新(HMR)的功能。

咱們找到這個文件HelloWorld.vue,不着急修改它,先來觀察下它的結構。

這個文件是以.vue爲文件後綴的,表明這是一個Vue組件

一個Vue組件包含三個部分:

  • 最頂部是一個<template>標籤
  • 中間是一個<script lang="ts">標籤
  • 最下面是一個<style scoped>標籤

HelloWorld.vue.png

這和咱們最先學習前端編寫html頁面的結構是同樣的,將HTML/CSS/JavaScript分紅三個區塊。

不過咱們仍是注意到一點不一樣:

  • HTML部分是用<template>這個特殊的標籤包裹起來的;
  • <script>部分多了一個lang="ts"屬性,表明支持TypeScript
  • <style>部分多了一個scoped屬性,表明局部樣式,即:這裏面寫的樣式只針對當前這個Vue組件。

以上就是目前觀察到的Vue組件的基本特色。

3 <template>分析

咱們把<template>/<script>/<style>三個標籤展開,看下里面的結構。

先看下<template>,裏面元素比較多,先都收起來,看下大體結構。

template.png

咱們注意到裏面就是一些html元素,彷佛和寫html沒什麼區別,不過仔細一看,還有會有些不一樣:

  • 首先就是第2行的雙大括號包裹的部分{{ msg }},這和咱們以前寫的html有點不同,這是一種Vue的模板語法,叫文本插值,裏面的msg是組件的變量,變量的值會被渲染到<h1>標籤裏面。
<h1>{{ msg }}</h1>
複製代碼
  • 第30行是一個<button>標籤,咱們很熟悉它是一個按鈕,裏面也有一個文本插值,綁定的是count變量,還有一個@click屬性咱們沒見過,這是Vue事件綁定的語法,綁定了button的點擊事件。
<button type="button" @click="count++">count is: {{ count }}</button>
複製代碼

Vite熱更新 - template

咱們嘗試修改下template裏面的內容,好比將最後一行的:

hot module replacement.
複製代碼

改爲

hot module replacement(HMR).
複製代碼

看下頁面會有什麼變化。

Vite熱更新-template.gif

從以上動圖能夠看出,修改完template中的內容,一保存文件,頁面內容立馬刷新,幾乎沒有任何延遲,頁面也沒有刷新,開發體驗很是絲滑。

貓貓震驚.gif

4 <script>分析

這部分是全文的核心部分,內容較長,若是想直接看本章節的小結,能夠點擊直通車連接: 4.9 小結

模板部分咱們已經有了一個初步的瞭解,再來看看腳本部分。

script.png

4.1 導入Vue方法

腳本的第一行從vue導入了兩個方法:

  • ref:返回一個響應式且可變的ref對象;
  • defineComponent:用來定義一個同步的Vue組件。
import { ref, defineComponent } from 'vue'
複製代碼

這兩個方法是高頻方法,必須緊緊記住。

4.2 導出Vue組件

第39行導出了一個Vue組件。

export default defineComponent({
  name: 'HelloWorld',
  props: {
    msg: {
      type: String,
      required: true
    }
  },
  setup: () => {
    const count = ref(0)
    return { count }
  }
})
複製代碼

Vue組件經過defineComponent方法來定義,該方法的參數是一個對象,該對象有3個屬性:

  • name:一個字符串,表明組件的名字;
  • props:一個對象,表明組件的入參,也就是組件與外部進行交互的一個口子,外部使用組件時,能夠經過props往組件內部傳遞數據;
  • setup:一個箭頭函數,這是Vue3新推出的Composite API的入口,會在組件建立以前、props被解析以後執行。

4.3 組件入參

第42行定義了一個msg變量,以前咱們在template中已經見過它,但是它的值是什麼呢?

props: {
    msg: {
      type: String,
      required: true
    }
  },
複製代碼

咱們注意到msg是嵌套在props裏面的,表明它是組件的一個入參,是組件與外部交互的API,那麼它的值就應該是從外部傳進來的。

從哪兒傳進來的呢?使用組件是經過它的名字name來使用的,因此咱們在源代碼裏面搜索組件的名字:HelloWorld,發現是在App.vue中使用的:

<HelloWorld msg="Hello Vue 3 + TypeScript + Vite" />
複製代碼

4.4 使用Vue組件

使用一個組件和使用一個普通的html標籤(好比div)幾乎是同樣的,惟一不一樣的是使用組件以前須要先導入並聲明該組件。

使用組件的方式很簡單,只須要3步:

  • 導入組件
  • 聲明組件
  • 使用組件

使用組件.png

4.5 Vite熱更新 - script

咱們嘗試修改下這個msg的值(好比改爲:Hello everyone! I'm learning Vue 3 + TypeScript + Vite),看下頁面會有什麼變化。

Vite熱更新-script.gif

從以上動圖能夠看出,與修改template的效果同樣,修改完msg的值,一保存文件,頁面內容立馬刷新,以前的:

Hello Vue 3 + TypeScript + Vite
複製代碼

立馬變成了:

Hello everyone! I'm learning Vue 3 + TypeScript + Vite
複製代碼

幾乎沒有任何延遲,頁面也沒有刷新,開發體驗很是絲滑。

貓貓震驚2.gif

4.6 響應式的ref對象

第48行定義了一個count變量:

setup: () => {
    const count = ref(0)
    return { count }
  }
複製代碼

以前咱們在template中也見過這個變量,它的值就是這裏定義的count,咱們注意到這個count的值是調用ref函數以後返回的,函數的參數是數字0。爲何要包一層ref,而不是直接將0賦值給count變量呢?

const count = 0
複製代碼

直接賦值不是更簡潔嗎?

咱們先來看下官網對ref的介紹:

接受一個內部值並返回一個響應式且可變的 ref 對象。ref 對象具備指向內部值的單個 property `.value`。
複製代碼

爲了理解ref函數的做用,咱們先嚐試在頁面裏點擊一下這個count is: 0的按鈕。

button.png

點擊完發現裏面的值立馬變成:

count is: 1
複製代碼

這時咱們將:

const count = ref(0)
複製代碼

修改爲:

const count = 0
複製代碼

再次點擊button按鈕,發現值沒有變。

咱們大體能理解ref函數返回響應式ref對象的含義:

響應式的意思就是這個變量的值是動態的,某些動做(點擊按鈕)改變了它的值,模板裏面的文本插值立馬也會跟着變化,從而頁面裏面的內容也會跟着刷新。

若是count沒有被ref函數包裹,那它就不是響應式的,點擊按鈕改變它的值以後,模板的內容不會跟着變化。

有一個須要注意的點:

setup中定義的變量必須返回,才能在template中使用,不然插值不會被渲染,而且會在瀏覽器控制檯警告提示這個變量沒有在實例中定義。

warn.png

[Vue warn]: Property "count" was accessed during render but is not defined on instance.
複製代碼

4.7 TypeScript支持

前面提到<script>中的lang="ts"屬性是用來支持TypeScript的,咱們來試試看吧。

先定義一個type類型:

type Size = 'sm' | 'md' | 'lg'
複製代碼

而後在setup方法中定義一個變量用來使用這個類型:

const size = ref<Size>('md')

return { size } // 記得返回哦
複製代碼

最後在template經過文本插值使用該變量:

<p>{{ size }}</p>
複製代碼

因爲咱們在<script>中加了lang="ts",因此頁面能正常顯示md

這時咱們把lang="ts"去掉,保存文件並刷新頁面,頁面變成白頁,而且瀏覽器控制檯也報錯:

Uncaught SyntaxError: unexpected token: identifier
複製代碼

前面定義的Size類型也出現了紅色的波浪下劃線。

Size.png

提示type類型聲明必須在TypeScript文件中使用:

Type aliases can only be used in TypeScript files.
複製代碼

4.8 TypeScript類型錯誤高亮提示

這樣彷佛看不出TypeScript的優點,咱們豐富下這個demo,來看看TypeScript的好處。

咱們加一個addSize方法,用來增長尺寸:

const addSize = () => {
  size.value = 'lg' // 給size變量賦值爲Size類型中定義好的值是沒問題的
}

return { addSize } // 記得返回哦
複製代碼

template中使用該方法:

<button type="button" @click="addSize">Add size</button>
複製代碼

若是將size賦值爲Size類型定義的值,好比:largeVetur類型檢查立刻就會提示,相應的賦值代碼也會出現紅色波浪下劃線:

ts.png

這時咱們可以當即警覺:

這裏的代碼可能寫得有問題

💡提示:Vetur是一款VSCode插件,用來作.vue文件的語法高亮和TypeScript類型檢查等。

很是感謝你能閱讀到這裏,還有最後5分鐘就閱讀完了,經過小結鞏固下學到的知識,而後喝杯水放鬆下吧😋

4.9 小結

<script>部分基本就是這些,咱們作一個簡單的小結:

  1. defineComponent方法用於定義Vue組件
  2. Vue組件的名字經過name屬性來定義,名字能夠用來惟一區分一個組件
  3. Vue組件經過props屬性來與外界進行數據交互
  4. setup方法是Vue3 Composite API的入口
  5. 使用Vue組件和使用html元素差很少,只是須要先導入、聲明組件才能使用
  6. ref用於返回一個響應式對象
  7. lang="ts"用來支持TypeScript

5 <style>分析

最後再來看下<style>部分。

<style scoped>
a {
  color: #42b983;
}

label {
  margin: 0 0.5em;
  font-weight: bold;
}

code {
  background-color: #eee;
  padding: 2px 4px;
  border-radius: 4px;
  color: #304455;
}
</style>
複製代碼

看着和寫CSS沒什麼區別,只是有一點不同(前面也提到過),就是<style>標籤中增長了一個scoped屬性,這個屬性用來定義局部樣式,裏面寫的樣式只針對當前組件生效。

5.1 局部樣式

爲了理解局部樣式的含義,咱們在其餘組件中也寫一個<code>標籤,看下它的樣式是否是和HelloWorld組件中的同樣,HelloWorld組件中,code標籤樣式是這樣的(有一個灰色的背景色):

code.png

code {
  background-color: #eee;
  padding: 2px 4px;
  border-radius: 4px;
  color: #304455;
}
複製代碼

咱們在App.vue中也寫一個code標籤:

<code>Vue DevUI</code>
複製代碼

App.vue.png

發如今HelloWorld組件的style中寫的樣式並不會影響App組件中的code,這就是局部樣式。

經過對比二者的html元素,發現HelloWorld組件中的元素都加上了一個data-v-開頭的特殊屬性,相應的css規則也加上了這個選擇器。

scoped.png

這一點和Angular中的encapsulation屬性很是相似。

5.2 Vite熱更新 - style

除了templatescript的熱更新,Vite也支持style樣式的熱更新,同樣的絲滑,就再也不贅述。

6 小結

經過本文,咱們使用Vite啓動了一個初始的項目工程,而且對Vue組件有了一個初步的認識,如今作個簡單的小結鞏固下吧。

  1. 先是搭建了一個Vue3+TypeScript+Vite的工程
  2. 而後瞭解了一下Vue組件的總體結構(.vue文件,template+script+style)
  3. 接着對template、script、style區塊進行了單獨的分析
  4. template和html很相似,只是增長了一些Vue特有的模板語法,如文本插值、事件綁定等
  5. script是定義組件邏輯的地方,能夠經過lang="ts"支持TypeScript
  6. defineComponentref是Vue提供的兩個很是經常使用的方法,defineComponent用來定義Vue組件,ref用來生成一個響應式的ref對象
  7. defineComponent方法的參數是一個對象,其中的name屬性用來定義Vue組件的名字,使用組件時經過名字引用
  8. 使用Vue組件和使用html標籤很相似,只是須要先導入和聲明組件
  9. props屬性用來定義組件與外部交互的API,是組件設計的關鍵
  10. setup方法是Vue3 Composite API的入口,它會在組件生成以前、props解析以後執行
  11. style用來編寫組件的樣式,能夠經過scoped支持只對當前組件生效的局部樣式

本篇文章到這裏就結束了,如下是Vue DevUI開源項目的介紹,若是感興趣能夠選擇繼續閱讀。


Vue DevUI正在火熱🔥開發中,歡迎你們踊躍參與進來,一塊兒共建一個基於DevUI設計理念的Vue開源組件庫。

和社區其餘組件庫相比,咱們主要有如下優點:

  1. vue devui是基於devui沉浸、至簡、靈活的設計價值觀進行設計和開發的,這是經受過devcloud衆多商用項目考驗的,確保質量和體驗
  2. vue devui的定位是一個跨端組件庫,確保知足pc/mobile多端用戶的需求
  3. devui是一個專一於用戶體驗的團隊,背後有50+優秀的設計師和工程師,確保產品的優秀體驗和技術的先進性
  4. 咱們有多個特點組件,好比甘特圖、分類搜索、精靈導航、同時支持自定義字體圖標和自定義svg的圖標組件等
  5. 咱們支持按需加載、自定義主題、國際化等組件庫標配特性。

如下是該項目的源碼:

gitee.com/devui/vue-d…

參與貢獻能夠加小助手微信:devui-official,拉你進Vue DevUI核心成員小組~😋😋

歡迎關注咱們DevUI組件庫,點亮咱們的小星星🌟:

github.com/devcloudfe/…

也歡迎使用DevUI新發布的DevUI Admin系統,開箱即用,10分鐘搭建一個美觀大氣的後臺管理系統!

再次預告:DevUI 12 和 DevUI Admin 2.0 立刻就要來了!

DevUI 將於本月10日發佈 DevUI 12 版本,除了升級 Angular 12 以外,更有超多有趣的新特性,盡情期待!

DevUI Admin 2.0 版本也將在本月17號重磅發佈,提供了一項神奇的黑科技,讓咱們拭目以待吧!

參考:

Vue3中文文檔

相關文章
相關標籤/搜索