前端發展百花放,一技未熟百技出。
茫然不知何下手,關注小編勝百書。
近期工做感受很忙,都沒有多少時間去寫文章,今天這篇文章主要是將本身前期學習Vue3.0
時候整理的一些筆記內容進行了彙總,經過對本文的閱讀,你將能夠本身完成Vue3.0
環境搭建,同時還會對Vue3.0
的一些新的特性進行了解,方便本身進行Vue3.0
的學習。本文首發於公衆號【前端有的玩】,關注===
會了,還有更多面試題等你來刷哦。javascript
本文全部的示例均使用ant design vue2.0
實現,關於ant design vue2.0
請參考 https://2x.antdv.com/docs/vue/introduce-cn/
在前面的文章中,咱們經過vite
搭建了一個開發環境,可是實際上如今vite
並無完善到支撐一個完整項目的地步,因此本文咱們依然選擇使用vue-cli
腳手架進行環境搭建。css
小編使用的vue-cli
版本是4.5.4
,若是您的版本比較舊能夠經過npm update @vue/cli
來升級腳手架版本,若是沒有安裝能夠經過npm install @vue/cli -g
進行安裝
cmd
),而後經過vue create my-vue3-test
命令初始化項目Manually select features
,進行手動選擇功能而後經過Space
和上下鍵依次選擇html
Choose Vue version Babel TypeScript Router Vuex CSS Pre-processors Linter/Formatter
而後回車前端
Vue
版本,選擇3.x(Preview)
Use class-style component syntax?
選擇n
,即輸入n
而後回車Use Babel alongside TypeScript,輸入
y`Use history mode for router
輸入n
css
預處理器選擇Less
eslint
選擇ESLint + Prettier
Lint on save
和In dedicater config files
新建完項目以後,進入到項目中cd my-vue3-test
,而後執行 yarn serve
便可啓動項目vue
啓動以後便可經過訪問 http://localhost:8080/
訪問項目java
ant design vue
在當前Vue3.0
正式版還未發佈之際,國內比較出名的前端UI
庫中率先將Vue3.0
集成到自家的UI
庫中的,PC
端主要是ant-design-vue
,移動端主要是vant
, 本文全部示例代碼都會基於ant-design-vue
來進行,首先咱們先安裝ant-design-vue
react
安裝依賴es6
yarn add ant-design-vue@2.0.0-beta.6 yarn add babel-plugin-import -D
配置ant-design-vue
按需加載面試
進入項目根目錄,而後打開babel.config.js
文件,將裏面的內容修改成vue-cli
module.exports = { presets: ["@vue/cli-plugin-babel/preset"], plugins: [ // 按需加載 [ "import", // style 爲 true 加載 less文件 { libraryName: "ant-design-vue", libraryDirectory: "es", style: "css" } ] ] };
vue3 + antdv
來添加一個小頁面, 咱們直接將views/Home.vue
文件裏面的代碼替換爲<template> <a-form layout="inline" :model="state.form"> <a-form-item> <a-input v-model:value="state.form.user" placeholder="Username"> <template v-slot:prefix ><UserOutlined style="color:rgba(0,0,0,.25)" /></template> </a-input> </a-form-item> <a-form-item> <a-input v-model:value="state.form.password" type="password" placeholder="Password" > <template v-slot:prefix ><LockOutlined style="color:rgba(0,0,0,.25)" /></template> </a-input> </a-form-item> <a-form-item> <a-button type="primary" :disabled="state.form.user === '' || state.form.password === ''" @click="handleSubmit" > 登陸 </a-button> </a-form-item> </a-form> </template> <script> import { UserOutlined, LockOutlined } from "@ant-design/icons-vue"; import { Form, Input, Button } from "ant-design-vue"; import { reactive } from "vue"; export default { components: { UserOutlined, LockOutlined, [Form.name]: Form, [Form.Item.name]: Form.Item, [Input.name]: Input, [Button.name]: Button }, setup() { const state = reactive({ form: { user: "", password: "" } }); function handleSubmit() { console.log(state.form); } return { state, handleSubmit }; } }; </script>
而後重啓一下項目,就能夠發現已經能夠正常使用ant-design-vue
了。
對於Vue3.0
的問世,最吸引你們注意力的即是Vue3.0
的Composition API
,對於Componsition API
,能夠說是兩極分化特別嚴重,一部分人特別喜歡這個新的設計與開發方式,而另外一部分人則感受使用Composition API
很容易寫出來意大利麪式的代碼(可能這部分人不知道蘭州拉麪吧)。到底Composition API
是好是壞,小編不作評論,反正我只是一個搬磚的。而本小節介紹的setup
就是Composition API
的入口。
setup
是Vue3.0
提供的一個新的屬性,能夠在setup
中使用Composition API
,在上面的示例代碼中咱們已經使用到了setup
,在上文代碼中咱們在setup
中經過reactive
初始化了一個響應式數據,而後經過return
返回了一個對象,對象中包含了聲明的響應式數據和一個方法,而這些數據就能夠直接使用到了template
中了,就像上文代碼中的那樣。關於reactive
,我將會在下一小節爲你帶來講明。
setup
函數有兩個參數,分別是props
和context
。
props
props
是setup
函數的第一個參數,是組件外部傳入進來的屬性,與vue2.0
的props
基本是一致的,好比下面代碼
export default { props: { value: { type: String, default: "" } }, setup(props) { console.log(props.value) } }
可是須要注意的是,在setup
中,props
是不能使用解構的,即不能將上面的代碼改寫成
setup({value}) { console.log(value) }
雖然template
中使用的是setup
返回的對象,可是對於props
,咱們不須要在setup
中返回,而是直接能夠在template
使用,好比上面的value
,能夠直接在template
寫成
<custom-component :value="value"></custom-component>
context
context
是setup
函數的第二個參數,context
是一個對象,裏面包含了三個屬性,分別是
attrs
attrs
與Vue2.0
的this.$attrs
是同樣的,即外部傳入的未在props
中定義的屬性。對於attrs
與props
同樣,咱們不能對attrs
使用es6
的解構,必須使用attrs.name
的寫法
slots
slots
對應的是組件的插槽,與Vue2.0
的this.$slots
是對應的,與props
和attrs
同樣,slots
也是不能解構的。
emit
emit
對應的是Vue2.0
的this.$emit
, 即對外暴露事件。
setup
函數通常會返回一個對象,這個對象裏面包含了組件模板裏面要使用到的data
與一些函數或者事件,可是setup
也能夠返回一個函數,這個函數對應的就是Vue2.0
的render
函數,能夠在這個函數裏面使用JSX
,對於Vue3.0
中使用JSX
,小編將在後面的系列文章中爲您帶來更多說明。
最後須要注意的是,不要在setup
中使用this
,在setup
中的this
和你真正要用到的this
是不一樣的,經過props
和context
基本是能夠知足咱們的開發需求的。
Composition API
,先從reactive
和ref
開始在使用Vue2.0
的時候,咱們通常聲明組件的屬性都會像下面的代碼同樣
export default { data() { return { name: '子君', sex: '男' } } }
而後就能夠在須要用到的地方好比computed
,watch
,methods
,template
等地方使用,可是這樣存在一個比較明顯的問題,即我聲明data
的地方與使用data
的地方在代碼結構中可能相距很遠,有一種君住長江頭,我住長江尾,日日思君不見君,共飲一江水
的感受。而Composition API
的誕生的一個很重要的緣由就是解決這個問題。在尤大大在關於Composition API
的動機中是這樣描述解決的問題的:
如今咱們先了解一下Compositon API
中的reactive
和ref
reactive
在Vue2.6
中, 出現了一個新的api
,Vue.observer
,經過這個api
能夠建立一個響應式的對象,而reactive
就和Vue.ovserver
的功能基本是一致的。首先咱們先來看一個例子
<template> <!--在模板中經過state.name使用setup中返回的數據--> <div>{{ state.name }}</div> </template> <script> import { reactive } from "vue"; export default { setup() { // 經過reactive聲明一個可響應式的對象 const state = reactive({ name: "子君" }); // 5秒後將子君修改成 前端有的玩 setTimeout(() => { state.name = "前端有的玩"; }, 1000 * 5); // 將state添加到一個對象中而後返回 return { state }; } }; </script>
上面的例子就是reactive
的一個基本的用法,咱們經過上面的代碼能夠看到reactive
和Vue.observer
聲明可響應式對象的方法是很像的,可是他們之間仍是存在一些差異的。咱們在使用vue2.0
的時候,最多見的一個問題就是常常會遇到一些數據明明修改了值,可是界面卻並無刷新,這時候就須要使用Vue.set
來解決,這個問題是由於Vue2.0
使用的Object.defineProperty
沒法監聽到某些場景好比新增屬性,可是到了Vue3.0
中經過Proxy
將這個問題解決了,因此咱們能夠直接在reactive
聲明的對象上面添加新的屬性,一塊兒看看下面的例子
<template> <div> <div>姓名:{{ state.name }}</div> <div>公衆號:{{ state.gzh }}</div> </div> </template> <script> import { reactive } from "vue"; export default { setup() { const state = reactive({ name: "子君" }); // 5秒後新增屬性gzh 前端有的玩 setTimeout(() => { state.gzh = "前端有的玩"; }, 1000 * 5); return { state }; } }; </script>
上面的例子雖然在state
中並無聲明gzh
屬性,可是在5s
後咱們能夠直接給state
添加gzh
屬性,這時候並不須要使用Vue.set
來解決新增屬性沒法響應的問題。
在上面的代碼中,reactive
經過傳入一個對象而後返回了一個state
,須要注意的是state
與傳入的對象是不用的,reactive
對原始的對象並無進行修改,而是返回了一個全新的對象,返回的對象是Proxy
的實例。須要注意的是在項目中儘可能去使用reactive
返回的響應式對象,而不是原始對象。
const obj = {} const state = reactive(obj) // 輸出false console.log(obj === state)
ref
假如如今咱們須要在一個函數裏面聲明用戶的信息,那麼咱們可能會有兩種不同的寫法
// 寫法1 let name = '子君' let gzh = '前端有的玩' // 寫法2 let userInfo = { name: '子君', gzh: '前端有的玩' }
上面兩種不一樣的聲明方式,咱們使用的時候也是不一樣的,對於寫法1
咱們直接使用變量就能夠了,而對於寫法2
,咱們須要寫成userInfo.name
的方式。咱們能夠發現userInfo
的寫法與reactive
是比較類似的,而Vue3.0
也提供了另外一種寫法,就像寫法1
同樣,即ref
。先來看一個例子。
<template> <div> <div>姓名:{{ name }}</div> </div> </template> <script> import { ref } from "vue"; export default { setup() { const name = ref("子君"); console.log('姓名',name.value) // 5秒後修改name爲 前端有的玩 setTimeout(() => { name.value = "前端有的玩"; }, 1000 * 5); return { name }; } }; </script>
經過上面的代碼,能夠對比出來reactive
與ref
的區別
reactive
傳入的是一個對象,返回的是一個響應式對象,而ref
傳入的是一個基本數據類型(其實引用類型也能夠),返回的是傳入值的響應式值reactive
獲取或修改屬性能夠直接經過state.prop
來操做,而ref
返回值須要經過name.value
的方式來修改或者讀取數據。可是須要注意的是,在template
中並不須要經過.value
來獲取值,這是由於template
中已經作了解套。Vue3.0
優雅的使用v-model
v-model
並非vue3.0
新推出的新特性,在Vue2.0
中咱們已經大量的到了v-model
,可是V3
和V2
仍是有很大的區別的。本節咱們將主要爲你們帶來如何在Vue3.0
中使用v-model
,Vue3.0
中的v-model
提供了哪些驚喜以及如何在Vue3.0
中自定義v-model
。
Vue2.0
和Vue3.0
中使用v-model
在Vue2.0
中如何實現雙向數據綁定呢?經常使用的方式又兩種,一種是v-model
,另外一種是.sync
,爲何會有兩種呢?這是由於一個組件只能用於一個v-model
,可是有的組件須要有多個能夠雙向響應的數據,因此就出現了.sync
。在Vue3.0
中爲了實現統一,實現了讓一個組件能夠擁有多個v-model
,同時刪除掉了.sync
。以下面的代碼,分別是Vue2.0
與Vue3.0
使用v-model
的區別。
在Vue2.0
中使用v-model
<template> <a-input v-model="value" placeholder="Basic usage" /> </template> <script> export default { data() { return { value: '', }; }, }; </script>
在Vue3.0
中使用v-model
<template> <!--在vue3.0中,v-model後面須要跟一個modelValue,即要雙向綁定的屬性名--> <a-input v-model:value="value" placeholder="Basic usage" /> </template> <script> export default { // 在Vue3.0中也能夠繼續使用`Vue2.0`的寫法 data() { return { value: '', }; }, }; </script>
在vue3.0
中,v-model
後面須要跟一個modelValue
,即要雙向綁定的屬性名,Vue3.0
就是經過給不一樣的v-model
指定不一樣的modelValue
來實現多個v-model
。對於v-model
的原理,下文將經過自定義v-model
來講明。
v-model
Vue2.0
自定義一個v-model
示例<template> <div class="custom-input"> <input :value="value" @input="$_handleChange" /> </div> </template> <script> export default { props: { value: { type: String, default: '' } }, methods: { $_handleChange(e) { this.$emit('input', e.target.value) } } } </script>
在代碼中使用組件
<template> <custom-input v-model="value"></custom-input> </template> <script> export default { data() { return { value: '' } } } </script>
在Vue2.0
中咱們經過爲組件設置名爲value
屬性同時觸發名爲input
的事件來實現的v-model
,固然也能夠經過model
來修改屬性名和事件名,能夠看我之前的文章中有詳解。
Vue3.0
自定義一個v-model
示例組件代碼
<template> <div class="custom-input"> <input :value="value" @input="_handleChangeValue" /> </div> </template> <script> export default { props: { value: { type: String, default: "" } }, name: "CustomInput", setup(props, { emit }) { function _handleChangeValue(e) { // vue3.0 是經過emit事件名爲 update:modelValue來更新v-model的 emit("update:value", e.target.value); } return { _handleChangeValue }; } }; </script>
在代碼中使用組件
<template> <!--在使用v-model須要指定modelValue--> <custom-input v-model:value="state.inputValue"></custom-input> </template> <script> import { reactive } from "vue"; import CustomInput from "../components/custom-input"; export default { name: "Home", components: { CustomInput }, setup() { const state = reactive({ inputValue: "" }); return { state }; } }; </script>
到了Vue3.0
中,由於一個組件支持多個v-model
,因此v-model
的實現方式有了新的改變。首先咱們不須要使用固定的屬性名和事件名了,在上例中由於是input
輸入框,屬性名咱們依然使用的是value
,可是也能夠是其餘任何的好比name
,data
,val
等等,而在值發生變化後對外暴露的事件名變成了update:value
,即update:屬性名
。而在調用組件的地方也就使用了v-model:屬性名
來區分不一樣的v-model
。
在本文中咱們主要講解了開發環境的搭建,setup
,reactive
,ref
,v-model
等的介紹,同時經過對比Vue3.0
與Vue2.0
的不一樣,讓你們對Vue3.0
有了必定的瞭解,在下文中咱們將爲你們帶來更多的介紹,好比技術屬性,watch
,生命週期等等,敬請期待。本文首發於公衆號【前端有的玩】,學習Vue
,面試刷題,盡在【前端有的玩】,`乘興裸辭心甚爽,面試工做屢遭難。
幸得每日一題伴,點擊關注莫偷懶。`,下週一新文推送,不見不散。
不要吹滅你的靈感和你的想象力; 不要成爲你的模型的奴隸。 ——文森特・梵高