前言
本筆記主要基于官方文檔《遷移政策—— 全局 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:Vue 2.x 的全局配置:
- Vue.extend( options )
- Vue.nextTick( [callback, context] )
- Vue.set( target, propertyName/index, value )
- Vue.delete( target, propertyName/index )
- Vue.directive( id, [definition] )
- Vue.filter( id, [definition] )
- Vue.component( id, [definition] )
- Vue.use( plugin )
- Vue.mixin( mixin )
- Vue.compile( template )
- Vue.observable( object )
- Vue.version
- silent
- optionMergeStrategies
- devtools
- errorHandler
- warnHandler
- ignoredElements
- keyCodes
- performance
- productionTip
Vue 2.x 全局 api 的弊端
Vue 2.x 沒有 “APP” 概念(APP 一個重要的特點就是互相獨立)。Vue 2.x 所謂的 app 是通過
new Vue()
建立的
Vue
根執行個體。這樣有一個巨大的弊端:從相同的 Vue 構造函數建立的每個根執行個體都共享同一套全局環境。這樣就導緻一個問題,隻要某一個根執行個體對 全局 API 和 全局配置做了變動,就會影響由相同 Vue 構造函數建立的其他根執行個體。
Vue 3.x 的改動
引入 createApp
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 ( ) |
---|---|
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.config.productionTip
Vue 2.x的說明:
Vue.config.productionTip
- 類型:
boolean
- 預設值:
true
用法:
設定為
以阻止 vue 在啟動時生成生産提示。
false
在 Vue 3.x,隻有在使用 “dev + full build”(該建構器具有運作時編譯器功能和警告提示功能)時,才會顯示“use production build”的提示。對于“ES modules”建構器,因為其與“bundler”一起使用,而且在大多數情況下“CLI”或其他 “boilerplate ”(又叫手腳架 )都會正确的配置項目環境。是以,在絕大多數的情況下
productionTip
不會出現,是以可以去掉了。
Vue.config.ignoredElements
重命名為 app.config.isCustomElement
Vue.config.ignoredElements
app.config.isCustomElement
Vue 2.x的說明:
Vue.config.ignoredElements
- 類型:
Array<string | RegExp>
- 預設值:
[]
- 用法:
須使 Vue 忽略在 Vue 之外的自定義元素 (e.g. 使用了 Web Components APIs)。否則,它會假設你忘記注冊全局元件或者拼錯了元件名稱,進而抛出一個關于Vue.config.ignoredElements = [ 'my-custom-web-component', 'another-web-component', // 用一個 `RegExp` 忽略所有“ion-”開頭的元素 // 僅在 2.5+ 支援 /^ion-/ ]
的警告。
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”建構器支援
。如果,使用的是“ Runtime-only”建構器,則必須在建構器中配置
app.config.isCustomElement
。例如,通過在webpack的配置檔案中的
isCustomElement
的
vue-loader
配置。
compilerOptions
關于“Runtime + Compiler”與“ Runtime-only”的差別,具體可看:《對Vue中 runtime-compiler 和 runtime-only 兩種模式的了解》// in webpack config rules: [ { test: /\.vue$/, use: 'vue-loader', options: { compilerOptions: { isCustomElement: tag => tag === 'plastic-button' } } } // ... ]
Vue.prototype
替換為 app.config.globalProperties
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.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
更多知識:provide / inject
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節:數組的監聽