Vue3.0--Vue Composition API使用體驗

2022-01-29 Vue中文社區

本文將之前採用Vue2.6開發的todoList小項目改造成為Vue3.0編寫,並介紹一下2.x和3.x之間寫法的不同之處。

點擊體驗[1] Github地址:Vue.js2.6版本todoList[2],Vue.js3.0版本todoList[3]

Vue3.x適配大部分Vue2.x的組件配置,也就是說以前我們在Vue2.x針對組件的一些配置項,例如:

export default {
name: 'test',
components: {},
props: {},
data () {
return {}
},
created(){},
mounted () {},
watch:{},
methods: {}
}

在Vue3.x中也是可以適配的,對應的相關生命周期方法也可正常執行,但是Vue3.x的一大核心是引入了Vue Composition API[4](組合式API),這使得組件的大部分內容都可以通過setup()方法進行配置,同時Vue Composition API在Vue2.x也可以使用,需要通過安裝@vue/composition-api來使用:

npm install @vue/composition-api
...
import VueCompositionApi from '@vue/composition-api';

Vue.use(VueCompositionApi);

下面主要介紹一下採用Vue Composition API來改造採用2.x開發的todoList項目時的新老代碼對比。

如何創建一個Vue3.0的項目

首先,安裝vue cli的最新版本,一般是vue cli 4,安裝成功後,調用:

vue create myapp

創建一個基於Vue2.x的項目,然後進入項目的根目錄,執行:

vue add vue-next

然後就會自動安裝vue-cli-plugin-vue-next[5]插件,完畢之後,myapp項目就會變成一個基於Vue3.0Beta版本的項目框架。

根實例初始化:

在2.x中通過new Vue()的方法來初始化:

import App from './App.vue'
new Vue({
  store,
  render: h => h(App)
}).$mount('#app')

在3.x中Vue不再是一個構造函數,通過createApp方法初始化:

import App from './App.vue'
createApp(App).use(store).mount('#app')

ref或者reactive代替data中的變量:

在2.x中通過組件data的方法來定義一些當前組件的數據:

...
data() {
  return {
    name: 'test',
    list: [],
  }
},
...

在3.x中通過ref或者reactive創建響應式對象:

import {ref,reactive} from 'vue'
...
setup(){
  const name = ref('test')
  const state = reactive({
    list: []
  })
  return {
      name,
      state
  }
}
...

ref將給定的值創建一個響應式的數據對象並賦值初始值(int或者string),reactive可以直接定義複雜響應式對象。

methods中定義的方法也可以寫在setup()中:

在2.x中methods來定義一些當前組件內部方法:

...
methods: {
  fetchData() {

  },
}
...

在3.x中直接在setup方法中定義並return:

...
setup(){
  const fetchData = ()=>{
      console.log('fetchData')
  }

  return {
      fetchData
  }
}
...

無法使用EventBus:

在2.x中通過EventBus的方法來實現組件通信:

var EventBus = new Vue()
Vue.prototype.$EventBus = EventBus
...
this.$EventBus.$on()  this.$EventBus.$emit()

在3.x中移除了$on, $off等方法(參考rfc[6]),而是推薦使用mitt[7]方案來代替:

import mitt from 'mitt'
const emitter = mitt()
// listen to an event
emitter.on('foo', e => console.log('foo', e) )
// fire an event
emitter.emit('foo', { a: 'b' })

由於3.x中不再支持prototype的方式給Vue綁定靜態方法,可以通過app.config.globalProperties.mitt = () => {}方案。

setup()中使用props和this:

在2.x中,組件的方法中可以通過this獲取到當前組件的實例,並執行data變量的修改,方法的調用,組件的通信等等,但是在3.x中,setup()在beforeCreate和created時機就已調用,無法使用和2.x一樣的this,但是可以通過接收setup(props,ctx)的方法,獲取到當前組件的實例和props:

export default {
  props: {
    name: String,
  },
  setup(props,ctx) {
    console.log(props.name)
    ctx.emit('event')
  },
}

注意ctx和2.x中this並不完全一樣,而是選擇性地暴露了一些property,主要有[attrs,emit,slots]。

watch來監聽對象改變

2.x中,可以採用watch來監聽一個對象屬性是否有改動:

...
data(){
  return {
    name: 'a'  
  }
},
watch: {
  name(val) {
    console.log(val)
  }
}
...

3.x中,在setup()中,可以使用watch來監聽:

...
import {watch} from 'vue'
setup(){
  let state = reactive({
    name: 'a'
  })
  watch(
    () => state.name,
    (val, oldVal) => {
      console.log(val)
    }
  )
  state.name = 'b'
  return {
      state
  }
}
...

在3.x中,如果watch的是一個數組array對象,那麼如果調用array.push()方法添加一條數據,並不會觸發watch方法,必須重新給array賦值:

let state = reactive({
    list: []
 })
 watch(
    () => state.list,
    (val, oldVal) => {
      console.log(val)
    }
  )

  state.list.push(1) // 不會觸發watch

  state.list = [1] // 會觸發watch

此問題不知是否是Vue3.x特意加上的,有待正式版出來後在驗證。

computed計算屬性:

2.x中:

...
computed: {
    storeData () {
      return this.$store.state.storeData
    },
},
...

3.x中:

...
import {computed} from 'vue'
setup(){
  const storeData = computed(() => store.state.storeData)

  return {
      storeData
  }
}
...

參考資料[1]

點擊體驗: https://link.zhihu.com/?target=https%3A//www.nihaoshijie.com.cn/mypro/vue3todo/index.html

[2]

Vue.js2.6版本todoList: https://link.zhihu.com/?target=https%3A//github.com/lvming6816077/vue-todo/

[3]

Vue.js3.0版本todoList: https://link.zhihu.com/?target=https%3A//github.com/lvming6816077/vue3todo/

[4]

Vue Composition API: https://link.zhihu.com/?target=https%3A//composition-api.vuejs.org/zh/api.html

[5]

vue-cli-plugin-vue-next: https://link.zhihu.com/?target=https%3A//github.com/vuejs/vue-cli-plugin-vue-next

[6]

rfc: https://link.zhihu.com/?target=https%3A//github.com/vuejs/rfcs/blob/master/active-rfcs/0020-events-api-change.md

[7]

mitt: https://link.zhihu.com/?target=https%3A//github.com/developit/mitt%23examples--demos

相關焦點

  • 準備將您的Vue應用遷移到Vue 3
    因此,這意味著,如果您打算進行遷移,則應考慮使用第三方插件,因為這將成為阻止程序。檢查您正在使用的插件的問題或路線圖,以查看它們是否計劃升級以支持Vue3。這是將支持Vue 3的插件的示例:Bootstrap VueVue MultiselectVuetify如果您使用過的插件還沒有升級到Vue 3的計劃,則可以通過要求該問題的作者支持Vue 3甚至參與其中的升級來幫助您做出貢獻。使用@vue/composition-api寫您的組件我非常感謝Vue社區提供的@vue/composition-api。
  • 尤雨溪在Vue3.0 Beta直播裡聊到了這些…
    前言在 4 月 21 日晚,Vue 作者尤雨溪在嗶哩嗶哩直播分享了Vue.js 3.0 Beta最新進展。以下是直播內容整理1.全新文檔RFCsVue.js 3.0 Beta發布後的工作重點是保證穩定性和推進各類庫集成所有的進度和文檔都將在全新RFCs文檔可以看到。2.
  • 阿里媽媽又做了新工具,幫你把 Vue2 代碼改成 Vue3 的
    .cn.vuejs.org/guide/migration/emits-option.html[19]連結: https://v3.cn.vuejs.org/guide/migration/events-api.html[20]連結: https://v3.cn.vuejs.org/guide/migration/filters.html[21]連結: https
  • 一張動圖理解Vue3的Composition Api
    這個文章其實很簡單, 只要能說明composition的好處,就是極好的,我們用一個非常簡單的萬金油場景,比如我們有一個非常簡單的to do list回顧Option<template>  <div id="app">    <input
  • 一張圖教你快速玩轉vue-cli3
    useBuiltIns: 'entry' 然後在入口文件添加 import '@babel/polyfill',這種方式的問題就是會增加包的大小3.配置scss/stylus共享全局變量對與scss,可以使用如下方式開啟:// vue.config.js
  • Vue的基本使用
    基本使用步驟① 導入 vue.js 的 script 腳本文件② 在頁面中聲明一個將要被 vue 所控制的 DOM 區域vm.a // => 3當這些數據改變時,視圖會進行重渲染。這裡唯一的例外是使用 Object.freeze(),這會阻止修改現有的 property,也意味著響應系統無法再追蹤變化。
  • Vue 3 生命周期完整指南
    Vue2 和 Vue3 中的生命周期鉤子的工作方式非常相似,我們仍然可以訪問相同的鉤子,也希望將它們能用於相同的場景。如果項目使用 選項 API,就不必更改任何代碼了,因為 Vue3 兼容以前的版本。      }        }</script> 在組合API中使用Vue 3生命周期鉤子在組合API中,我們需要將生命周期鉤子導入到項目中,才能使用,這有助於保持項目的輕量性。
  • vue 使用 vue-pdf 實現pdf在線預覽
    本篇筆記循序漸進,從基礎的demo,到一個可用的程度,文末列出了大家在實際使用的過程中可能會遇到的問題和解決方案。安裝:這個沒有啥背景知識可講,我們直接跳到安裝環節,vue-pdf 和其他vue組件的安裝並無不同,打開命令行,敲入:npm install --save vue-pdf注意路徑。
  • vue的$nextTick的使用+源碼分析
    上面,我拋了一個問題,現在來聊一聊這個問題,首先說一說nextTick的作用,這裡我就直接引用官網api上的一句話,我覺得已經說的非常清楚了:將回調延遲到下次 DOM 更新循環之後執行。在修改數據之後立即使用它,然後等待 DOM 更新。它跟全局方法 Vue.nextTick 一樣,不同的是回調的 this 自動綁定到調用它的實例上。
  • Vue 生命周期鉤子完整指南
    Vue 2 和 Vue 3 中的生命周期鉤子,其工作方式非常相似。如果我們在項目中使用Options API,那就不必更改Vue生命周期鉤子的任何代碼,因為Vue 3兼容Vue之前的版本。OK,現在讓我們到Composition API中使用Vue 3生命周期鉤子。在Vue 3 Composition API中使用Vue生命周期鉤子在Composition API中,我們必須先將生命周期鉤子導入到項目中,然後才能使用它們。這是為了儘可能保持項目的輕量級。
  • 基於Vue實現一個有點意思的拼拼樂小遊戲
    本文轉載自【微信公眾號:趣談前端,ID:beautifulFront】經微信公眾號授權轉載,如需轉載與原文作者聯繫前言為了加深大家對vue的了解和vue項目實戰,筆者採用vue生態來重構此項目,方便大家學習和探索。
  • webpack loader 與plugin 開發實戰 —— 點擊 vue 頁面元素跳轉到對應的 vscode 代碼
    其包含了模塊資源、編譯生成資源以及變化的文件和被跟蹤依賴的狀態信息等等,以供插件工作時使用。如果我們在插件中需要完成一個自定義的編譯過程,那麼必然會用到這個對象。中調試由於我們是在 vue 項目中使用,所以為了配合 vue 的真實環境,我們通過 vue-cli 的webpack 配置來調試 loader。
  • 這幾款基於 vue3 和 vite 的開箱即用的中後臺管理模版,讓你 yyds !
    我們都知道 vue3 已經發布一年多了,相關的生態也在慢慢建立,很多公司也在嘗試用 vue3 來開發自己的應用系統。但是由於生態的不完善以及缺乏成熟方案的落地,vue3 的應用仍然探索和小規模試驗中。ant-simple-pro 是一款支持 vue3.0,react,angular,typescript
  • 記一次Spring boot 和Vue前後端分離的入門培訓
    前端工具和環境:Node.js V10.15.0Vue.js V2.5.21yarn: V1.13.0IDE:VScode後端工具和環境: Maven: 3.52jdk: 1.8MySql: 14.14IDE: IDEASpring Boot: 2.0+
  • 使用electron+vue開發一個跨平臺todolist(便籤)桌面應用
    開發桌面應用,對於一個web開發者來說,html+javascript+css的開發體驗讓我非常舒服。# 2在使用electron期間,我順便寫了一個簡單的todolist(便籤)應用,用於學習和嘗試;項目地址:https://github.com/xiajingren/xhznl-todo-list 界面參考了小黃條便籤。
  • 技術分享:vue 過濾器
    vue 過濾器 1 關於 vue 過濾器 在vue1.0的時候其實是內置了過濾器的,但是考慮到好多過濾器並不一定會被開發所調用,所以把原本內置的過濾器就給去掉了,但是過濾器還是比較普遍的,所以我們從vue2.0之後就需要自己定義過濾器
  • Taro 正式發布 3.4 版本: 全面支持 Preact & Vue 3.2
    上月我們還推出了支持開發鴻蒙應用的 v3.5.0 canary 版本,歡迎各位同學關注~一、支持使用 Preact—開發小程序應用時我們經常會受到包體積的掣肘,大型應用常常為了「尺土寸金」的包體積開展瘦身行動。在此背景下 React 將近 100k 的體積則顯得有點過於奢侈。
  • 10個簡單的技巧讓你的 vue.js 代碼更優雅 - 酷扯兒
    本文轉載自【微信公眾號:前端人,ID:FrontendPeople】,經微信公眾號授權轉載,如需轉載原文作者聯繫前言作為深度代碼潔癖,我們都希望能寫出簡單高效的代碼,讓我們的代碼看起來更加優雅,讓我們拋棄繁雜的代碼,一起開啟簡單的旅程~~slots 新語法向 3.0 看齊使用帶有「#」的新命名插槽縮寫語法,在Vue 2.6.0
  • 史上最全 Vue 前端代碼風格指南
    components/|- TheHeading.vue|- TheSidebar.vue複製代碼1.2.3 基礎組件名基礎組件:不包含業務,獨立、具體功能的基礎組件,比如日期選擇器、模態框等。components/|- StudentDashboardSettings.vue|- UserProfileOptions.vue複製代碼1.3 代碼參數命名1.3.1 name組件名應該始終是多個單詞,應該始終是 PascalCase 的。
  • Taro 3.4 beta 發布: 支持 Preact 為應用開闢更多體積空間
    安裝 v3.4.0-beta 的 CLI 工具:npm i -g @tarojs/cli@beta2.修改 package.json 文件中 Taro 相關依賴的版本修改為 ~3.4.0-beta.0,再重新安裝依賴。3.