目次
VUEX
ビュークスとは何ですか
Vuex: あらゆるコンポーネントで使用できる公開データを管理する Vue の状態管理ツールです
vuexの永続データ
プラグインをインストールする
npm i vuex-persistedstate --save
store/index.js で導入
import vuexPersist from "vuex-persistedstate"
構成
plugins: [ new vuexPersist({ storage: window.localStorage, }).plugin, ],
vuex の 5 つのコア
州 |
状態はデータを保存します。これはデータに相当します。 |
突然変異 |
状態を変更する場所であり、それのみが状態を変更する権利を持っています |
ゲッター |
計算されたプロパティと同等 |
行動 |
vuex で非同期操作を実行する場所 |
モジュール |
多数の状態がある場合、モジュールはモジュールによって管理されます |
州は this.$store.state.xxx を使用します
データが変更されると自動的に更新される、計算されたプロパティを使用することをお勧めします。
ミューテーションでは this.$store.commit ('イベント名'、渡されたパラメータ) を使用します。
ミューテーションのイベントには 2 つのパラメーターがあります。最初のパラメーターは vuex の状態である state である必要があり、2 番目のパラメーターは渡された値です。
アクションの使用
内部の各イベントには、関連する vuex コンテキストのインスタンスであるコンテキストパラメーターがあります。
vue ページのthis.$store.dispath('event name') を通じてアクションを送信できます。
vuex のヘルパー関数
補助関数は、vuex のデータとメソッドを vue コンポーネントにマップできます。操作を簡素化するという目的を達成するため
ヘルパー関数
マップ状態マップアクションマップミューテーションマップゲッター
vueページにヘルパー関数を導入
import { mapActions, mapGetters, mapMutations, mapState } from 'vuex'
予防:
MapState と MapGetter は 計算されたプロパティで使用することが推奨されており、データ データとして直接使用できます。
computed: {
...mapState(["shopData"]),
},
他の補助関数はメソッド内にあります
methods: {
...mapActions(["getData"]),
...mapMutations(["add"]),
}
詳細なモジュール化と補助機能の使用については、ここをクリックしてください。
vueルーター
フロントエンドルーティングの原理
ルーティングは URL を解析し、対応するコントローラーを呼び出して、ページを再リクエストせずにページのビューを更新するために使用されます。
ルーティングパターン
ルーティングはハッシュモードとヒストリーモードに分かれています
ハッシュと履歴の切り替え
ルーターの Index.js ファイルには、新しい Router()があり、内部のモードはデフォルトでハッシュモードですが、ここで履歴モードに変更できます。
const router = new VueRouter({
routes,
mode:'hash' //可在这里更改为history模式
})
ハッシュモード
ハッシュ モード: ブラウザ内の記号「#」と # の後の文字はハッシュと呼ばれます
http://localhost:8080/#/login
特徴
1 ハッシュは http リクエストに含まれないため、ハッシュを変更してもページはリロードされません
2 hashchange はハッシュ変更イベントを監視するために使用されます
3 変更が行われるたびにブラウザに履歴が追加されます
方法
HashHistory.push ジャンプルート、履歴スタックを追加
HashHistory.replace() はルートにジャンプし、履歴を追加せずに現在のページを直接置き換えます。
履歴モード
http://localhost:8080/home
特徴
1 履歴モードの URL はバックエンドの URL と同じである必要があります。バックエンドに対応するルートがない場合、404 エラーが返されます。
2 PopState (window.onpopstate )は、履歴変更イベントを監視するために使用されます。
方法
History.pushState() ルートをジャンプし、履歴スタックを追加します
History.replaceState() はルートにジャンプし、履歴を追加せずに現在のページを直接置き換えます。
ルーティングパラメータ
クエリ、パラメータ、動的ルーティングパラメータ
(1) params は名前のみを使用できます。 query は名前とパスを使用できます。
(2) params でリフレッシュすると失われますが、query でリフレッシュすると失われません。
(3) アドレスバーにパラメータは表示されませんが、クエリは表示されます
(4) params は動的ルーティングで使用できますが、クエリは使用できません
// query 传参
this.$router.push({ path:'/user', query:{ userId:5 } })
// params 传参
this.$router.push({ name:'user', params:{ userId:5 } })
// 动态路由传参
path: 'config/:lawCode/salary/:lawVersionCode',
name: 'basicLawSalary',
this.$router.push(`config/${this.lawCode}/salary/${this.lawVersionCode}`)
// 动态路由获取
this.$route.params.lawCode
ルーティングジャンプ
ナビゲーションルーティング
<ルーターリンク先='/'>
プログラムによるルーティング
router.push() |
レコードを履歴スタックに保存し、「戻る」をクリックして前のレコードに戻ります。 ルーターリンクへのリンクはプッシュと呼ばれます |
router.replace() |
履歴スタックは保存されませんが、現在の履歴は置き換えられます router-link に replace を追加するか、router.push オブジェクトに replace:true を追加して、現在の機能をアクティブにすることができます |
ルーター.go(-3) |
() 内のパラメータは整数で、履歴スタック内で前方または後方に進むステップ数を示します。 -1 は前の履歴に戻り、0 はページを更新し、1 は次の履歴に戻ります |
Vueのルーティングガード
ルーティング ガードは、グローバル ガード、ルーティング専用ガード、コンポーネント ガードに分かれています。
各ガードは 3 つの引数を受け取ります
入ろうとしているところへ 目标路由对象
from 現在のナビゲーションはこれからです离开的路由
次の フック関数。次のルートで何を行うかを確認するためのパラメータを定義します。
グローバルガード
router.beforeEach | グローバルフロントガードは、 入力されたページがログイン必要かどうかの判断に最適です。 |
router.beforeResolve | グローバルパーシングガード すべてのコンポーネント内ガードと非同期ルーティングされたコンポーネントが解決された後、ナビゲーションが確認される前に、解決ガードが呼び出されます。 |
router.afterEach | グローバル ポストフックは 通常、動的なリクエスト ヘッダーを設定するために使用され、ここではnext()が冗長です。 |
クリックして Global Guard の特定のアプリケーションを表示します
ルーティング排他ガード beforeEnter
const router = new VueRouter({
routes: [
{
path: '/foo',
component: Foo,
beforeEnter: (to, from, next) => {
// ...
}
}
]
})
コンポーネント内のガード
beforeRouteEnter | グループコンポーネントに入る前にガードする 注: ここでは vue の this を取得できませんが、 next にコールバックを渡すことでコンポーネント インスタンスにアクセスできます。 次へ ( vm=> { console.log(vm) } ) vm は vue のコンポーネント インスタンスです。 通常、ユーザーが変更を保存せずに突然終了するのを防ぐために使用されます。ナビゲーションはnext(false)でキャンセル可能 |
ルート更新前 | ルート更新の警備員 |
前ルート出発 | コンポーネントから離れるときのガード |
完全なナビゲーション分析プロセス
1. 非アクティブ化されたコンポーネントの beforeRouteLeave コンポーネントを呼び出して、ガードを離れます。
2 グローバル router.beforeEach グローバル pre-guardを呼び出します。
3再利用されたコンポーネントでbeforeRouteUpdate コンポーネント更新ガードを呼び出します。
4ルーティング設定にルーティング排他的ガードを入力する前に
呼び出します。 5 非同期ルーティング コンポーネントを解析します。
6アクティブ化されたコンポーネントでbeforeRouteEnter コンポーネント
を呼び出してガードに入ります。 7 グローバル router.beforeResolve グローバル解決ガードを呼び出します。
8 ナビゲーションが確認されました。9フックの後に
グローバル router.afterEach グローバルを呼び出します。10 DOM 更新をトリガーします。11 beforeRouteEnter ガードで next に渡されたコールバック関数を呼び出すと、作成されたコンポーネント インスタンスがコールバック関数のパラメータとして渡されます。
ルーティング関連の問題
クリックすると、vue routing で同じページにジャンプするエラーの問題が表示されます。
足場レム適応
APIリクエストをカプセル化する
複数の環境変数
Webパックの設定
webpack は、クロスドメイン構成リクエスト、エイリアス、およびパッケージ構成を行うことができます
パッケージ化構成には、パスの変更、運用環境でのsourceMapリソース マッピング ファイルの削除、console.logの印刷とコメントの削除、CDNを使用した最適化の高速化、リソース ファイルの圧縮、画像圧縮、パブリック コードの抽出、およびパッケージ化分析が含まれます。
Vue の 2 つの項目のデータ バインディング
ビュー2
パブリッシャー/サブスクライバー モデルと組み合わせると、object.defineProperty() を使用して各プロパティのセッターがハイジャックされ、ゲッターはデータが変更されたときにサブスクライバーにメッセージをパブリッシュし、対応する監視コールバックをトリガーしてビューをレンダリングします。データとビューの同期を実現します。
具体的な手順
ステップ 1:オブザーバー(observer) は、サブプロパティ オブジェクトのプロパティに加えてsetter と gettersを含むデータ オブジェクトを再帰的に走査する必要があるため、値が割り当てられると setter がトリガーされ、データが変更されます。監視される
ステップ 2:コンパイル(テンプレート パーサー) は、テンプレート命令を解析し、テンプレート内の変数をデータに置き換え、レンダリングされたページ ビューを初期化し、ノードを更新関数にバインドし、サブスクライバーを追加します。
ステップ 3: Watcher (subscriber) はObserver と Compileの間の通信ブリッジです。主に行うべきことは次のとおりです: 1.
自身をインスタンス化するときに属性サブスクライバー ( dep )に自分自身を追加します2. update()メソッド
が必要です3. dep.notice()によって属性変更が通知されると、独自のupdate()メソッドを呼び出して、コンパイル時にバインドされたコールバックをトリガーできます。
ステップ 4: MVVMはデータ バインディングの入り口として使用され、Observer、Compile、Watcherを統合し、Observer を使用して独自のモデル データの変更を監視し、Compile を使用してテンプレート命令を解析およびコンパイルし、最後に Watcher を使用してデータ間のギャップを設定します。データ変更とビュー変更の同期更新を実現するオブザーバーおよびコンパイル通信ブリッジ
ビュー3
es6のプロキシのsetメソッドとgetメソッドを利用してデータハイジャックを実現し、さらにvueのwatcherのupdateメソッドを組み合わせて二重項目データバインディングを実現
v2 に対する v3 の利点
- 配列型のデータ変更を直接監視
- 監視の対象はオブジェクト自体であり、各属性をトラバースする必要がなく、一定のパフォーマンスの向上が見られます。
- オブジェクトのプロパティを直接追加/削除できる
Vue 仮想 dom、diff アルゴリズム
仮想DOMとは
仮想DOMとは、通常のjsオブジェクトを使って実際のDOM構造を記述するもので、このオブジェクトにはタグ名(tag)、属性(attrs)、子要素オブジェクト(children)の3つの属性があり、仮想DOMはvueのrender()で変換されます。関数実際の DOM の場合、appendChild()を通じてページに追加します。
仮想 DOM を使用する理由
実際の DOM を作成するコストは比較的高く、DOM を頻繁に操作するとオーバーヘッドが比較的大きくなり、仮想 DOM を使用するコストは比較的低くなります。
仮想 DOM のパフォーマンスは、必ずしも従来の DOM よりも高いわけではありませんが、命令型プログラミングから関数型プログラミングやデータ駆動型プログラミングへの変換によって生じるパフォーマンスの問題を解決するために、仮想 DOM と Diff アルゴリズムの登場が期待されています。
仮想 DOM の使用は、ユーザーによる dom の操作を軽減するためだけであり、実際には、実際の dom は引き続き操作されます。
仮想 DOM を使用すると、差分アルゴリズムの比較にさらに有益です
Vue2の差分アルゴリズム
- js オブジェクト構造を使用して実際の DOM ツリーを構築し、それをドキュメントに挿入します。
- 状態が変化したら、新しい仮想 DOM を再構築します。
- 次に、新しい仮想 DOM と古い仮想 DOM を比較します。すべての DOM が比較され、記録された差異が構築された実際の DOM ツリーに適用され、ビューが更新されます。
Vue3の差分アルゴリズム
1 は、VNode の生成と同時にマークを付け、これに基づいてコア diff アルゴリズムを実行します。
2 更新に参加しない要素の場合、静的マークとプロンプトは 1 回だけ作成され、レンダリング中に直接再利用されます。
vueのコンポーネント開発
コンポーネント開発の利点
1 コードのサイズと繰り返しを削減する
2 保守が容易で、変更も容易
3 パッケージ化されたコンポーネントは再利用しやすく、使いやすい
4 コンポーネントごとに共同開発された 1 ページで、よりチームワークに沿ったもの
コンポーネントをパッケージ化する方法
1 コンポーネントは、ページレベルのコンポーネントとサブコンポーネントに分かれています。ページレベルのコンポーネントはビューフォルダー内のコンポーネントです
2サブコンポーネントを配置するための新しいコンポーネントフォルダーを作成します。
3 サブコンポーネントも vue ファイルです
4 これらのサブコンポーネントを使用するには、パスに従ってサブコンポーネントをインポートし、コンポーネントに登録する必要があります
5 配置したいページの位置にサブコンポーネントを配置します。キャメルケースを使用することに注意してください
コンポーネントの使用シナリオ
1 先頭入力の検索ボックス
ページ内の 2 つの同じモジュール。たとえば、ヘッダー、ナビゲーションバー、パンくずリストの下部にあるモジュール、スロットを介してデータを変更する
3 カルーセル、トップに戻るボタン、ラダー ナビゲーション、その他の機能のカプセル化
コンポーネントスタイルの浸透
css スタイルの浸透 >>> sass スタイルの浸透/deep/
スロットを使用したコンポーネントとコンポーネント間での値の受け渡し
詳細は以下を参照してください
コンポーネント通信
父から息子へ
1 カスタムプロパティのパス値
親コンポーネントの子コンポーネントタグにプロパティをバインドして、転送する変数をマウントします。子コンポーネントのpropsを通じてデータを受け入れる
小道具
props は配列またはオブジェクトにすることができ、受け入れられるデータは配列を使用して直接受け入れることも、オブジェクト フォームを使用してデータ型、必須値かどうか、およびデフォルト値を決定することもできます。
props:{
name:{
type:string, //数据类型
default:'000',//默认值,只有值是undefined或者不传属性的时候才会生效
required:true, //是否必须传递 }
}
注: 参照データ型のデフォルト値は、使用する前に関数によって返される必要があります。そうしないと、vue のロジックがエラーを報告します。
default: () => { return []/{} }
小道具のプロパティ
1 prop によって形成されるデータは一方向の流れであり、親コンポーネントのデータ変更は子コンポーネントに影響しますが、子コンポーネントは親コンポーネントを変更しません。
2 サブコンポーネントの prop によって渡される値を直接変更することはできません。変更しない場合は、警告が報告されます。
3 prop の検証では、渡されるデータ型、それが必須値であるかデフォルト値であるかを定義します。
4 prop が検証されていない場合、コンポーネントは任意の値を受け入れることができます。名前が同じ場合、prop データが元のデータを置き換えます。
2 パス値を提供します
親コンポーネントは、 provide : { }を使用してデータを定義します
サブコンポーネントはinject: [ ] を使用してデータを受け取ります
注: Provide によって提供される配列は、その子孫コンポーネントのいずれでも使用できます。
3 this.$parent
子コンポーネント内のthis.$parentを通じて 親コンポーネント を検索し、親コンポーネントのすべてのデータとメソッドを取得します。
子传父
1つのカスタムイベント
親コンポーネントの子コンポーネントタグにカスタムイベントをバインドすることで、子コンポーネントから渡されたイベントが受け入れられます。子コンポーネントは、$emit を通じて親コンポーネントでカスタム イベントをトリガーし、パラメーターを送信します。
2 this.$children
親コンポーネント内の this.$childrenを通じて子コンポーネント を検索し、すべての子コンポーネントを含むクラス配列コレクションを取得します。
非親子コンポーネントのパス値
1 main.js でグローバル バスを定義します。バスは Vue のインスタンス化されたオブジェクトです
Vue.prototype.$bus = new Vue()
2 データを渡す必要があるページ呼び出しイベントとデータを渡す
this.$bus.$emit('getData', data:this.data)
3 データを受け入れる必要があるページはイベントを作成してデータを取得します
this.$bus.$on('getData', (data) => { this.msg = data })
4 beforeDestoryでリッスン イベントを閉じる
beforeDestory(){
this.$bus.$off('getData')
}
注: 操作の順序は、最初にデータを受信するページでイベントが作成され、次にデータを渡すページ呼び出しイベントが作成されます。
値の転送ごとにイベントが作成され、大量のメモリが消費されます
スロットスロット
スロットは、匿名スロット、名前付きスロット、およびスコープ付きスロットに分割されます。
匿名スロット
サブコンポーネント内で、 <slot />を設定すると、匿名スロットを使用でき、データはスロットに対応する位置に配置されます。複数の匿名スロットがある場合、各スロットにはデータが描画されます
匿名スロットには実際には名前があり、これは デフォルトであり、通常は書き込まれません。
名前付きスロット
複数のスロットに名前を付けて区別する
命名: v-slot:name は #nameと省略できます。
V2の使用
<div slot=‘left’> </div>
或
<template v-slot:left> </template>
V3の使用
<template v-slot:left> </template>
スコープ付きスロット
カスタム属性を通じてスロットで使用されるデータを準備します。
サブコンポーネント内
<slot name="z" :say1="say1" :say2="say2"></slot>
サブコンポーネントタグ
<template #z="{say1, say2}"> //解构作用域插槽的数据
<div>{
{say1}}</div>
</template>
なぜvueのデータは関数なのか
ルート インスタンスのオブジェクト データはオブジェクトまたは関数 (ルート インスタンスはシングルトン) にすることができ、データの競合は発生しません。
コンポーネントインスタンスのデータは同じ参照データであり、コンポーネントをパブリックコンポーネントとして共有する場合、オブジェクトの場合はエラーとなり、一か所のデータが変更されるとすべてのデータが一括して変更されます。逆に、データが function の場合、各インスタンスのデータはクロージャ内にあるため、個別に影響を受けることはありません。
vue の一般的なコマンド
v-if |
要素の追加や削除を条件で判断するのは不活性で、最初に条件を満たしていないと作成されません。 スイッチングコストが高く、状況が変化する可能性が低い状況に適しています。 |
v-その他 | v-if と一緒に使用されます。その後に v-if または v-else-if を続ける必要があります。そうしないと機能しません。 |
Vショー | 条件に応じて要素の表示・非表示を判断し、 display:noneを 追加・削除することで要素を制御します。 初期レンダリングコストが高く、頻繁な状態切り替えに適しています。 |
v-for | v-for是根据遍历数据来进行渲染,要配合key使用。要注意的是当v-for和v-if同处于一个节点时,v-for的优先级比v-if更高,不能与 v-if 同时使用,除非使用 template 空标签包裹 |
v-on | 用来绑定一个事件或者方法,可以简写为@click |
v-bind | 用来绑定元素的属性,一般用于绑定class值或style样式,可以简写为 : 绑定class的三种方式: 1、对象型 ‘{red:isred}’ 2、三元型 ‘isred?“red”:“blue”’ 3、数组型 ‘[{red:“isred”},{blue:“isblue”}] |
v-model | 使用与表单元素,实现双项数据绑定,本质为自定义事件@input和自定义属性:value的集合 |
v-html | 用于渲染富文本,即带有html的字符串 |
vue的自定义指令
vue允许我们设置自定义指令,自定义指令分为局部自定义指令与与全局自定义指令
局部自定义指令directives,定义在组件内部,只能在当前组件使用
全局自定义指令Vue.directive作用在全局
自定义指令的参数
el | 所绑定的元素,可以直接操作 |
binding |
一个对象,包含以下属性: name: 指令名,不包括 v- 前缀 |
Vnode |
当前节点信息 |
v2的自定义指令钩子函数
bind | 只调用一次,指令第一次绑定到元素时调用。在这里可以进行一次性的初始化设置 |
inserted |
被绑定元素插入父节点时调用 |
update |
所在组件的 VNode 更新时调用,但是可能发生在其子 VNode 更新之前 |
componentUpdated |
指令所在组件的 VNode 及其子 VNode 全部更新后调用 |
unbind |
只调用一次,指令与元素解绑时调用 |
v3的自定义指令钩子函数
created |
创建后调用 |
beforeMount |
自定义指令绑定到 DOM 后调用. 只调用一次 |
mounted |
自定义指令所在DOM, 插入到父 DOM 后调用 |
beforeUpdate |
自定义指令所在 DOM, 更新之前调用 |
updated |
组件VNode 和子VNode 更新后执行 |
beforeUnmount |
销毁前 |
unmounted |
销毁后 |
使用场景
输入框自动聚焦
// 注册一个全局自定义指令 `v-focus`
Vue.directive('focus', {
// 当被绑定的元素插入到 DOM 中时
inserted: function (el) {
// 聚焦元素
el.focus()
}
})
<input v-focus>
相对时间的转换 例:5分钟前
<span v-relativeTime="time"></span>
new Vue({
el: '#app',
data: {
time: 1565753400000
}
})
Vue.directive('relativeTime', {
bind(el, binding) {
// Time.getFormatTime() 方法,自行补充
el.innerHTML = Time.getFormatTime(binding.value)
el.__timeout__ = setInterval(() => {
el.innerHTML = Time.getFormatTime(binding.value)
}, 6000)
},
unbind(el) {
clearInterval(el.innerHTML)
delete el.__timeout__
}
})
传入一个颜色,自动为全局背景色
let app = createApp(App)
// 全局自定义指令
app.directive('color', {
created(el, binding) {
el.style.background = binding.value;
},
updated(el, binding) {
el.style.background = binding.value;
}
})
vue中的修改符
事件修饰符
.stop | 阻止事件冒泡 |
.capture |
触发事件捕获 |
.self |
当事件作用在元素本身时才会触发 |
.once |
只触发一次 |
.prevent |
阻止默认事件 |
·passive |
告诉浏览器你不想阻止事件的默认行为 |
·trim |
自动过滤用户输入的首尾空格 |
v-model的修饰符
.lazy | <input v-model.lazy="msg"> 转变为在change事件再同步 |
.number | 用法同上 自动将用户的输入值转化为数值类型 |
.trim | 用法同上 自动过滤用户输入的首尾空格 |
键盘事件修饰符,支持多个按键
keyup.13 / enter | 点击回车键 |
.delete | 删除或退格键 |
.up .down .left .right | 上下左右按键 |
@keydown.ctrl.13 | 同时按下Ctrl + enter时触发 |
element或子组件的修饰符
对于组件库与子组件来说,都是封装好的事件,书写事件将会成为一个子传父
使用 @click.native ,可以解决这个问题
vue的生命周期
beforeCreate |
实例创建前,目前只有一些实例本身的事件和生命周期函数,无法拿到dom和data数据 |
created |
实例创建后,是最早可以使用data和methods中数据的钩子函数。仍然无法拿到dom |
beforeMount |
在created与beforeMount之间,是用来形成虚拟dom DOM挂载前,但挂载的是之前的虚拟dom |
mounted |
DOM挂载后,在此刻dom渲染完毕,页面和内存的数据已经同步,最早的可以获取DOM结构的位置 |
beforeUptate |
更新前,当data的数据被渲染在DOM上,并且发生改变才会执行这个钩子函数 |
updated |
更新后,在此刻内存和页面都是最新的 |
beforeDestroy |
销毁前,即将销毁data和methods中的数据,但再此时还是可以使用的,可以做一些释放内存的操作,同时也是最后可以获取实例与dom的钩子函数 |
destroyed |
已经销毁完毕 |
activated |
被包含在 keep-alive 中创建的组件才会有这个钩子,组件激活时触发 |
deactivated |
被包含在 keep-alive 中创建的组件才会有这个钩子,组件失活时触发 |
vue中的watch
watch,数据监听,用于监听数据变化,当对应数据变化时触发
应用场景
watch{
str:{
handler(newVal){}, //引用数据类型的新旧值是一致的,所以是只有一个新数据就可
deep:ture, //是否深度监听
immediate:true //是否开启初始监听
}
}
如果不需要开启深度监听与初始监听,可简写为
watch{
str(newVal){}
}
computed,methods,watch的区别
computed是计算属性,对应数据变化,自动计算,需要return返出最终的值,拥有缓存,数据不变时,调用缓存
methods是vue中的事件与方法,需要手动调用才能触发
watch是数据监听,不需要return返回值,数据变化自动监听,可判别变化前后的差异
过滤器filter
过滤器是对 即将显示的数据做进一步的筛选处理,然后显示,过滤器并没有改变原来的数据,只是在原数据的基础上产生新的数据,需要使用return返回最终的值
过滤器分为局部过滤器和全局过滤器,使用方法是在要过滤的数据后添加 |
keep-alive
keep-alive 是 Vue 的内置组件,当它包裹动态组件时,会缓存不活动的组件实例,而不是销毁它们。keep-alive 是一个抽象组件:它自身不会渲染成一个 DOM 元素,也不会出现在父组件链中。
在组件切换过程中 把切换出去的组件保留在内存中,防止重复渲染DOM,减少加载时间及性能消耗,提高用户体验性
被包含在 keep-alive 中创建的组件,会多出两个生命周期的钩子: activated(组件激活时使用) 与 deactivated(组价离开时调用)
如果需要缓存整个项目,直接在app.vue中用keep-alive包裹router-view即可。要缓存部分页面,需要在路由地址配置中,在meta属性中添加一个状态,在app.vue中判断一下包裹的router-view即可
v-for为什么要使用key
key是给每一个vnode的唯一id,也是diff的一种优化策略,可以根据key,更准确, 更快的找到对应的vnode节点,如果不使用key的话,不影响正常的使用,但是会在控制台报警告
$nextTick()的作用
作用
$nextTick()是在下次 DOM 更新循环结束之后执行延迟回调。在修改数据之后立即使用这个方法,获取更新后的 DOM
使用场景
你在Vue生命周期的created()
钩子函数进行的DOM操作一定要放在Vue.nextTick()
的回调函数中,因为在此时还拿不到dom节点
入力ボックスの場合、表示された直後に自動的にフォーカスを取得することは不可能です。vue render()関数が仮想 dom を実際の dom に変換するとき、それは非同期であり、その時点で直接取得できないためです。したがって、this.$nextTick()を使用して、内部にフォーカスを取得するコードを書くと、この関数を実現できます。
vue がデータを変更した後、ページが更新されない
<template>
<div>
<p v-for="(value,key) in item" :key="key">
{
{ value }}
</p>
<button @click="addProperty">动态添加新属性</button>
</div>
</template>
<script>
export default {
data:()=>{
item:{
oldProperty:"旧值"
}
},
methods:{
addProperty(){
this.item.newProperty = "新值" // 为items添加新属性
console.log(this.items) // 输出带有newProperty的items
}
}
};
</script>
質問:上記と同様、オブジェクトに新しい属性を直接追加して値を割り当てると、最新の情報がコンソールに出力されますが、このデータはビューに自動的に更新されません。
理由: Vue2 は、データの二重項目データ バインディングを実現するためにObject.definePropertyを使用します。これにより、すべてのプロパティにset と getが追加されます。この新しいプロパティの追加と値の割り当てという直接操作は、セットが存在しない場合に行われます。バインドされている場合、セットをトリガーできず、2 つのデータ項目のバインドを実現できません。
Vue では、すでに作成されたインスタンスに新しい応答プロパティを動的に追加することはできません
解決
1 Vue.$set()を使用して新しいプロパティを追加します。少数のプロパティを追加する場合に適しています。
this.$set(this.item, "newProperty", "张三");
2 Object.assign()を使用して新しいオブジェクトを作成し、元のオブジェクトと新しい属性を含むオブジェクトをマージします。これは、多数の属性を追加するのに適しています。
this.item = Object.assign({},this.item,{newProperty:'新值'})
3 $forceUpdate は 更新を強制しますが、これはお勧めできません
this.item.newProperty = "新值"
this.$forceUpdate();