内容が多いため、
Vue2 と比較した Vue3 のアップデート (1) >>> の2 つのパートに分けました。
18. キー修飾子の変更
vue3 では、v-on 修飾子としての数字 (つまり、キー コード) の使用はサポートされなくなり、config.keyCodes もサポートされなくなります。Vue
2 では、keyCode を v-on メソッドを変更する方法として使用できます。
<!-- 键码版本 -->
<input v-on:keyup.13="submit" />
さらに、グローバル config.keyCodes オプションを使用して独自のエイリアスを定義することもできます。
Vue.config.keyCodes = {
f1: 112
}
<!-- 键码版本 -->
<input v-on:keyup.112="showHelpText" />
<!-- 自定义别名版本 -->
<input v-on:keyup.f1="showHelpText" />
Vue 3 でキーコード修飾子を使用すると、「「v-on」ディレクティブの「KeyboardEvent.keyCode」修飾子は非推奨です。代わりに「KeyboardEvent.key」を使用してください」というエラーが報告されます。代替解決策:
KeyboardEvent.key
<!-- 别名版本 -->
<input v-on:keyup.enter="submit" />
19. $listeners を削除する
vue3 では、イベント リスナーは $attrs オブジェクトの一部になったため、$listeners オブジェクトは Vue 3 で削除されました。
Vue 2 では、this.$attrs を通じてコンポーネントに渡される属性にアクセスでき、this.$listeners を通じてコンポーネントに渡されるイベント リスナーにアクセスできます。Vue 3 の仮想 DOM では、イベント リスナーには on というプレフィックスが付きます。
. 属性を変更して $attrs オブジェクトの一部となり、$listeners が削除されます。
このコンポーネントが id 属性と v-on:close リスナーを受け取ると、$attrs オブジェクトは次のようになります:
v2:
{
id: 'my-input',
}
v3:
{
id: 'my-input',
onClose: () => console.log('close 事件被触发')
}
20. マウントされたアプリケーションは要素を置き換えません
Vue 2.x では、テンプレートを使用してアプリケーションをマウントすると、レンダリングされたコンテンツがマウントするターゲット要素を置き換えます。Vue 3.x では、レンダリングされたアプリケーションは子要素として挿入され、ターゲット要素の innerHTML を置き換えます。
アプリケーション テンプレートをマウントします。
<div id="rendered">{
{
message }}</div>
元のページ:
<body>
<div id="app">
Some app content
</div>
</body>
v2 レンダリング結果:
<body>
<div id="rendered">Hello Vue!</div>
</body>
v3 レンダリング結果:
<body>
<div id="app" data-v-app="">
<div id="rendered">Hello Vue!</div>
</div>
</body>
21. propsData オプションを削除する
propsData オプションは、以前は Vue インスタンスの作成時に props を渡すために使用されていましたが、現在は削除されています。Vue 3 アプリケーションのルート コンポーネントの props を渡したい場合は、createApp の 2 番目のパラメーターを使用します。
v2:
const Comp = Vue.extend({
props: ['username'],
template: '<div>{
{ username }}</div>'
})
new Comp({
propsData: {
username: 'Evan'
}
})
v3:
const app = createApp(
{
props: ['username'],
template: '<div>{
{ username }}</div>'
},
{
username: 'Evan' }
)
22. prop のデフォルト関数でこれにアクセスします
現在、prop のデフォルト値を生成する Vue 3 のファクトリー関数は、これにアクセスできなくなりました。
代わりに、
コンポーネントによって受け取られた元の prop がパラメータとしてデフォルト関数に渡され、
inject API はデフォルト関数で使用できます。
import {
inject } from 'vue'
export default {
props: {
theme: {
default (props) {
// `props` 是传递给组件的、
// 在任何类型/默认强制转换之前的原始值,
// 也可以使用 `inject` 来访问注入的 property
return inject('theme', 'default-theme')
}
}
}
}
23. レンダリング機能API(変更)
レンダリング関数のパラメータ
2.x では、render 関数は h 関数 (createElement の慣用的なエイリアス) をパラメータとして自動的に受け取ります。
// Vue 2 渲染函数示例
export default {
render(h) {
return h('div')
}
}
3.x では、h 関数はパラメーターとして自動的に渡されるのではなく、グローバルにインポートされるようになりました。
// Vue 3 渲染函数示例
import {
h } from 'vue'
export default {
render() {
return h('div')
}
}
レンダリング関数のシグネチャの変更
2.x では、render 関数は h 関数などのパラメータを自動的に受け取ります。
// Vue 2 渲染函数示例
export default {
render(h) {
return h('div')
}
}
3.x では、render 関数はパラメータを受け取らなくなったため、主に setup() 関数内で使用されます。これには、スコープ内で宣言されたリアクティブ状態と関数、および setup() に渡されるパラメーターにアクセスできるという利点もあります。
import {
h, reactive } from 'vue'
export default {
setup(props, {
slots, attrs, emit }) {
const state = reactive({
count: 0
})
function increment() {
state.count++
}
// 返回渲染函数
return () =>
h(
'div',
{
onClick: increment
},
state.count
)
}
}
VNode Prop のフォーマット
2.x では、domProps には VNode プロパティのネストされたリストが含まれます。
// 2.x
{
staticClass: 'button',
class: {
'is-outlined': isOutlined },
staticStyle: {
color: '#34495E' },
style: {
backgroundColor: buttonColor },
attrs: {
id: 'submit' },
domProps: {
innerHTML: '' },
on: {
click: submitForm },
key: 'submit-button'
}
3.x では、VNode prop 構造全体がフラットです。上の例を使用して、今どのように見えるかを見てみましょう。
// 3.x 语法
{
class: ['button', {
'is-outlined': isOutlined }],
style: [{
color: '#34495E' }, {
backgroundColor: buttonColor }],
id: 'submit',
innerHTML: '',
onClick: submitForm,
key: 'submit-button'
}
24. 統合スロット
vue3 では、this.$slots はスロットを関数として公開するようになり、this.$scopedSlots は削除されました。
v2:
レンダリング関数、つまり h を使用する場合、コンテンツ ノードのスロット データ プロパティを定義するために 2.x が使用されます。
// 2.x 语法
h(LayoutComponent, [
h('div', {
slot: 'header' }, this.header),
h('div', {
slot: 'content' }, this.content)
])
さらに、スコープ付きスロットは、次の構文を使用して参照できます。
// 2.x 语法
this.$scopedSlots.header
v3:
// 3.x Syntax
h(LayoutComponent, {
}, {
header: () => h('div', this.header),
content: () => h('div', this.content)
})
スコープ指定されたスロットをプログラムで参照する必要がある場合、それらは $slots オプションに統合されるようになりました。
// 2.x 语法
this.$scopedSlots.header
// 3.x 语法
this.$slots.header()
25. サスペンスを追加する
サスペンスは実験的な新機能であり、その API はいつでも変更される可能性があります。
公式はまた、「 実稼働環境では使用しないでください 」と注意している
ため、これについては簡単に理解してください。
このコンポーネントは、待機中のプロセスを単一コンポーネント内ではなくコンポーネント ツリー上で処理できるようにする代替手段を提供します。コンポーネントには 2 つのスロットがあります。どちらも直接の子ノードを 1 つだけ受け取ります。デフォルトスロット内のノードが可能な限り表示されます。そうでない場合は、フォールバック スロットのノードが表示されます。
26. 移行クラス名の変更
vue3 では、遷移クラス名 v-enter が v-enter-from に変更され、遷移クラス名 v-leave が v-leave-from に変更されます。
コンポーネントの関連する prop 名も変更されました。
Leave-class は、leave-from-class に名前変更されました (レンダリング関数または JSX では、leaveFromClass として記述できます)
enter-class は、enter-from-class に名前変更されました (レンダリング関数または JSX では、次のように記述できます: enterFromClass)
v2 移行クラス:
.v-enter,
.v-leave-to {
opacity: 0;
}
.v-leave,
.v-enter-to {
opacity: 1;
}
v3 移行クラス:
.v-enter-from,
.v-leave-to {
opacity: 0;
}
.v-leave-from,
.v-enter-to {
opacity: 1;
}
27. ルート ノードとしてのトランジションは、トランジション効果をトリガーしなくなりました。
Vue 2 では、コンポーネントのルート ノードとして使用することにより、コンポーネントの外部からトランジション エフェクトがトリガーされる可能性があります。
<!-- 模态组件 -->
<template>
<transition>
<div class="modal"><slot/></div>
</transition>
</template>
<!-- 用法 -->
<modal v-if="showModal">hello</modal>
showModal の値を切り替えると、モーダル コンポーネント内でトランジション エフェクトがトリガーされます。
しかし、Vue 3 では、<transition>
ルート ノードとして使用しているコンポーネントが外部から切り替えられると、トランジション エフェクトがトリガーされなくなりました。代わりに、プロパティをコンポーネントに渡して、コンポーネント内の遷移をトリガーできます。
28. トランジション グループのルート要素はデフォルトでルート要素をレンダリングしなくなりました
Vue 3 では、<transition-group>
ルート要素はデフォルトでレンダリングされなくなりましたが、タグ属性を使用してルート要素を作成することはできます。
Vue 2 では、<transition-group>
他のカスタム コンポーネントと同様に、ルート要素が必要です。デフォルトのルート要素は one です<span>
が、これは tag 属性を使用してカスタマイズできます。
<transition-group tag="ul">
<li v-for="item in items" :key="item">
{
{ item }}
</li>
</transition-group>
Vue 3 ではフラグメントがサポートされているため、コンポーネントにルート ノードは必要なくなりました。そのため、<transition-group>
ルート ノードはデフォルトではレンダリングされなくなりました。
上の例のように、Vue 2 コードでタグ属性を定義した場合、すべては以前と同じになります。
29. v-on.native 修飾子を削除する
v-on の .native 修飾子が削除されました。同時に、新しい発行オプションにより、サブコンポーネントが実際にトリガーされるイベントを定義できるようになります。
したがって、コンポーネント トリガーとして定義されていない子コンポーネント内のすべてのイベント リスナーについて、Vue はそれらをネイティブ イベント リスナーとして子コンポーネントのルート要素に追加します (子コンポーネントのオプションで継承Attrs: false が設定されている場合を除く)。
<my-component
v-on:close="handleComponentEvent"
v-on:click="handleNativeClickEvent"
/>
MyComponent.vue:
<script>
export default {
emits: ['close']
}
</script>
30、vモデル
vue3 がカスタム コンポーネントに使用される場合、v-model プロパティとイベントのデフォルト名が変更されました:
prop: value -> modelValue;
events: input -> update:modelValue;
v-bind の .sync 修飾子とコンポーネントのモデル オプションが変更されました取り除く
v2:
プロップ名またはイベント名を変更する場合は、ChildComponent コンポーネントにモデル オプションを追加する必要があります。
<ChildComponent v-model="pageTitle" />
// ChildComponent.vue
export default {
model: {
prop: 'title',
event: 'change'
},
props: {
// 这将允许 `value` 属性用于其他用途
value: String,
// 使用 `title` 代替 `value` 作为 model 的 prop
title: {
type: String,
default: 'Default title'
}
}
}
したがって、この例では、v-model は次の短縮形です。
<ChildComponent :title="pageTitle" @change="pageTitle = $event" />
v3:
3.x では、カスタム コンポーネントの v-model は、modelValue プロパティを渡し、スローされた update:modelValue イベントを受け取ることと同等です。モデルの名前を変更する必要がある場合は、コンポーネントのモデル オプションの代わりにパラメーターを v-model に渡すことができます。
<ChildComponent v-model:title="pageTitle" />
<!-- 是以下的简写: -->
<ChildComponent :title="pageTitle" @update:title="pageTitle = $event" />
31. v-if と v-for の優先度の比較
v2:
バージョン 2.x では、v-if と v-for が要素で同時に使用される場合、v-for が優先されます。
v3:
バージョン 3.x では、v-if は常に v-for よりも前に有効になります。
32. v-bind マージ動作
v2:
2.x では、要素が v-bind="object" と同一の独立属性の両方を定義している場合、独立属性は常に object 内のバインディングをオーバーライドします。
<!-- 模板 -->
<div id="red" v-bind="{ id: 'blue' }"></div>
<!-- 结果 -->
<div id="red"></div>
v3:
3.x では、要素が v-bind="object" と同一の独立属性の両方を定義している場合、バインディングが宣言される順序によって、バインディングがどのように結合されるかが決まります。後で定義したプロパティは、以前に定義した結果をオーバーライドします。
<!-- 模板 -->
<div id="red" v-bind="{ id: 'blue' }"></div>
<!-- 结果 -->
<div id="blue"></div>
<!-- 模板 -->
<div v-bind="{ id: 'blue' }" id="red"></div>
<!-- 结果 -->
<div id="red"></div>
33. VNode ライフサイクル イベント
Vue 2 では、イベントを通じてコンポーネントのライフサイクルの主要な段階をリッスンできます。これらのイベント名は、hook: プレフィックスで始まり、対応するライフサイクル フックの名前が続きます。
Vue 3 では、このプレフィックスは vnode- に変更されました。さらに、これらのイベントは、コンポーネントの場合と同様に、HTML 要素でも使用できるようになりました。
v2:
Vue 2 では、これらのイベント名は対応するライフサイクル フックと一致しており、接頭辞としてフック:: が付けられます。
<template>
<child-component @hook:updated="onUpdated">
</template>
v3:
Vue 3 では、イベント名には vnode- プレフィックスが付きます。
<template>
<child-component @vnode-updated="onUpdated">
</template>
34. ウォッチリスニングアレイ
Vue3 では、watch オプションを使用して配列をリッスンする場合、配列が置換されたときにのみコールバックが起動されます。つまり、配列が変更されたときに listen コールバックはトリガーされなくなります。配列が変更されたときに listen コールバックをトリガーするには、deep オプションを指定する必要があります。
watch: {
bookList: {
handler(val, oldVal) {
console.log('book list changed')
},
deep: true
},
}