天天看點

Vue 3 遷移政策筆記—— 第14節:全局 API

前言

本筆記主要基于官方文檔《遷移政策—— 全局 API》彙總而來。如有了解出入,請以官方文檔為主。建議您以官方文檔為主,本文為輔。這樣您可以“以自己為主”審視的閱讀,進而不被我的觀點帶偏。

概述

新增一個新的 API

createApp

,調用其傳回一個 app 執行個體。

createApp

傳回的執行個體之間互相獨立。

Vue 2.x 全局 api 的舉例

Vue 2.x 擁有許多 全局 api 和 全局配置。在全局範圍内,這些 API 和配置改變了 Vue 的行為。

例如,建立一個全局元件:

Vue.component('button-counter', {
  data: () => ({
    count: 0
  }),
  template: '<button @click="count++">Clicked {{ count }} times.</button>'
})
           

或建立一個全局指令:

Vue.directive('focus', {
  inserted: el => el.focus()
})
           

又或者全局使用一個插件:

var Vue = require('vue')
var VueRouter = require('vue-router')

Vue.use(VueRouter)
           
Vue 2.x 的全局 API:
  1. Vue.extend( options )
  2. Vue.nextTick( [callback, context] )
  3. Vue.set( target, propertyName/index, value )
  4. Vue.delete( target, propertyName/index )
  5. Vue.directive( id, [definition] )
  6. Vue.filter( id, [definition] )
  7. Vue.component( id, [definition] )
  8. Vue.use( plugin )
  9. Vue.mixin( mixin )
  10. Vue.compile( template )
  11. Vue.observable( object )
  12. Vue.version
Vue 2.x 的全局配置:
  1. silent
  2. optionMergeStrategies
  3. devtools
  4. errorHandler
  5. warnHandler
  6. ignoredElements
  7. keyCodes
  8. performance
  9. productionTip

Vue 2.x 全局 api 的弊端

Vue 2.x 沒有 “APP” 概念(APP 一個重要的特點就是互相獨立)。Vue 2.x 所謂的 app 是通過

new Vue()

建立的

Vue

根執行個體。這樣有一個巨大的弊端:從相同的 Vue 構造函數建立的每個根執行個體都共享同一套全局環境。這樣就導緻一個問題,隻要某一個根執行個體對 全局 API 和 全局配置做了變動,就會影響由相同 Vue 構造函數建立的其他根執行個體。

Vue 3.x 的改動

引入

createApp

Vue 3.x 引入一個新的 API

createApp

,用來替代

new Vue()

來建立 app 執行個體。

import { createApp } from 'vue'

const app = createApp({})
           

app 執行個體擁有全局 API 的一個子集。所有會改變了 Vue 的行為的 全局 API 和 全局配置 都遷移到這個子集中來。具體變動如下表格:

2.x Global API 3.x Instance API (

app

)
Vue.config app.config
Vue.config.productionTip removed (詳情請看)
Vue.config.ignoredElements app.config.isCustomElement (詳情請看)
Vue.component app.component
Vue.directive app.directive
Vue.mixin app.mixin
Vue.use app.use (詳情請看)
Vue.prototype app.config.globalProperties (詳情請看)

所有其他不會改變了 Vue 的行為的全局 API 都通過

exports

導出,調用時需要手動導入。例如:

import { nextTick } from 'vue'

nextTick(() => {
  // something DOM-related
})
           

具體請看下一節: Global API Treeshaking

移除

Vue.config.productionTip

Vue 2.x

Vue.config.productionTip

的說明:
  • 類型:

    boolean

  • 預設值:

    true

  • 用法:

    設定為

    false

    以阻止 vue 在啟動時生成生産提示。

在 Vue 3.x,隻有在使用 “dev + full build”(該建構器具有運作時編譯器功能和警告提示功能)時,才會顯示“use production build”的提示。對于“ES modules”建構器,因為其與“bundler”一起使用,而且在大多數情況下“CLI”或其他 “boilerplate ”(又叫手腳架 )都會正确的配置項目環境。是以,在絕大多數的情況下

productionTip

不會出現,是以可以去掉了。

Vue.config.ignoredElements

重命名為

app.config.isCustomElement

Vue 2.x

Vue.config.ignoredElements

的說明:
  • 類型:

    Array<string | RegExp>

  • 預設值:

    []

  • 用法:
    Vue.config.ignoredElements = [
      'my-custom-web-component',
      'another-web-component',
      // 用一個 `RegExp` 忽略所有“ion-”開頭的元素
      // 僅在 2.5+ 支援
      /^ion-/
    ]
               
    須使 Vue 忽略在 Vue 之外的自定義元素 (e.g. 使用了 Web Components APIs)。否則,它會假設你忘記注冊全局元件或者拼錯了元件名稱,進而抛出一個關于

    Unknown custom element

    的警告。

引入

ignoredElements

的目的時為了支援本地自定義元素(即,Vue 外部定制的自定義元素),是以新的命名相比舊的命名更加淺顯易懂。此外,

config.isCustomElement

接收的函數比舊的

string/RegExp

模式更加的靈活:

// before
Vue.config.ignoredElements = ['my-el', /^ion-/]

// after
const app = Vue.createApp({})
app.config.isCustomElement = tag => tag.startsWith('ion-')
           

着重提醒:

在 Vue 3.x 中,對自定義元素是否是元件名的檢查已經移動到模闆編譯階段執行。是以,隻有“Runtime + Compiler”建構器支援

app.config.isCustomElement

。如果,使用的是“ Runtime-only”建構器,則必須在建構器中配置

isCustomElement

。例如,通過在webpack的配置檔案中的

vue-loader

compilerOptions

配置。
// in webpack config
rules: [
  {
    test: /\.vue$/,
    use: 'vue-loader',
    options: {
      compilerOptions: {
        isCustomElement: tag => tag === 'plastic-button'
      }
    }
  }
  // ...
]
           
關于“Runtime + Compiler”與“ Runtime-only”的差別,具體可看:《對Vue中 runtime-compiler 和 runtime-only 兩種模式的了解》

Vue.prototype

替換為

app.config.globalProperties

在 Vue 2.x 中,Vue.prototype 通常用于添加可在所有元件中通路的屬性(即,全局屬性)。Vue 3.x 的

app.config.globalProperties

與其完全相同。

// before - Vue 2
Vue.prototype.$http = () => {}

// after - Vue 3
const app = Vue.createApp({})
app.config.globalProperties.$http = () => {}
           

Vue.use

改為

app.use

兩者的作用及用法完全相同。在 Vue 3.x 已經不再支援

Vue.use

,統一使用

app.use

來安裝插件。

将根執行個體挂載到頁面上

通過

createApp

建立好根執行個體後,我們還需要将根執行個體挂在到頁面上,才能看到效果。如下:

const app = createApp(MyApp)

app.component('button-counter', {
  data: () => ({
    count: 0
  }),
  template: '<button @click="count++">Clicked {{ count }} times.</button>'
})

app.directive('focus', {
  mounted: el => el.focus()
})

// 通過 app.mount 将 app 挂載到html檔案中id為`#app`的元素上
app.mount('#app')
           

Provide / Inject

與 Vue 2.x 一樣,Vue 3.x app 執行個體同樣支援

provide

inject

。如下:

// in the entry
app.provide('guide', 'Vue 3 Guide')

// in a child component
export default {
  inject: {
    book: {
      from: 'guide'
    }
  },
  template: `<div>{{ book }}</div>`
}
           
關于

provide

inject

更多知識:provide / inject

在多個 app 是執行個體間共享配置

Vue 3.x 提供了一個多個 app 共享配置的方法:設定一個建立 app 的工廠函數。如下:

import { createApp } from 'vue'
import Foo from './Foo.vue'
import Bar from './Bar.vue'

const createMyApp = options => {
  const app = createApp(options)
  app.directive('focus' /* ... */)

  return app
}

createMyApp(Foo).mount('#foo')
createMyApp(Bar).mount('#bar')
           

很顯然,這個方法的共享并不是多個執行個體使用同一個配置環境。而是,借助工廠函數對每一個 app 執行個體做相同的配置。彼此之間的配置是不通用。也就是說,在具體的一個 app 執行個體的子元件中對全局配置做改動,并不會影響到其他 app 執行個體。

本系列目錄

  • Vue 3 遷移政策筆記—— 第1節:v-for 中的 Ref 數組
  • Vue 3 遷移政策筆記—— 第2節:Async Components 異步元件
  • Vue 3 遷移政策筆記—— 第3節:Attribute Coercion Behavior (屬性強制行為)
  • Vue 3 遷移政策筆記——第4節:$attrs 包括class&style
  • Vue 3 遷移政策筆記—— 第5節:移除 $children
  • Vue 3 遷移政策筆記—— 第6節:自定義指令
  • Vue 3 遷移政策筆記—— 第7節:自定義元素互動
  • Vue 3 遷移政策筆記—— 第8節:Data 選項
  • Vue 3 遷移政策筆記—— 第9節:新增 emits 選項
  • Vue 3 遷移政策筆記—— 第10節:事件 API
  • Vue 3 遷移政策筆記—— 第11節:移除過濾器
  • Vue 3 遷移政策筆記—— 第12節:片段
  • Vue 3 遷移政策筆記—— 第13節:函數式元件
  • Vue 3 遷移政策筆記—— 第14節:全局 API
  • Vue 3 遷移政策筆記—— 第15節:全局 API 的 tree shaking
  • Vue 3 遷移政策筆記—— 第16節:Inline Template 屬性
  • Vue 3 遷移政策筆記—— 第17節:Key 屬性
  • Vue 3 遷移政策筆記—— 第18節:按鍵修飾符
  • Vue 3 遷移政策筆記—— 第19節:移除 $listeners
  • Vue 3 遷移政策筆記—— 第20節:Props 的預設值函數不能通路this
  • Vue 3 遷移政策筆記—— 第21節:渲染函數 API
  • Vue 3 遷移政策筆記—— 第22節:Slots 的統一
  • Vue 3 遷移政策筆記—— 第23節:Transition Class 的變化
  • Vue 3 遷移政策筆記—— 第24節:Transition Group 不再需要設定根元素
  • Vue 3 遷移政策筆記—— 第25節:v-on.native修飾符被移除
  • Vue 3 遷移政策筆記—— 第26節:在元件上使用 v-model 的變化
  • Vue 3 遷移政策筆記—— 第27節:v-if 和 v-for 的優先級
  • Vue 3 遷移政策筆記—— 第28節:v-bind 合并行為
  • Vue 3 遷移政策筆記—— 第29節:數組的監聽

繼續閱讀