View3.js
迷惑な vscode プロンプトボックスを閉じる方法
https://blog.csdn.net/liuyuemozhu/article/details/101056556
ES6 モジュール性と非同期プログラミングの高度な使用法
ES6モジュラー
1. 復習:node.js でモジュール性を実装する方法
node.js は CommonJS のモジュール仕様に従います。で:
- require() メソッドを使用して他のモジュールをインポートする
- モジュールの外部共有メンバーは module.exports オブジェクトを使用します。
モジュール化の利点: 誰もが同じモジュール仕様に従ってコードを作成できるため、通信コストが削減され、さまざまなモジュール間の相互呼び出しが大幅に容易になり、他人と自分自身に利益がもたらされます。
2. フロントエンドモジュール仕様の分類
ES6 モジュラー仕様が誕生する前に、JavaScript コミュニティはすでに AMD、CMD、CommonJS などのモジュラー仕様を試し、提案していました。ただし、コミュニティによって提案されたこれらのモジュラー標準には、依然として特定の相違点と制限があり、ブラウザーとサーバーの普遍的なモジュラー標準ではありません。
AMD と CMD はブラウザ側の Javascript モジュール化に適しています
サーバーサイド Javascript モジュール化のための CommonJS
モジュール仕様が多すぎると、開発者の学習が困難になり、開発コストが増加します。したがって、統一された ES6 モジュラー仕様が誕生しました。
3. ES6 モジュラー仕様とは何ですか?
ES6 モジュラー仕様は、ブラウザー側とサーバー側の両方に共通のモジュラー開発仕様です。この登場により、フロントエンド開発者のモジュール学習コストが大幅に削減され、開発者は AMD、CMD、CommonJS などの追加のモジュール仕様を学習する必要がなくなりました。
ES6 モジュール仕様では次のように定義されています。
- 各 js ファイルは独立したモジュールです
- import キーワードを使用して他のモジュール メンバーをインポートする
- モジュール メンバーを外部と共有するには、export キーワードを使用します
4.node.js で ES6 のモジュール性を体験する
デフォルトでは、node.js は CommonJS モジュラー仕様のみをサポートしています。node.js に基づいた ES6 のモジュラー構文を体験して学習したい場合は、次の 2 つの手順に従って構成できます。
①node.js v14.15.1以降がインストールされていることを確認します。
②package.jsonのルートノードに「type」:「module」ノードを追加します
5. ES6 モジュール性の基本構文
ES6 のモジュール性には主に次の 3 つの用途が含まれます。
①デフォルトエクスポートとデフォルトインポート
② オンデマンド輸出、オンデマンド輸入
③モジュール内のコードを直接インポートして実行する
5.1 デフォルトのエクスポート
デフォルトのエクスポートの構文: デフォルトのデフォルトのエクスポートされたメンバーをエクスポートします。
//定义模块私有成员n1
let n1 = 10
//定义模块私有成员n2(外界访问不到n2,因为他没有被共享出去)
let n2 = 20
function show() {
}
export default {
//使用export default 默认导出语法,向外共享n1 和show 两个创建
n1,
show
}
デフォルトのインポート構文: インポートは「モジュール識別子」から名前を受け取ります
import m1 from './01-默认导出'
console.log(m1)
各モジュールでは、エクスポートのデフォルトを 1 つだけ許可します。それ以外の場合は、エラーが報告されます。
5.2 オンデマンドでのエクスポート
オンデマンドでエクスポートするための構文: オンデマンドでエクスポートされるメンバーのエクスポート
export let s1 = 'aaa'
export let s2 = 'ccc'
export function say() {
}
オンデマンドインポートの構文: import { s1 } from 'モジュール識別子'
//导入模块成员
import {
s1, s2, say } from './03- 按需导出 .js'
console.log(s1)
console.log(s2)
console.log(say)
ここに幕間があります: ウーユのためにドアを開けたのは本当にウーユでした、そしてウーユは家に帰りました。コードはこのコードで、エクスポート時にエラーが報告され続けました。エラー メッセージは次のとおりでした: コード: 'ERR_MODULE_NOT_FOUND'、その後インターネットで解決策を探し続けましたが、うまくいきませんでした。そして、私は彼を無視して、彼が元気なときにそれをスキップしようとしました。誰かがそれを見たら、私の疑問が解決されることを願っています。
オンデマンドエクスポート、オンデマンドインポートに関する注意事項
① 各モジュールで複数のオンデマンドエクスポートが利用可能
② オンデマンドでインポートされるメンバーの名前は、オンデマンドでエクスポートされるメンバーの名前と一致している必要があります。
③ オンデマンドでインポートする場合、as キーワードを使用して名前を変更できます。
④オンデマンドインポートはデフォルトインポートと併用可能
5.3 モジュール内のコードを直接インポートして実行する
モジュール内のコードを単純に実行するだけの場合は、モジュール内の外部共有メンバーを取得する必要はありません。この時点で、モジュール コードを直接インポートして実行できます。サンプル コードは次のとおりです。
//在当前模块中执行一个for循环操作
for (let i = 0; i < 3 ; i++) {
console.log(i)
}
----------分割线-------------
//直接导入并执行模块代码,不需要得到模块向外共享的成员
//注意要加后缀名
import './05-直接导入并执行模块中的代码.js'
約束
1.コールバック地獄
コールバック関数の複数の層のネストにより、コールバック地獄が作成されます。サンプルコードは次のとおりです。
setTimeout(() => {
console.log('延时 1 秒后输出')
setTimeout(() => {
console.log('延时 2 秒后输出')
setTimeout(() => {
console.log('延时 3 秒后输出')
}, 3000)
}, 2000)
}, 1000)
コールバック地獄のデメリット:
- コードの結合が強すぎて全身に影響が出てメンテナンスが困難になる
- 大量の冗長コードが相互にネストされているため、コードが読みにくくなっています。
1.1 コールバック地獄の解決方法
コールバック地獄の問題を解決するために、ES6 (ECMAScript 2015) では Promise の概念が追加されました。
1.2 Promiseの基本概念
①Promiseはコンストラクタです
- Promise const p = new Promise() のインスタンスを作成できます。
- new によって生成される Promise インスタンス オブジェクトは、非同期操作を表します。
② Promise.prototype には .then() メソッドが含まれています
- 新しい Promise() コンストラクターがインスタンス オブジェクトを取得するたびに、
- .then() メソッドには、p.then() などのプロトタイプ チェーンを通じてアクセスできます。
③ .then() メソッドは、成功および失敗のコールバック関数を事前に指定するために使用されます。
- p.then (成功コールバック関数、失敗コールバック関数)
- p.then(結果 => { }、エラー => { })
- .then() メソッドを呼び出す場合、成功コールバック関数は必須ですが、失敗コールバック関数はオプションです。
2. コールバック関数に基づいてファイルの内容を順次読み取ります。
//读取文件1.txt
fs.readFiles('./files/1.txt', 'utf-8', (err1, r1) => {
if (err1) return console.log(err1.message) //读取文件失败
console.log(r1)
//读取文件1.txt
fs.readFiles('./files/2.txt', 'utf-8', (err2, r2) => {
if (err2) return console.log(err2.message) //读取文件失败
console.log(r2)
fs.readFiles('./files/3.txt', 'utf-8', (err3, r3) => {
if (err3) return console.log(err3.message) //读取文件失败
console.log(r3)
})
})
})
3. then-fs に基づいてファイルの内容を読み取ります
node.js が公式に提供する fs モジュールはコールバック関数によるファイルの読み取りのみをサポートしているため、Promise 呼び出しメソッドはサポートしていません。したがって、最初に次のコマンドを実行して、Promise に基づいたファイルの内容の読み取りをサポートする then-fs サードパーティ パッケージをインストールする必要があります。
npm install then-fs
3.1 then-fs の基本的な使用法
then-fs が提供する readFile() メソッドを呼び出すと、ファイルの内容を非同期で読み取ることができ、戻り値は Promise のインスタンス オブジェクトになります。したがって、.then() メソッドを呼び出して、各 Promise 非同期操作の成功および失敗後にコールバック関数を指定できます。サンプルコードは次のとおりです。
import thenFs from 'then-fs'
thenFs.readFile('./files/1.txt', 'utf-8').then((r1) => {
console.log(r1) })
thenFs.readFile('./files/2.txt', 'utf-8').then((r2) => {
console.log(r2) })
thenFs.readFile('./files/3.txt', 'utf-8').then((r3) => {
console.log(r3) })
注: 上記のコードはファイルの読み取り順序を保証できないため、さらに改善する必要があります。
3.2 .then() メソッドの特徴
新しい Promise インスタンス オブジェクトが前の .then() メソッドで返された場合、処理は次の .then() まで続行できます。.then() メソッドのチェーン呼び出しにより、コールバック地獄の問題は解決されます。
3.3 Promiseに基づいてファイルの内容を順次読み込む
Promise はコールバック地獄の問題を解決するために連鎖呼び出しをサポートしています。サンプルコードは次のとおりです。
import thenFs from 'then-fs'
// 返回值是Promise的实例对象
thenFs.readFile('./files/1.txt', 'utf-8')
.then((r1) => {
//2.通过.then为第一个Promise实例指定成功之后的回调函数
console.log(r1)
return thenFs.readFile('./files/2.txt', 'utf-8') //3.在第一个.then中返回一个新的Promise实例对象
})
.then((r2) => {
//4.继续调用.then,为上一个.then 的返回值(新的 Promise实例)指定成功之后的回调函数
console.log(r2)
return thenFs.readFile('./files/3.txt', 'utf-8') //5.在第二个 .then中再返回一个新的 Promise实例对象
})
.then((r3) => {
//6.继续调用.then,为上一个.then的返回值(新的Promise实例)指定成功之后的回调函数
console.log(r3)
})
3.4 .catch によるエラーのキャッチ
Promise のチェーン操作でエラーが発生した場合は、Promise.prototype.catch メソッドを使用してエラーをキャプチャして処理できます。
.catch((err) => {
console.log(err.message)
})
前のエラーによって後続の .then が正常に実行されなくなることを望まない場合は、事前に .catch を呼び出すことができます。サンプル コードは次のとおりです。
import thenFs from 'then-fs'
// 返回值是Promise的实例对象
thenFs.readFile('./files/11.txt', 'utf-8')
.catch((err) => {
console.log(err.message)
})
.then((r1) => {
//2.通过.then为第一个Promise实例指定成功之后的回调函数
console.log(r1)
return thenFs.readFile('./files/2.txt', 'utf-8') //3.在第一个.then中返回一个新的Promise实例对象
})
.then((r2) => {
//4.继续调用.then,为上一个.then 的返回值(新的 Promise实例)指定成功之后的回调函数
console.log(r2)
return thenFs.readFile('./files/3.txt', 'utf-8') //5.在第二个 .then中再返回一个新的 Promise实例对象
})
.then((r3) => {
//6.继续调用.then,为上一个.then的返回值(新的Promise实例)指定成功之后的回调函数
console.log(r3)
})
.catch((err) => {
console.log(err.message)
})
3.5 Promise.all() 方法
Promise.all() メソッドは、並列 Promise 非同期操作を開始し、すべての非同期操作が完了するまで待機してから、次の .then 操作を実行します (待機メカニズム)。サンプルコードは次のとおりです。
import thenFs from 'then-fs'
const promiseArr = [
thenFs.readFile('./files/1.txt', 'utf-8'),
thenFs.readFile('./files/2.txt', 'utf-8'),
thenFs.readFile('./files/3.txt', 'utf-8')
]
Promise.all(promiseArr).then(result => {
console.log(result)
})
3.6 Promise.race() 方法
Promise.race() メソッドは、並列 Promise 非同期操作を開始します。非同期操作が完了すると、次の .then 操作 (レース メカニズム) がすぐに実行されます。サンプルコードは次のとおりです。
import thenFs from 'then-fs'
const promiseArr = [
thenFs.readFile('./files/1.txt', 'utf-8'),
thenFs.readFile('./files/2.txt', 'utf-8'),
thenFs.readFile('./files/3.txt', 'utf-8')
]
Promise.race(promiseArr)
.then(result => {
console.log(result) //111
})
.catch(err => {
console.log(err.message)
})
4. Promiseに基づくファイル読み込みのカプセル化方法
メソッドのカプセル化要件:
① メソッド名は getFile として定義する必要があります。
② メソッドは、読み込むファイルのパスを示す仮パラメータ fpath を受け取ります。
③メソッドの戻り値がPromiseインスタンスオブジェクトである
4.1 getFileメソッドの基本定義
// 1.方法的名称为getFile
// 2.方法接收一个形参 fpath,表示要读取的文件的路径
function getFile(fpath){
//3.方法的返回值为Promise的实例对象
return new Promise()
}
注: 5 行目の new Promise() は、正式な非同期操作のみを作成します。
4.2 特定の非同期操作の作成
特定の非同期操作を作成する場合は、新しい Promise() コンストラクター中に関数関数を渡し、その関数関数内で特定の非同期操作を定義する必要があります。サンプルコードは次のとおりです。
import fs from 'fs'
// 1.方法的名称为getFile
// 2.方法接收一个形参 fpath,表示要读取的文件的路径
function getFile(fpath){
//3.方法的返回值为Promise的实例对象
return new Promise(function () {
fs.readFile(fpath,'utf-8',(err,dataStr) => {
})
})
}
4.3 .then の 2 つの実際のパラメータを取得する
.then() で指定した成功コールバック関数と失敗コールバック関数は、関数の仮引数で受け取ることができます。サンプルコードは次のとおりです。
import fs from 'fs'
// 1.方法的名称为getFile
// 2.方法接收一个形参 fpath,表示要读取的文件的路径
function getFile(fpath) {
//3.方法的返回值为Promise的实例对象
// resolve形参是:调用getFiles()方法时,通过 .then指定的成功的"回调函数
// reject形参是:调用 getFiles()方法时,通过.then指定的"失败的""回调函数
return new Promise(function(resolve,reject) {
fs.readFile(fpath, 'utf-8', (err, dataStr) => {})
})
}
//getFile方法的调用过程
getFile('./files/1.txt').then(成功的回调函数,失败的回调函数)
4.4 コール解決および拒否コールバック関数
Promise の非同期操作の結果は、解決または拒否コールバック関数を呼び出すことで処理できます。サンプルコードは次のとおりです。
import fs from 'fs'
// 1.方法的名称为getFile
// 2.方法接收一个形参 fpath,表示要读取的文件的路径
function getFile(fpath) {
//3.方法的返回值为Promise的实例对象
// resolve形参是:调用getFiles()方法时,通过 .then指定的成功的"回调函数
// reject形参是:调用 getFiles()方法时,通过.then指定的"失败的""回调函数
return new Promise(function(resolve, reject) {
fs.readFile(fpath, 'utf-8', (err, dataStr) => {
if (err) return reject(err) //如果读取失败,则调用"失败的回调函数"
resolve(dataStr) //如果读取成功,则调用"成功的回调函数"
})
})
}
//getFile方法的调用过程
getFile('./files/1.txt').then((r1) => {
console.log(r1) }, (err) => {
console.log(err.message) })
getFile('./files/11.txt').then((r1) => {
console.log(r1) }).catch(err => console.log(err.message))
非同期/待機
1. async/awaitとは何ですか
async/await は、Promise の非同期操作を簡素化するために ES8 (ECMAScript 2017) で導入された新しい構文です。async/await が登場する前は、開発者は連鎖した .then() を介して Promise の非同期操作を処理することしかできませんでした。サンプルコードは次のとおりです。
import thenFs from 'then-fs'
// 返回值是Promise的实例对象
thenFs.readFile('./files/11.txt', 'utf-8')
.then((r1) => {
//2.通过.then为第一个Promise实例指定成功之后的回调函数
console.log(r1)
return thenFs.readFile('./files/2.txt', 'utf-8') //3.在第一个.then中返回一个新的Promise实例对象
})
.then((r2) => {
//4.继续调用.then,为上一个.then 的返回值(新的 Promise实例)指定成功之后的回调函数
console.log(r2)
return thenFs.readFile('./files/3.txt', 'utf-8') //5.在第二个 .then中再返回一个新的 Promise实例对象
})
.then((r3) => {
//6.继续调用.then,为上一个.then的返回值(新的Promise实例)指定成功之后的回调函数
console.log(r3)
})
.then 連鎖呼び出しの利点:
コールバック地獄の問題を修正
.then 連鎖呼び出しの欠点:
コードの冗長性、可読性の低さ、理解の困難さ
2. async/awaitの基本的な使い方
async/await を使用して Promise の非同期操作を簡素化するサンプル コードは次のとおりです。
import thenFs from 'then-fs'
async function getAllFile() {
const r1 = await thenFs.readFile('./files/1.txt', 'utf-8')
console.log(r1)
const r2 = await thenFs.readFile('./files/2.txt', 'utf-8')
console.log(r2)
const r3 = await thenFs.readFile('./files/3.txt', 'utf-8')
console.log(r3)
}
getAllFile()
3. async/await使用時の注意点
① 関数内で await を使用する場合、関数を async に変更する必要があります
② async メソッドでは、最初の await より前のコードは同期実行され、await 以降のコードは非同期に実行されます。
console.log('A')
async function getAllFile(){
console.log('B')
const r1 = await thenFs.readFile('./files/1.txt', 'utf-8')
const r2 = await thenFs.readFile('./files/2.txt', 'utf-8')
const r3 = await thenFs.readFile('./files/3.txt', 'utf-8')
console.log(r1,r2,r3)
console.log('D')
}
getAllFile()
console.log('c')
//执行顺序为
//a
//b
//c
//111 222 333
//d
イベントループ
1.JavaScript はシングルスレッド言語です
JavaScript はシングルスレッドのプログラミング言語です。言い換えれば、一度に実行できることは 1 つだけです。
タスクキューのシングルスレッド実行に関する問題:
前のタスクに非常に時間がかかる場合、後続のタスクは待機する必要があり、プログラムがハングする原因になります。
2. 同期タスクと非同期タスク
時間のかかるタスクによってプログラムがフリーズするのを防ぐために、JavaScript では実行されるタスクを 2 つのカテゴリに分類します。
①同期タスク(同期)
- 時間のかからないタスクとも呼ばれ、メインスレッドで実行するためにキューに入れられるタスクを指します。
- 次のタスクは、前のタスクが実行された後にのみ実行できます。
②非同期タスク(非同期)
- 時間のかかるタスクとも呼ばれる非同期タスクは、JavaScript によって実行のためにホスト環境に委任されます。
- 非同期タスクが完了すると、JavaScript メインスレッドに、非同期タスクのコールバック関数 EventLoop を実行するように通知されます。
3. 同期タスクと非同期タスクの実行処理
① 同期タスクは JavaScript メインスレッドによって順次実行されます。
② 非同期タスクはホスト環境に委任されて実行されます。
③ 完了した非同期タスクに対応するコールバック関数がタスクキューに追加され、実行を待ちます。
④ JavaScript メインスレッドの実行スタックがクリアされた後、タスクキュー内のコールバック関数が順次読み込まれて実行されます。
⑤ JavaScript メインスレッドは上記のステップ 4 の EventLoop を繰り返し続けます。
4. EventLoopの基本概念
JavaScript メイン スレッドは、非同期タスクのコールバック関数を「タスク キュー」から読み取り、それらを実行スタックに置き、順次実行します。このプロセスは周期的であるため、動作メカニズム全体はイベントループとも呼ばれます。
5. EventLoopと組み合わせて出力シーケンスを分析する
import thenFs from "then-fs"
console.log('a')
thenFs.readFile('./files/1.txt', 'utf-8').then(dataStr => {
console.log('b')
})
setTimeout(() => {
console.log('c')
}, 0)
console.log('d')
// a
// d
// c 因为延时为0,所以比b读取文件更快,所以先打印c后打印b
// b
正しい出力: ADCB。このうち、A と D は同期タスクに属します。C と B はコードの順序に従って順次実行され、非同期タスクです。これらのコールバック関数はタスク キューに追加され、メイン スレッドがアイドル状態のときに実行を待機します。
マクロタスクとマイクロタスク
1. マクロタスクとマイクロタスクとは何ですか?
JavaScript では、非同期タスクをさらに 2 つのカテゴリに分類します。
①マクロタスク(macrotask)
非同期 Ajax リクエスト、
setTimeout、setInterval、
ファイル操作
その他のマクロタスク
②マイクロタスク
約束して、そして、和を捕まえて、最後に
process.nextTick
その他のマイクロタスク マクロタスクとマイクロタスク
2. マクロタスクとマイクロタスクの実行順序
各マクロタスクの実行後、実行するマイクロタスクがあるかどうかがチェックされ、実行されるマイクロタスクがある場合は、すべてのマイクロタスクが実行されてから次のマクロタスクが続行されます。マクロタスクとマイクロタスク
3. 銀行に用事に行くシーン
① シャオユンとシャオテンは用事のため銀行へ行きました。まずは番号札を取ってから列に並びます
マクロタスクキュー
② 現在の銀行支店には窓口係が 1 人しかいないと仮定すると、Xiaoyun が預金業務を行っているとき、Xiaoteng は待つことしかできません。
シングルスレッド、マクロタスクは順番に実行されます
③シャオユンが預金業務を終えた後、窓口係は彼に他の業務を担当したいかどうか尋ねました。
現在のマクロタスクが実行された後、マイクロタスクがあるかどうかを確認します
④ シャオユンは窓口係にこう言いました。金融商品を購入し、クレジット カードを申し込み、最後に午年の記念コインを交換したいですか?
マイクロタスクは実行され、後続のマクロタスクは延期されます
⑤ シャオユンがカウンターを出た後、窓口係はシャオテンの事務を処理し始めた
すべてのマイクロタスクが実行された後、次のマクロタスクとマイクロタスクの実行が開始されます。
4. 次のコード出力のシーケンスを分析します。
setTimeout(function() {
console.log('1')
})
new Promise(function(resolve) {
console.log('2')
resolve()
}).then(function() {
console.log('3')
})
console.log('4')
正しい出力シーケンスは次のとおりです: 2431
分析します:
① 最初にすべての同期タスクを実行します
コードの 6 行目と 12 行目を実行します
②マイクロタスクを再度実行する
コードの9行目を実行
③ 次のマクロタスクを実行する
コード2行目のマクロタスクとマイクロタスクを実行します。
5. 典型的な面接の質問
次のコード出力のシーケンスを分析してください。
console.log('1')
setTimeout(function() {
console.log('2')
new Promise(function(resolve) {
console.log('3')
resolve()
}).then(function() {
console.log('4')
})
})
new Promise(function(resolve) {
console.log('5')
resolve()
}).then(function() {
console.log('6')
})
setTimeout(() => {
console.log('7')
new Promise(function(resolve) {
console.log('8')
}).then(function() {
console.log('9')
})
})
正しい出力シーケンスは次のとおりです: 156234789
APIインターフェースの場合
フロントエンドエンジニアリングとWebpack
フロントエンドエンジニアリング
1. 初心者から見たフロントエンド開発と実際のフロントエンド開発
初心者から見たフロントエンド開発:
- HTML+CSS+JavaScriptが書けてフロントエンド開発ができる
- ページのスタイルを美しくする必要がある場合は、ブートストラップをドラッグするだけです。
- DOM を操作するか、Ajax リクエストを開始する必要がある場合は、jQuery をドラッグします。
- テンプレート構造をレンダリングする必要がある場合は、art-template などのテンプレート エンジンを使用します。
実際のフロントエンド開発:
- モジュール化(jsのモジュール化、cssのモジュール化、その他リソースのモジュール化)
- コンポーネント化 (既存の UI 構造、スタイル、動作を再利用)
- 標準化(ディレクトリ構造の分割、コーディングの標準化、インターフェースの標準化、ドキュメントの標準化、Gitブランチ管理)
- 自動化 (自動ビルド、自動デプロイメント、自動テスト)
2. フロントエンドエンジニアリングとは何ですか?
フロントエンドエンジニアリングとは、エンタープライズレベルのフロントエンドプロジェクト開発において、フロントエンド開発に必要なツール、技術、プロセス、経験などを標準化・標準化することを指します。細部に至る最終的な実装は、フロントエンドの「4つのモダナイゼーション」(モジュール化、コンポーネント化、標準化、自動化)を実現することだ。
3. フロントエンドエンジニアリングのメリット
フロントエンド エンジニアリングの利点は、主に次の 2 つの側面に反映されます。
①フロントエンドエンジニアリングにより、フロントエンド開発を「自己完結型システム」として構築し、フロントエンドプロジェクトの作成から展開までを網羅
② フロントエンドの開発効率を最大化し、技術選定、フロントエンドとフロントエンドの共同デバッグなどに伴う調整コストやコミュニケーションコストを削減します。 フロントエンドエンジニアリング
4. フロントエンドエンジニアリングソリューション
初期のフロントエンド エンジニアリング ソリューション:
- grunt( https://www.gruntjs.net/ )
- ガルプ( https://www.gulpjs.com.cn/ )
現在主流のフロントエンド エンジニアリング ソリューション:
- webpack( https://www.webpackjs.com/ )
- 小包( https://zh.parceljs.org/ )
Webpackの基本的な使い方
1.Webpackとは
コンセプト: webpack は、フロントエンド プロジェクト エンジニアリングに特化したソリューションです。
主な機能: フレンドリーなフロントエンドのモジュラー開発サポートに加え、コードの圧縮と難読化、ブラウザー側の JavaScript 互換性の処理、パフォーマンスの最適化などの強力な機能を提供します。
利点: プログラマーは特定の機能の実装に集中できるため、フロントエンドの開発効率とプロジェクトの保守性が向上します。
注: 現在のエンタープライズ レベルのフロントエンド プロジェクト開発では、プロジェクトの大部分が Webpack に基づいてパッケージ化され、構築されています。
2. 1 行おきに色が変わる項目のリストを作成します。
① プロジェクト用に新しい空のディレクトリを作成し、npm init –y コマンドを実行してパッケージ管理構成ファイル package.json を初期化します。
② srcソースコードディレクトリを新規作成
③ src ->index.htmlホームページとsrc ->index.jsスクリプトファイルを新規作成します。
④ ホームページの基本構造を初期化する
⑤ npm install jquery –S コマンドを実行して jQuery をインストールします。
⑥ ES6 モジュール化を通じて jQuery をインポートし、リストのインターレース色変更効果のための Webpack の基本的な使用を実現します。
3. プロジェクトに Webpack をインストールします
ターミナルで次のコマンドを実行して、webpack に関連する 2 つのパッケージをインストールします。
npm install [email protected] [email protected] -D
4. プロジェクトで設定する
webpack ① プロジェクトのルート ディレクトリに、webpack.config.js という名前の webpack 構成ファイルを作成し、次の基本構成を初期化します。
module.exports = {
mode: 'development'
//mode 用来指定构建模式,可选值有development和production
}
② package.json の scripts ノードの下に、次のように dev スクリプトを追加します。
"scripts": {
"dev": "webpack" //script 节点下的脚本,可以通过npm run 执行,例如npm run dev
}
③ ターミナルで npm run dev コマンドを実行して webpack を起動し、プロジェクトをパッケージ化してビルドします。
4.1 モードのオプションの値
モード ノードには次の 2 つのオプションの値があります。
①開発
- 開発環境
- コード圧縮とパフォーマンスの最適化は、パッケージ化によって生成されたファイルに対しては実行されません。
- パッケージング速度が速く、開発段階での使用に適しています。
②生産
- 本番環境
- コード圧縮とパフォーマンスの最適化は、パッケージ化によって生成されたファイルに対して実行されます。
- パッケージ化速度は非常に遅いため、プロジェクトのリリース段階での使用にのみ適しています。
4.2 webpack.config.js ファイルの役割
webpack.config.js は webpack の設定ファイルです。webpack が実際にパッケージ化とビルドを開始する前に、まずこの構成ファイルを読み取り、指定された構成に基づいてプロジェクトをパッケージ化します。
注: webpack は、node.js に基づいて開発されたパッケージ化ツールであるため、その構成ファイルは、webpack のパーソナライズされた構成のための、node.js 関連の構文とモジュールの使用をサポートしています。
4.3 Webpack のデフォルトの規則
Webpack には次のデフォルトの規則があります。
① デフォルトのパッケージングエントリファイルは src ->index.js です。
② デフォルトの出力ファイルパスは dist -> main.js です。
注: webpack.config.js でデフォルトのパッケージ化規則を変更できます。
4.4 カスタマイズされた梱包の入り口と出口
webpack.config.js 構成ファイルで、エントリ ノードを介してパッケージング エントリを指定します。出力ノードを通じてパッケージ化されたアウトレットを指定します。サンプルコードは次のとおりです。
const path = require('path')
module.exports = {
mode: 'development',
//打包入口文件的路径
entry: path.join(__dirname, './src/index.js'),
output: {
//输出文件的存放路径
path: path.join(__dirname, './dist'),
// 输出文件的名称
filename: 'bundle.js'
}
}
Webpack のプラグイン
1. Webpackプラグインの役割
サードパーティのプラグインをインストールして構成すると、Webpack の機能が拡張され、Webpack がさらに使いやすくなります。最も一般的に使用される Webpack プラグインは次のとおりです。
① webpack-dev-server
- node.jsステージで使用されるnodemonツールに似ています
- ソース コードが変更されるたびに、webpack はプロジェクトを自動的にパッケージ化してビルドします。
②html-webpack-プラグイン
- Webpack の HTML プラグイン (テンプレート エンジン プラグインに似ています)
- このプラグインを通じて、index.html ページのコンテンツをカスタマイズできます。
2.webpack-dev-server
webpack-dev-server を使用すると、webpack でプロジェクトのソース コードの変更を監視し、自動的にパッケージ化してビルドできます。
2.1 webpack-dev-server をインストールする
次のコマンドを実行して、このプラグインをプロジェクトにインストールします。
npm install [email protected] -D
2.2 webpack-dev-server の構成
① package.json -> scriptsのdevコマンドを以下のように修正します。
"scripts": {
"dev": "webpack serve"
}
② npm run dev コマンドを再度実行して、プロジェクトを再パッケージ化します。
③ ブラウザで http://localhost:8080 アドレスにアクセスして、自動パッケージ化の効果を確認します 注: webpack-dev-server は、webpack でリアルタイム パッケージング http サーバー プラグインを開始します
2.3 パッケージ化によって生成されたファイルはどこに行きますか?
① webpack-dev-server を設定しない場合、webpack パッケージ化によって生成されたファイルは実際の物理ディスクに保存されます。
- 開発者が webpack.config.js で指定した構成に厳密に準拠します。
- 出力ノードで指定されたパスに従って格納します
② webpack-dev-server を設定すると、パッケージ化によって生成されたファイルがメモリに保存されます。
- 出力ノードによって指定されたパスに従って、実際の物理ディスクには保存されなくなります。
- メモリが物理ディスクよりもはるかに高速であるため、リアルタイムのパック出力のパフォーマンスが向上しました。
2.4 メモリ内に生成されたファイルにアクセスするにはどうすればよいですか?
webpack-dev-server によってメモリに生成されたファイルは、デフォルトでプロジェクトのルート ディレクトリに配置され、仮想化され非表示になります。
-
/ を直接使用してプロジェクトのルート ディレクトリを表し、その後にアクセスするファイルの名前を指定すると、メモリ内のファイルにアクセスできます。
-
たとえば、/bundle.js は、webpack-dev-server によってメモリ内に生成された Bundle.js ファイルにアクセスすることを意味します。
-
<script src="/bundle.js"></script>
3.html-webpack-プラグイン
これは webpack の HTML プラグインであり、このプラグインを通じてindex.html ページのコンテンツをカスタマイズできます。要件: html-webpack-plugin プラグインを使用して、src ディレクトリにあるindex.html ホームページをプロジェクトのルート ディレクトリにコピーします。
3.1 html-webpack-plugin をインストールする
次のコマンドを実行して、このプラグインをプロジェクトにインストールします。
npm install [email protected] -D
3.2 html-webpack-plugin の設定
webpack.config.js を追加する
// 1.导入插件,得到构造函数
const HtmlPlugin = require('html-webpack-plugin')
// 2. 创建插件的实例对象
const HtmlPlugin = new HtmlPlugin({
template: './src/index.html',
filename: './index.html'
})
module.exports = {
mode: 'development',
// 3.挂载插件的实例对象
Plugin: [HtmlPlugin]
}
const path = require('path')
// 1.导入插件,得到构造函数
const HtmlPlugin = require('html-webpack-plugin')
// 2. 创建插件的实例对象
const HtmlPlugin = new HtmlPlugin({
template: './src/index.html',
filename: './index.html',
})
module.exports = {
mode: 'development',
//打包入口文件的路径
entry: path.join(__dirname, './src/index.js'),
output: {
//输出文件的存放路径
path: path.join(__dirname, './dist'),
// 输出文件的名称
filename: 'bundle.js',
},
// 挂载插件的实例对象
plugins: [htmlPlugin]
}
3.3 html-webpack-plugin に関する疑問を解決する
① HTMLプラグインを介してプロジェクトのルートディレクトリにコピーされたindex.htmlページもメモリ上に配置されます。
② HTML プラグインは、生成されたindex.html ページの下部に、パッケージ化された Bundle.js ファイルを自動的に挿入します。
4. devServer ノード
webpack.config.js 構成ファイルでは、devServer ノードを介してさらに webpack-dev-server プラグインを構成できます。サンプル コードは次のとおりです。
devServer: {
open: true,//初次打包完成后,自动打开浏览器
host: '12.0.0.1',//实时打包所使用的主机地址
port: 80 //实时打包所使用的端口号
}
注: webpack.config.js 構成ファイルまたは package.json 構成ファイルを変更する場合は、リアルタイム パッケージング サーバーを再起動する必要があります。そうしないと、最新の構成ファイルが有効になりません。
webpack.config.js
const path = require('path')
// 1.导入插件,得到构造函数
const HtmlPlugin = require('html-webpack-plugin')
// 2. 创建插件的实例对象
const htmlPlugin = new HtmlPlugin({
template: './src/index.html',
filename: './index.html',
})
module.exports = {
mode: 'development',
//打包入口文件的路径
entry: path.join(__dirname, './src/index.js'),
output: {
//输出文件的存放路径
path: path.join(__dirname, './dist'),
// 输出文件的名称
filename: 'bundle.js',
},
// 挂载插件的实例对象
plugins: [htmlPlugin],
devServer: {
open: true,
host: '127.0.0.1',
port: 80
}
}
Webpack のローダー
1.ローダーの概要
実際の開発プロセスでは、webpack はデフォルトで .js 接尾辞で終わるモジュールのみをパッケージ化して処理できます。.js 以外のサフィックス名を持つ他のモジュールは、デフォルトでは webpack で処理できません。通常どおりパッケージ化するにはローダー ローダーを呼び出す必要があります。そうしないと、エラーが報告されます。
ローダーの役割は、Webpack による特定のファイル モジュールのパッケージ化と処理を支援することです。例えば:
-
css-loader は .css 関連ファイルをパッケージ化して処理できます
-
less-loader は .less 関連ファイルをパッケージ化して処理できます
-
babel-loader は、webpack では処理できない高度な JS 構文をパッケージ化して処理できます。
2.ローダー呼び出し処理
3. CSS ファイルをパッケージ化して処理する
① npm i [email protected] [email protected] -D コマンドを実行し、css ファイルを処理するローダーをインストールします。
② webpack.config.js の module -> rules 配列に、次のようにローダー ルールを追加します。
module: {
//所有第三方文件配置模块的匹配规则
rules: [//文件后缀的匹配规则
{
test: /\.css/, use: ['style-loager', 'css-loader'] }//\代表转译的意思,把这个点转译成一个真正的引号,以css结尾的文件,都用ues数组调用的loader
]
}
このうち、test は一致するファイルの種類を表し、use は呼び出される対応するローダーを表します。
知らせ:
-
use 配列で指定されたローダーの順序は固定されています
-
複数のローダーの呼び出し順序は次のとおりです。Webpack 内のローダーを後ろから前に呼び出します。
4. パッケージ化して処理するファイルの数を減らす
① npm [email protected]@3.12.2 -Dコマンドを実行します。
② webpack.config.js の module -> rules 配列に、次のようにローダー ルールを追加します。
module: {//所有第三方文件配置模块的匹配规则
rules: [//文件后缀的匹配规则
{ test: /\.less$/, use: ['style-loader', 'css-loader', 'less-loader'] },
]
}
5. URLパスに関連するファイルをスタイルシートにパッケージ化して処理する
① npm i [email protected] [email protected] -D コマンドを実行します。
② webpack.config.js の module -> rules 配列に、次のようにローダー ルールを追加します。
module: {
//所有第三方文件配置模块的匹配规则
rules: [//文件后缀的匹配规则
{
test:/\/.jpg|png|gif$/,ues:'url-loader?limit=22229'},
]
}
その中で、ローダーのパラメータ項目は次のとおりです。
-
limit は画像のサイズを指定するために使用されます。単位はバイト (byte) です。
-
サイズが制限以下の画像のみが、base64 形式の画像に変換されます。
関連資料
インデックスなし
html,body,ul{
margin: 0;
padding: 0;
li{
line-height: 35px;
padding: 10px;
font-size: 12px;
}
}
#box {
width: 380px;
height: 114px;
background-color: red;
background: url('../image/1BC1D6FF35C9D9FE28A5C4FEB17F55A2.png');
}
インデックス.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<!-- index.js存在兼容性问题 -->
<!-- <script src="./index.js"></script> -->
<!-- <script src="../dist/bundle.js"></script> -->
<!-- <script src="/bundle.js"></script> -->
</head>
<body>
<ul>
<li>这是第1个li</li>
<li>这是第2个li</li>
<li>这是第3个li</li>
<li>这是第4个li</li>
<li>这是第5个li</li>
<li>这是第6个li</li>
<li>这是第7个li</li>
<li>这是第8个li</li>
<li>这是第9个li</li>
</ul>
<div id='box'></div>
</body>
</html>
5.1 ローダの別の設定方法
パラメーター項目を含むローダーは、オブジェクトを通じて構成することもできます。
module: {
//所有第三方文件配置模块的匹配规则
rules: [//文件后缀的匹配规则
{
test:/\/.jpg|png|gif$/,ues:
loader:'url-loader',//通过loader属性指定调用的loader
options:{
//通过options属性指定参数项
limit:66300
}
},
]
}
const path = require('path')
// 1.导入插件,得到构造函数
const HtmlPlugin = require('html-webpack-plugin')
// 2. 创建插件的实例对象
const htmlPlugin = new HtmlPlugin({
template: './src/index.html',
filename: './index.html',
})
module.exports = {
mode: 'development',
//打包入口文件的路径
entry: path.join(__dirname, './src/index.js'),
output: {
//输出文件的存放路径
path: path.join(__dirname, './dist'),
// 输出文件的名称
filename: 'bundle.js',
},
// 挂载插件的实例对象
plugins: [htmlPlugin],
devServer: {
open: true,
host: '127.0.0.1',
port: 80
},
module: {
rules: [
{
test: /\.css$/, use: ['style-loader', 'css-loader'] },
{
test: /\.less$/, use: ['style-loader', 'css-loader', 'less-loader'] },
{
test: /\/.jpg|png|gif$/,
use: {
loader: 'url-loader', //通过loader属性指定调用的loader
options: {
//通过options属性指定参数项
limit: 66300
}
}
},
],
},
}
6. 高度な構文を js ファイルにパッケージ化して処理する
webpack は高度な JavaScript 構文の一部のみをパッケージ化して処理できます。Webpack が処理できない高度な JS 構文については、パッケージ化に babel-loader を使用する必要があります。たとえば、webpack は次の JavaScript コードを処理できません。
class Person{
//通过start关键字,为Person类定义了一个静态属性info
//webpack无法打包处理"静态属性"这个高级语法
static info = 'person info'
}
console.log(Person.info)
6.1 babel-loader 関連パッケージのインストール
次のコマンドを実行して、対応する依存関係パッケージをインストールします。
npm install [email protected] @babel/[email protected] @babel/[email protected] -D
パッケージ名とバージョン番号のリストは次のとおりです (赤がパッケージ名、黒がパッケージのバージョン番号)。
-
バベルローダー@8.2.1
-
@バベル/コア@7.12.3
-
@babel/[email protected]
6.2 バベルローダーの設定
webpack.config.js の module -> rules 配列に、次のようにローダー ルールを追加します。
{
test: /\.js$/,
// exclude为排除项
// 表示badel-loader 只需要处理开发编写的js文件,不需要处理node-modules下的js文件
exclude: /node-modules/,
use: {
loader: 'babel-loader',
options: {
//参数项
// 声明一个badel插件,此插件用来转化class中的高级语法
plugins: ['@babel/plugin-proposal-class-properties'],
}
}
},
パッケージ化して公開する
1. なぜパッケージ化してリリースするのか?
プロジェクトの開発が完了した後、webpack を使用してプロジェクトをパッケージ化してリリースする主な理由は次のとおりです。
① 開発環境では、パッケージ化により生成されたファイルがメモリ上に格納され、パッケージ化により生成された最終ファイルを取得できません。
② 開発環境では、パッケージ化によって生成されたファイルはコード圧縮やパフォーマンスの最適化が行われません。
プロジェクトを実稼働環境で高いパフォーマンスで実行するには、プロジェクトをパッケージ化してリリースする必要があります。
2. Webpack のパッケージ化とリリースを構成する
package.json ファイルの script ノードの下に、次のようにビルド コマンドを追加します。
"scripts": {
"dev": "webpack serve",
//项目发布时,运行build命令
"build":"webpack --mode production"
},
–model は、Webpack の実行モードを指定するために使用されるパラメーターです。Production は実稼働環境を表し、パッケージ化によって生成されたファイルに対してコード圧縮とパフォーマンスの最適化を実行します。
注: --model で指定されたパラメータは、webpack.config.js のモデル オプションをオーバーライドします。
3. JavaScript ファイルを js ディレクトリに生成します
webpack.config.js 構成ファイルの出力ノードで、次の構成を実行します。
output: {
//输出文件的存放路径
path: path.join(__dirname, './dist'),
// 明确告诉webpack把生成的bundle.js文件存放到dist目录下的js子目录中
filename: 'js/bundle.js',
},
4. イメージファイルをイメージディレクトリに生成します。
webpack.config.js の url-loader 構成項目を変更し、outputPath オプションを追加して、イメージ ファイルの出力パスを指定します。
{
test: /\/.jpg|png|gif$/,
use: {
loader: 'url-loader', //通过loader属性指定调用的loader
options: {
//通过options属性指定参数项
limit: 66300,
outputPath: 'image'
},
}
},
5. dist ディレクトリ内の古いファイルを自動的にクリーンアップする
パッケージ化して公開するたびに dist ディレクトリ内の古いファイルを自動的にクリーンアップするには、clean-webpack-plugin プラグインをインストールして構成できます。
//1.安装清理dist目录的webpack插件
npm i clean-webpack-plugin@3.0.0 -D
//2.按需导入插件,得到插件的构造函数之后,创建插件的实例对象
const {
CleanWebpackPlugin } = require('clean-webpack-plugin')
const cleanPlugin = new CleanWebpackPlugin()
//3.把创建的cleanPlugin 插件实例对象,挂载到plugins节点中
plugins: [htmlPlugin, cleanPlugin],
const path = require('path')
// 1.导入插件,得到构造函数
const HtmlPlugin = require('html-webpack-plugin')
// 2. 创建插件的实例对象
const htmlPlugin = new HtmlPlugin({
template: './src/index.html',
filename: './index.html',
})
const {
CleanWebpackPlugin } = require('clean-webpack-plugin')
new cleanPlugin = CleanWebpackPlugin()
module.exports = {
mode: 'development',
//打包入口文件的路径
entry: path.join(__dirname, './src/index.js'),
output: {
//输出文件的存放路径
path: path.join(__dirname, './dist'),
// 输出文件的名称
filename: 'js/bundle.js',
},
// 挂载插件的实例对象
plugins: [htmlPlugin, cleanPlugin],
devServer: {
open: true,
host: '127.0.0.1',
port: 80
},
module: {
rules: [
{
test: /\.css$/, use: ['style-loader', 'css-loader'] },
{
test: /\.less$/, use: ['style-loader', 'css-loader', 'less-loader'] },
{
test: /\/.jpg|png|gif$/,
use: {
loader: 'url-loader', //通过loader属性指定调用的loader
options: {
//通过options属性指定参数项
limit: 66300,
outputPath: 'image'
},
}
},
{
test: /\.js$/,
// exclude为排除项
// 表示badel-loader 只需要处理开发编写的js文件,不需要处理node-modules下的js文件
exclude: /node-modules/,
use: {
loader: 'babel-loader',
options: {
//参数项
// 声明一个badel插件,此插件用来转化class中的高级语法
plugins: ['@babel/plugin-proposal-class-properties'],
}
}
},
],
},
}
6. エンタープライズレベルのプロジェクトのパッケージ化とリリース
エンタープライズ レベルのプロジェクトをパッケージ化してリリースする場合、以前の方法よりもはるかに複雑になり、主なリリース プロセスは次のとおりです。
-
梱包レポートを生成し、レポートに基づいて特定の最適化計画を分析します。
-
木を揺らす
-
サードパーティライブラリの CDN ロードを有効にする
-
コンポーネントのオンデマンド読み込みを構成する
-
ルートの遅延読み込みを有効にする
-
カスタマイズされたホームページのコンテンツ
ソースマップ
1. 本番環境で発生した問題
フロントエンド プロジェクトを運用環境に導入する前に、JavaScript ソース コードを圧縮して難読化して、ファイル サイズを削減し、ファイルの読み込み効率を向上させる必要があります。この時点で、別の疑問が必然的に生じます。
圧縮と難読化後のコードのデバッグは非常に困難です
-
変数は意味的な意味を持たない名前に置き換えられます
-
空白行とコメントは削除されます
2. ソースマップとは何ですか?
Source Map は、位置情報を格納する情報ファイルです。言い換えれば、ソース マップ ファイルには、コード圧縮と難読化の間の対応関係が保存されます。
これにより、エラーが発生した場合、デバッグ ツールは変換されたコードではなく元のコードを直接表示するため、後のデバッグが大幅に容易になります。
3. Webpack開発環境のソースマップ
開発環境では、webpack はデフォルトでソース マップ機能を有効にします。プログラムの実行中にエラーが発生した場合、コンソール上でエラー行の位置を直接表示し、特定のソース コードを見つけることができます。
3.1 デフォルトのソースマップの問題
開発環境でデフォルトで生成されるソース マップには、生成されたコードの場所が記録されます。これにより、実行時エラーの行数がソースコードの行数と一致しないという問題が発生します。概略図は次のとおりです。
3.2 デフォルトのソースマップの問題を解決する
開発環境では、実行時のエラー行数がソース コードの行数と一致するように、次の構成を webpack.config.js に追加することをお勧めします。
module.exports = {
mode: 'development',
//此选项生成的Source Map 能够保证"运行时报错的行数"与""源代码的行数"保持一致
devtool: 'eval-source-map',
//省略其他配置
}
4. Webpack本番環境のソースマップ
運用環境で devtool オプションを省略すると、ソース マップは最終的に生成されるファイルに含まれません。これにより、ソース マップを通じて元のコードが権限のない者に公開されるのを防ぎます。
4.1 ソースコードを公開せずに行数のみを特定する
運用環境で、エラーが報告された特定の行数のみを特定し、ソース コードを公開したくない場合。このとき、devtool の値は nosources-source-map に設定できます。実際の効果を図に示します。
4.2 行数を特定し、ソースコードを公開する
運用環境で、エラー行数を特定しながら特定のエラーのソース コードを表示したい場合。このとき、devtoolの値をsource-mapに設定することができます。実際の効果を図に示します。
このオプションを使用した後は、一般のユーザーがソース マップ ファイルにアクセスできないようにサーバーを設定する必要があります。
5. ソースマップのベストプラクティス
①開発環境の場合:
-
devtool の値を eval-source-map に設定することをお勧めします。
-
利点: 特定のエラー行を正確に特定できる
② 本番環境の場合:
-
ソース マップをオフにするか、devtool の値を nosources-source-map に設定することをお勧めします。
-
メリット: ソースコードの漏洩を防ぎ、Web サイトのセキュリティを向上させます。
Vue の基本を始める
vueの紹介
1.vueとは
公式コンセプト: Vue (/vjuː/ と発音、ビューに似ています) は、ユーザー インターフェイスを構築するためのフロントエンド フレームワークです。
主要なキーワード: ユーザー インターフェイスの構築、フレームワーク
1.1 コアキーワードの解釈: ユーザーインターフェイスの構築
フロントエンド開発者の主な仕事は、Web サイト ユーザー (Web サイト ユーザーとも呼ばれます) のために美しく、快適で、使いやすい Web ページを構築することです。
記述構造: HTML ハイパーテキスト マークアップ言語に基づいて、Web ページのコンテンツ構造を構築します。
美化スタイル: Web ページの視覚効果を美化するための基本的な CSS スタイル。
インタラクションの処理: Javascript に基づいて Web ページ内の DOM オブジェクトを操作し、ユーザーと Web ページ間のインタラクションを処理します。
1.2 ユーザーインターフェイスを構築する従来の方法
従来の Web フロントエンド開発では、ユーザー インターフェイスは jQuery + テンプレート エンジンに基づいて構築されます。
書き込み構造: テンプレート エンジン テクノロジに基づいて、データがページ上にレンダリングされます。
利点: 最初はフロントエンド開発者が解放され、今後は、Web ページ構造をレンダリングするために手動で文字列を結合する必要がなくなります。
欠点: 1. 多数のテンプレート構造を定義する必要がある; 2. 構文の強調表示とスマート プロンプトが欠如している; 3. データが変更された場合、テンプレート コンパイル関数を再度呼び出す必要があり、そうしないとページ構造が更新されません。
美化スタイル: Web ページの視覚効果を美化するための基本的な CSS スタイル。
インタラクションの処理: jQuery テクノロジーに基づいて、ユーザーと Web ページ間のインタラクションを処理します。
利点: DOM API 間の互換性を保護し、DOM 操作の効率とエクスペリエンスを向上させます。短所: ビジネスが複雑でデータが頻繁に変更される場合、フロントエンド開発者はコアのビジネス処理ではなく DOM 操作に多くの時間とエネルギーを浪費する必要があります。
1.3 vue を使用してユーザー インターフェイスを構築する
vue を使用してユーザー インターフェイスを構築すると、jQuery + テンプレート エンジンの多くの問題点が解決され、フロントエンド開発の効率とエクスペリエンスが大幅に向上します。
記述構造: vue で提供される指示に基づいて、ページの構造を便利かつ迅速にレンダリングできます (Shu を見逃してうれしいです)。
データドリブン ビュー (ページが依存するデータ ソースが変更される限り、ページは自動的に再レンダリングされます)
Ps: ディレクティブは、開発者がページの構造をレンダリングするのを支援するために、Vue によって開発者向けに提供されるテンプレート構文です。
美化スタイル: Web ページの視覚効果を美化するための基本的な CSS スタイル。
インタラクションの処理: vue で提供されるイベント バインディングに基づいて、ユーザーとページ間のインタラクションを簡単に処理できます。
追記: 開発者はコアビジネスの実現に集中して取り組んでいます
1.4 核となるキーワードの解釈: フレームワーク
vue の公式の位置付けは、ユーザー インターフェイス (一般に vue ファミリー バケットとして知られる) を構築するための完全なソリューション セットを提供するため、フロントエンド フレームワークです。
- vue (コアライブラリ)
- vue-router (ルーティング ソリューション)
- vuex (状態管理ソリューション)
- vue コンポーネント ライブラリ (ページ UI 効果を迅速に構築するためのソリューション)
Vue プロジェクト開発を支援する一連のツール:
- vue-cli (npm グローバル パッケージ: エンジニアリングされた vue プロジェクトをワンクリックで生成 - Webpack に基づいており、大規模で包括的)
- vite (npm グローバル パッケージ: エンジニアリングされた Vue プロジェクトのワンクリック生成 - 小さくてエレガント)
- vue-devtools (ブラウザプラグイン: デバッグを支援するツール)
- vetur (vscode プラグイン: 構文の強調表示とスマート ヒントを提供します)
1.5 概要: vue とは
vue は、ユーザー インターフェイスを構築するためのフロントエンド フレームワークです。
フロントエンドフレームワーク:
-
ユーザー インターフェイスを構築するためのソリューションの完全なセット
-
vue ファミリー バケット: vue + vue-router + vuex + コンポーネント ライブラリ
-
プロジェクト開発を支援するサポート ツール vue-cli + vue-devtools を提供します
ユーザー インターフェイスを構築します。
- ディレクティブ: 開発者によるページのレンダリングを支援するために使用されるテンプレート構文
- イベント バインディング: ユーザーと Web ページ間の対話を処理するために使用されます。
- データドリブン ビュー: データ ソースが変更されると、ページ構造が自動的に再レンダリングされます。
2.vueの特徴
vue フレームワークの特徴は主に次の 2 つの側面に反映されています。
① データドリブンな視点
②双方向データバインディング
2.1 データ駆動型のビュー
vue を使用するページでは、vue はデータの変更をリッスンし、ページ構造を自動的に再レンダリングします。概略図は次のとおりです。
利点: ページ データが変更されると、ページが自動的に再レンダリングされます。
注: データ駆動型ビューは一方向のデータ バインディングです。
2.2 双方向のデータバインディング
フォームに入力する場合、双方向データ バインディングにより、開発者は DOM を操作せずに、ユーザーが入力したコンテンツをデータ ソースに自動的に同期できます。概略図は次のとおりです。
利点: 開発者は、フォーム要素の最新の値を取得するために DOM 要素を手動で操作する必要がなくなりました。
2.3 MVVM
MVVM は、データ駆動型ビューと双方向データ バインディングを実装するための Vue の中核原則です。各 HTML ページは次の 3 つの部分に分割されます。
MVVMの概念では次のようになります。
- ビューは、現在のページによってレンダリングされる DOM 構造を表します。
- モデルは、現在のページがレンダリング時に依存するデータ ソースを表します。
- ViewModel は、MVVM のコアである vue のインスタンスを表します。
2.4 MVVM の仕組み
ViewModel は MVVM の中核として、現在のページのデータ ソース (Model) とページ構造 (View) を接続します。
データ ソースが変更されると、ViewModel によって監視され、VM は最新のデータ ソースに基づいてページ構造を自動的に更新します。
フォーム要素の値が変更されると、その値も VM によって監視され、変更後の最新の値がモデル データ ソースに自動的に同期されます。
3.vueのバージョン
現在、vue には次の 3 つのメジャー バージョンがあります。
vue の 2.x バージョンは、現在、エンタープライズ レベルのプロジェクト開発における主流のバージョンです。
vue の 3.x バージョンは 2020 年 9 月 19 日にリリースされました。エコシステムはまだ完成しておらず、エンタープライズ レベルのプロジェクト開発ではまだ普及および推進されていません。
vue の 1.x バージョンはほぼ削除されており、学習および使用は推奨されなくなりました。
要約:
vue の 3.x バージョンは、エンタープライズ レベルのプロジェクト開発の将来のトレンドです。
vue の 2.x バージョンは、将来 (1 ~ 2 年以内) に段階的に廃止される予定です。
3.1 vue3.x と vue2.x のバージョンの比較
vue2.x の API と機能のほとんどは vue3.x でもサポートされています。同時に、vue3.x では 3.x に固有の新機能も追加され、2.x の古い機能の一部が削除されています。
新機能は次のとおりです。
複合 API、マルチルート ノード コンポーネント、TypeScript サポートの向上など。
廃止された古い機能は次のとおりです。
フィルター、on、on、はサポートされなくなりましたon 、 off 、 $ once インスタンス メソッドなど。
詳細な変更情報については、公式ドキュメントに記載されている移行ガイドを参照してください: https://v3.vuejs.org/guide/migration/introduction.html
vueの基本的な使い方
1. 基本的な使用手順
①vue.jsのスクリプトスクリプトファイルをインポートする
②vueで制御するDOM領域をページ内に宣言
③vmインスタンスオブジェクト(vueインスタンスオブジェクト)の作成
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<!-- 2.声明要被vue所控制的dom区域 -->
<div id='app'>{
{username}}</div>
<!-- 1.导入vue的脚本文件 -->
<script src="./lib/vue-2.6.12.js"></script>
<!-- 3.创建vue实例对象 -->
<script>
const vm = new Vue({
// 3.1使用el属性指定vue要控制的区域
el: '#app',
// 3.2数据源
data: {
username: 'zs',
},
})
</script>
</body>
</html>
2. 基本コードとMVVMの対応
Vue用のデバッグツール
1. vue-devtools デバッグ ツールをインストールします。
vue によって公式に提供される vue-devtools デバッグ ツールを使用すると、開発者は vue プロジェクトのデバッグと開発を容易にできます。
Chrome ブラウザは vue-devtools をオンラインでインストールします
vue 2.x デバッグ ツール:
https://chrome.google.com/webstore/detail/vuejs-devtools/nhdogjmejiglipccpnnnanhbledajbpd
vue 3.x デバッグ ツール:
https://chrome.google.com/webstore/detail/vuejs-devtools/ljjemllljcmogpfapbkkighbhhppjdbg
注: vue2 と vue3 のブラウザ デバッグ ツールを相互に使用することはできません。
2. Chrome ブラウザで vue-devtools を設定する
Chrome ブラウザの右上隅にあるボタンをクリックし
、[その他のツール]->[拡張機能]->[Vue.js devtools 詳細] を選択し、次の 2 つのオプションを確認します。
注: 構成項目を変更した後、有効にするためにブラウザを再起動する必要があります。
3. vue-devtools を使用して vue ページをデバッグします
ブラウザで vue を使用してページにアクセスし、ブラウザの開発者ツールを開き、Vue パネルに切り替えて、vue-devtools を使用して現在のページをデバッグします。
vue ディレクティブとフィルター
1. 命令の概念
ディレクティブは、開発者がページの基本構造をレンダリングするのを支援するために、Vue によって開発者向けに提供されるテンプレート構文です。
vue の命令は、用途に応じて次の 6 つのカテゴリに分類できます。
①コンテンツのレンダリング命令
② 属性バインディング命令
③イベントバインディング命令
④双方向綴じの説明
⑤ 条件付き描画命令
⑥ リスト描画命令
注: 命令は、Vue 開発における最も基本的で、一般的に使用され、最も単純な知識ポイントです。
1.1 コンテンツのレンダリング手順
コンテンツレンダリング命令は、開発者が DOM 要素のテキストコンテンツをレンダリングするのを支援するために使用されます。一般的に使用されるコンテンツのレンダリング命令は 3 つあります。
- v-テキスト
- { { }}
- v-html
v-テキスト
使用例:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<div id='app'>
<!-- 把username对应的值,渲染到第一个p标签中 -->
<p v-text="username"></p>
<!-- 把gender对应的值,渲染到第二个p标签中 -->
<!-- 注意:第二个p标签中,默认的文本‘性别’会被值覆盖掉 -->
<p v-tetx="gender">性别</p>
</div>
<script src="./lib/vue-2.6.12.js"></script>
<script>
const vm = new Vue({
el: 'app',
data: {
username: 'zs',
gender: '男'
}
})
</script>
</body>
</html>
注: v-text ディレクティブは、要素内のデフォルト値をオーバーライドします。
{ { }} 構文
vue が提供する { { }} 構文は、 v-text がデフォルトのテキスト コンテンツを上書きするという問題を解決するために特に使用されます。この{ }}構文の正式名称は補間式(英語名:Mustache)といいます。
<!-- 使用{
{}} 插值表达式,将对应的值渲染到元素的内容节点中 -->
<!-- 同时保留元素自身的默认值 -->
<p>姓名:{
{username}}</p>
<p>性别:{
{gender}}</p>
注: v-text ディレクティブと比較して、補間式は開発でより一般的に使用されます。要素内のデフォルトのテキストコンテンツを上書きしないためです。
v-html
v-text ディレクティブと補間式は、プレーン テキスト コンテンツのみをレンダリングできます。HTML タグを含む文字列をページ上の HTML 要素としてレンダリングする場合は、v-html ディレクティブを使用する必要があります。
<--desc: '<i>abc<i>'-->
<P v-html="desc"></P>
1.2 属性バインディングの手順
属性値を要素の属性に動的にバインドする必要がある場合は、v-bind 属性バインディング ディレクティブを使用する必要があります。使用例は以下のとおりです。
<!--假设有如下的data数据:
data:{
inputValue:'请输入内容',
imgSrc:'https://cn.vuejs.org/images/logo.png'
}
-->
<!--使用v-bind指令,为input的placeholder动态绑定属性值-->
<input type="text" v-bind:placcholder="inputvalue"/>
<br/>
<!--使用v-bind指令,为img的src动态绑定属性值-->
<img v-bind:src="imgSrc" alt=""/>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<div id='app'>
<input type="text" v-bind:placeholder="inputValue">
<hr>
<img v-bind:src="imgSrc">
</div>
<script src="./lib/vue-2.6.12.js"></script>
<script>
const vm = new Vue({
el: '#app',
data: {
inputValue: '请输入内容',
//图片的src地址
imgSrc: './image/1.png',
},
})
</script>
</body>
</html>
属性バインディングディレクティブの短い形式
v-bind 命令は開発において非常に頻繁に使用されるため、vue ではその略称が公式に提供されています (英語の略称: )。
<!--假设有如下的data数据:
data:{
inputValue:'请输入内容',
imgSrc:'https://cn.vuejs.org/images/logo.png'
}
-->
<!--使用v-bind指令,为input的placeholder动态绑定属性值-->
<input type="text" :placcholder="inputvalue"/>
<br/>
<!--使用v-bind指令,为img的src动态绑定属性值-->
<img :src="imgSrc" alt=""/>
JavaScript 式の使用
vue が提供するテンプレート レンダリング構文では、単純なデータ値のバインディングのサポートに加えて、次のような Javascript 式の操作もサポートされます。
{
{number+1}}
{
{ok? 'yes':'no'}}
{
{message.split('').reverse().join('')}}
<div v-bind:id="list-"+id></div>
1.3 イベントバインディング命令
vue は、プログラマーがイベント リスナーを DOM 要素にバインドするのを支援する v-on イベント バインディング命令を提供します。構文形式は次のとおりです。
<h3>count 的值为:{
{count}}</h3>
<!--语法格式为v-on:事件名称="事件处理函数的名称"-->
<button v-on: click='addCount'>+1</button>
注: ネイティブ DOM オブジェクトには、onclick、oninput、onkeyup などのネイティブ イベントがあり、これらを vue のイベント バインディング フォームに置き換えると、v-on:click、v-on:input、v-on:keyup になります。
v-on を介してバインドされたイベント処理関数は、メソッド ノードで宣言する必要があります。
const vm = new Vue({
el: '#app',
data: {
count: 0,
},
methods: {
//v-on 绑定的事件处理函数,需要声明在methods节点中
addCount() {
//事件处理函数的名字
//this表示当前new出来的vm实例对象
//通过this可以访问到data中的数据
this.count += 1
}
},
})
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<div id="app">
<h3>count 的值为:{
{count}}</h3>
<!--语法格式为v-on:事件名称="事件处理函数的名称"-->
<button v-on:click="addCount">+1</button>
</div>
<script src="./lib/vue-2.6.12.js"></script>
<script>
const vm = new Vue({
el: '#app',
data: {
count: 0,
},
methods: {
//v-on 绑定的事件处理函数,需要声明在methods节点中
addCount() {
//事件处理函数的名字
//this表示当前new出来的vm实例对象
//通过this可以访问到data中的数据
this.count += 1
}
},
})
</script>
</body>
</html>
イベントバインディングの短縮形
v-on命令は開発において非常に頻繁に使用されるため、vueでは公式にその略称(英語では@と略します)を設けています。
<div id="app">
<h3>count 的值为:{
{count}}</h3>
<!--语法格式为v-on:事件名称="事件处理函数的名称"-->
<button @click="count+=1">+1</button>
</div>
イベントオブジェクト イベント
ネイティブDOMイベントバインディングでは、イベントオブジェクトのイベントをイベント処理関数の仮パラメータで受け取ることができます。同様に、v-on命令(略称@)にバインドされたイベント処理関数でもイベントオブジェクトのイベントを受け取ることができますサンプルコードは以下の通りです。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<div id="app">
<h3>count 的值为:{
{count}}</h3>
<!--语法格式为v-on:事件名称="事件处理函数的名称"-->
<button @click="addCount">+1</button>
</div>
<script src="./lib/vue-2.6.12.js"></script>
<script>
const vm = new Vue({
el: '#app',
data: {
count: 0,
},
methods: {
//v-on 绑定的事件处理函数,需要声明在methods节点中
addCount(e) {
const nowBgColor = e.target.style.backgroundColor
e.target.style.backgroundColor = nowBgColor === 'red' ? '' : 'red'
this.count += 1
}
},
})
</script>
</body>
</html>
イベントをバインドしてパラメータを渡す
v-on 命令を使用してイベントをバインドする場合、() を使用してパラメーターを渡すことができます。サンプル コードは次のとおりです。
<div id="app">
<h3>count 的值为:{
{count}}</h3>
<!--语法格式为v-on:事件名称="事件处理函数的名称"-->
<button @click="addCount(2)">+2</button>
</div>
methods: {
//在形参处用step接收传递过来的参数值
addCount(step) {
this.count += step
}
},
$イベント
Event は、vue によって提供される特別な変数で、ネイティブ イベント パラメーター オブジェクトのイベントを表すために使用されます。Event は、vue によって提供される特別な変数で、ネイティブ イベント パラメーター オブジェクトのイベントを表すために使用されます。e v e n t は、 vueによって提供される特別な変数で、ネイティブ イベント パラメーター オブジェクトe v e n tを表すために使用されます。イベントは、イベントパラメータオブジェクトのイベントが上書きされる問題を解決できます。使用例は次のとおりです。
<h3>count 的值为:{
{count}}</h3>
<!--语法格式为v-on:事件名称="事件处理函数的名称"-->
<button @click="addCount(2,$event)">+2</button>
methods: {
//v-on 绑定的事件处理函数,需要声明在methods节点中
addCount(step, e) {
const nowBgColor = e.target.style.backgroundColor
e.target.style.backgroundColor = nowBgColor === 'red' ? '' : 'red'
this.count += step
}
},
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<div id="app">
<h3>count 的值为:{
{count}}</h3>
<!--语法格式为v-on:事件名称="事件处理函数的名称"-->
<button @click="addCount(2,$event)">+2</button>
</div>
<script src="./lib/vue-2.6.12.js"></script>
<script>
const vm = new Vue({
el: '#app',
data: {
count: 0,
},
methods: {
//v-on 绑定的事件处理函数,需要声明在methods节点中
addCount(step, e) {
const nowBgColor = e.target.style.backgroundColor
e.target.style.backgroundColor = nowBgColor === 'red' ? '' : 'red'
this.count += step
}
},
})
</script>
</body>
</html>
イベント修飾子
イベント ハンドラーでPreventDefault() または stopPropagation() を呼び出すことは、非常に一般的な要件です。したがって、Vue は、プログラマがイベントのトリガーをより簡単に制御できるようにするイベント修飾子の概念を提供します。一般的に使用される 5 つのイベント修飾子は次のとおりです。
イベント修飾子 | 説明する |
---|---|
。防ぐ | デフォルトの動作を防止します (例: 接続のジャンプの防止、フォームの送信の防止など) |
。停止 | イベントの急増を防ぐ |
。捕獲 | キャプチャ モードで現在のイベント ハンドラーをトリガーする |
。一度 | バインドされたイベントは 1 回だけトリガーされます |
。自己 | イベント ハンドラーは、event.target が現在の要素自体である場合にのみトリガーされます。 |
構文形式は次のとおりです。
<!--触发click点击事件,阻止a链接的默认行为-->
<a href="https://www.baidu.com" @click.prevent="onLinkClick">百度首页</a>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
.inner {
line-height: 100px;
background-color: aliceblue;
font-size: 13px;
text-align: center;
}
.outer {
background-color: bisque;
padding: 50px;
font-size: 13px;
}
.box {
background-color: coral;
padding: 50px;
}
</style>
</head>
<body>
<!-- 在页面中声明一个将要被 vue 所控制的 DOM 区域 -->
<div id="app">
<h4>① .prevent 事件修饰符的应用场景</h4>
<a href="https://www.baidu.com" @click.prevent="onLinkClick">百度首页</a>
<hr />
<h4>② .stop 事件修饰符的应用场景</h4>
<div class="outer" @click="onOuterClick">
外层的 div
<div class="inner" @click.stop="onInnerClick">内部的 div</div>
</div>
<hr />
<h4>③ .capture 事件修饰符的应用场景</h4>
<div class="outer" @click.capture="onOuterClick">
外层的 div
<div class="inner" @click="onInnerClick">内部的 div</div>
</div>
<hr />
<h4>④ .once 事件修饰符的应用场景</h4>
<div class="inner" @click.once="onInnerClick">内部的 div</div>
<hr />
<h4>⑤ .self 事件修饰符的应用场景</h4>
<div class="box" @click="onBoxClick">
最外层的 box
<div class="outer" @click.self="onOuterClick">
中间的 div
<div class="inner" @click="onInnerClick">内部的 div</div>
</div>
</div>
<hr />
</div>
<script src="./lib/vue-2.6.12.js"></script>
<script>
const vm = new Vue({
el: '#app',
// 声明处理函数的节点
methods: {
// 超链接的点击事件处理函数
onLinkClick() {
alert('ok')
},
// 点击了外层的 div
onOuterClick() {
console.log('触发了 outer 的 click 事件处理函数')
},
// 点击了内部的 div
onInnerClick() {
console.log('触发了 inner 的 click 事件处理函数')
},
onBoxClick() {
console.log('触发了 box 的 click 事件处理函数')
}
},
})
</script>
</body>
</html>
キー修飾子
キーボード イベントをリッスンするとき、多くの場合、詳細なキーストロークを判断する必要があります。この時点で、次のようなキー修飾子をキーボード関連のイベントに追加できます。
<!--只有在‘key”是“Enter’时调用“vm. submit()'' -->
<input @keyup.enter="submit">
<!--只有在'key'是'ESc'时调用'vm.clearInput()' -->
<input @keyup.esc="clearInput">
1.4 双方向バインディング命令
vue は、開発者が DOM を操作せずにフォーム データを迅速に取得できるように、v-model の双方向データ バインディング命令を提供します。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
</head>
<body>
<div id="app">
<p>用户名是:{
{username}}</p>
<input type="text" v-model="username" />
<hr />
<p>选中的省份是:{
{province}}</p>
<select v-model="province">
<option value="">请选择</option>
<option value="1">北京</option>
<option value="2">河北</option>
<option value="3">黑龙江</option>
</select>
</div>
<script src="./lib/vue-2.6.12.js"></script>
<script>
const vm = new Vue({
el: '#app',
data: {
// 姓名
username: 'zs',
// 省份
province: '1',
},
})
</script>
</body>
</html>
注: v-model ディレクティブは、フォーム要素でのみ使用できます。
v-model ディレクティブの修飾子
ユーザー入力の処理を容易にするために、vue は v-model ディレクティブに次の 3 つの修飾子を提供します。
修飾子 | 効果 | 例 |
---|---|---|
。番号 | ユーザー入力値を数値型に自動的に変換します |
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<div id='app'>
姓名:<input type="text" v-model.trim="username">
</hr>
年龄:<input type="text" v-model.number="age">
</hr>
地址:<input type="text" v-model.lazt="address">
</div>
<script src="./lib/vue-2.6.12.js"></script>
<script>
const vm = new Vue({
el: '#app',
data: {
address: '北京市',
age: '12',
username: "zs"
},
})
</script>
</body>
</html>
1.5 条件付きレンダリング命令
条件付きレンダリング命令は、開発者が必要に応じて DOM の表示と非表示を制御できるようにするために使用されます。条件付きレンダリング命令には、次の 2 つがあります。
- v-if
- Vショー
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<div id="app">
<button @click="flag =!flag">Toggle Flag</button>
<p v-if="flag">请求成功---被v-if控制</p>
<p v-show="flag">请求成功---被v-show控制</p>
</div>
<script src="./lib/vue-2.6.12.js"></script>
<script>
const vm = new Vue({
el: '#app',
data: {
// flag用来控制元素的显示与隐藏
// 值为 true 时显示元素
// 值为false时隐藏元素
flag: true,
}
})
</script>
</body>
</html>
v-ifとv-showの違い
実装原則は異なります。
- v-if ディレクティブは、DOM 要素を動的に作成または削除して、ページ上の要素の表示と非表示を制御します。
- v-show コマンドは、style="display: none;" スタイルを要素に動的に追加または削除して、要素の表示と非表示を制御します。
パフォーマンスの消費は異なります。
v-if はスイッチング オーバーヘッドが高く、v-show は初期レンダリング オーバーヘッドが高くなります。
- 頻繁に切り替える必要がある場合は、v-show を使用することをお勧めします。
- 実行時に条件がほとんど変化しない場合は、v-if の方が適しています。
v-その他
v-if は、単独で使用することも、v-else ディレクティブと一緒に使用することもできます。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<div id="app">
<p v-if="num>0.5">随机数 > 0.5</p>
<p v-else>随机数 ≤ 0 .5</p>
<hr>
<p>优秀</p>
<p>良好</p>
<p>一般</p>
<p>差</p>
</div>
<script src="./lib/vue-2.6.12.js"></script>
<script>
const vm = new Vue({
el: '#app',
data: {
// 生成1以内的随机数
num: Math.random(),
// 类型
type: 'A'
},
})
</script>
</body>
</html>
v-else-if
v-else-if ディレクティブは、名前が示すように、v-if の「else-if ブロック」として機能し、継続的に使用できます。
<p v-if="type === 'A'">优秀</p>
<p v-else-if="type === 'B'">良好</p>
<p v-else-if="type === 'C'">一般</p>
<p v-else>差</p>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<div id="app">
<p v-if="num>0.5">随机数 > 0.5</p>
<p v-else>随机数 ≤ 0 .5</p>
<hr>
<p v-if="type === 'A'">优秀</p>
<p v-else-if="type === 'B'">良好</p>
<p v-else-if="type === 'C'">一般</p>
<p v-else>差</p>
</div>
<script src="./lib/vue-2.6.12.js"></script>
<script>
const vm = new Vue({
el: '#app',
data: {
// 生成1以内的随机数
num: Math.random(),
// 类型
type: 'A'
},
})
</script>
</body>
</html>
1.6 リストレンダリング命令
vue は、開発者が配列に基づいて同様の UI 構造をループおよびレンダリングするのを支援する v-for 命令を提供します。
v-for ディレクティブには、items 内の item という特別な構文が必要です。ここで、
items はループされる配列です
item は現在のループ項目です
data{
list:[
{id:1,name:'zs'},
{id:2,name:'ls'}
]
}
//------------------------
<ul>
<li v-for='item in list'>姓名是:{
{item.name}}</li>
</ul>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<div id="app">
<ul>
<li v-for="user in list">姓名是:{
{user.name}}</li>
</ul>
</div>
<script src="./lib/vue-2.6.12.js"></script>
<script>
const vm = new Vue({
el: '#app',
data: {
list: [{
id: 1,
name: 'zs'
}, {
id: 2,
name: 'ls'
}]
}
})
</script>
</body>
</html>
v-for のインデックス
v-for ディレクティブは、オプションの 2 番目の引数 (現在の項目のインデックス) もサポートします。構文形式は (item, Index) in items です。サンプルコードは次のとおりです。
data: {
list: [{
id: 1,
name: 'zs'
}, {
id: 2,
name: 'ls'
}]
}
//------------------------
<ul>
<li v-for='(item , index)in list'>索引是:{
{index}},姓名是:{
{item.name}}</li>
</ul>
注: v-for ディレクティブの item item と Index は仮パラメータであり、必要に応じて名前を変更できます。たとえば、userlist の (user, i)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<div id="app">
<ul>
<li v-for="(user,i) in list">索引是:{
{i+1}},姓名是:{
{user.name}}</li>
</ul>
</div>
<script src="./lib/vue-2.6.12.js"></script>
<script>
const vm = new Vue({
el: '#app',
data: {
list: [{
id: 1,
name: 'zs'
}, {
id: 2,
name: 'ls'
}]
}
})
</script>
</body>
</html>
キーを使用してリストの状態を維持します
リスト内のデータが変更されると、デフォルトでは、Vue はレンダリング パフォーマンスを向上させるために既存の DOM 要素を可能な限り再利用します。ただし、このデフォルトのパフォーマンス最適化戦略では、ステートフル リストが正しく更新されなくなります。
Vue にヒントを与えることで、各ノードの ID を追跡できるようになり、ステートフル リストが正しく更新されるようにしながら、レンダリング パフォーマンスを向上させることができます。この時点で、各項目に一意のキー属性を指定する必要があります。
<!-- 用户列表区域 -->
<ul>
<!-- 加key属性的好吃: -->
<!-- 1.正确维护列表的状去-->
<!-- 2.复用现有的DOM元素,提升渲染的性能 -->
<li v-for="(user, index) in userlist" :key="user id">
<input type="checkbox" />
姓名:{
{user.name}}
</li>
</ul>
キーに関する注意事項
① keyの値は文字列型または数値型のみとなります
② キーの値は一意でなければなりません(つまり、キーの値は重複できません)
③ データ項目の id 属性の値をキーの値として使用することを推奨します(id 属性の値は一意であるため)。 ④ インデックスの値をキーの値として使用しても意味がありません。キー (インデックスの値が一意ではないため)
⑤ v-for命令を使用する場合はkeyの値を指定することを推奨します(性能向上だけでなく、リスト状態の乱れを防ぐため)
2. フィルター
フィルターはテキストの書式設定によく使用されます。例えば:
こんにちは -> こんにちは
フィルタは JavaScript 式の最後に追加し、「パイプ文字」によって呼び出す必要があります。サンプル コードは次のとおりです。
<!--在双花括号中通过""管道符""调用capitalize过滤器,对message 的值进行格式化-->
<P>{
{ message | capitalize }}</P>
<!--在v-bind中通过"管道符"调用formatId 过滤器,对rawId 的值进行格式化-->
<div v-bind:id="rawId | formatId"></div>
フィルターは、補間式と v-bind プロパティ バインディングの 2 つの場所で使用できます。
2.1 フィルタの定義
vue インスタンスの作成中に、フィルター ノードでフィルターを定義できます。サンプル コードは次のとおりです。
const vm = new Vue({
el: "#app",
data: {
message: 'hello vuc.js ',
info: 'title info'
},
filters: {
//在 filters节点下定义"过滤器"
capitalize(str) {
//把首字母转为大写的过滤器
return str.charAt(0).toUpperCase() + str.slice(1)
}
}
})
フィルター
フィルターは Vue が開発者向けに提供する機能で、テキストの書式設定によく使用されます。フィルターは、補間式と v-bind プロパティ バインディングの 2 つの場所で使用できます。
フィルタは JavaScript 式の最後に追加し、「パイプ文字」によって呼び出す必要があります。サンプル コードは次のとおりです。
2.2 プライベートフィルターとグローバルフィルター
フィルター ノードの下で定義されたフィルターは、現在の vm インスタンスによって制御される el 領域内でのみ使用できるため、「プライベート フィルター」と呼ばれます。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<div id="app">
<p :title="info">{
{message | capitalize}}</p>
</div>
<div id="app2">
<p>{
{abc|capitalize}}</p>
</div>
<script src="./lib/vue-2.6.12.js"></script>
<script>
const vm = new Vue({
el: '#app',
data: {
message: 'hello',
info: 'title info',
},
filters: {
capitalize(str) {
return str.charAt(0).toUpperCase() + str.slice(1)
}
}
})
</script>
<script>
const vm2 = new Vue({
el: '#app2',
data: {
abc: 'abc',
},
})
</script>
</body>
</html>
複数の Vue インスタンス間でフィルターを共有する場合は、次の形式でグローバル フィルターを定義できます。
//全局过滤器–独立于每个vm实例之外
// Vue.filter()方法接收两个参数
//第1个参数,是全局过滤器的""名字”
//第2个参数,是全局过滤器的""处理函数”
Vue.filter( ' capitalize", (str)=> {
return str.charAt(0).toUpperCase() + str.slice(1) + '~~'
})
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<div id="app">
<p :title="info">{
{message | capitalize}}</p>
</div>
<div id="app2">
<p>{
{abc|capitalize}}</p>
</div>
<script src="./lib/vue-2.6.12.js"></script>
<script>
Vue.filter('capitalize', (str) => {
return str.charAt(0).toUpperCase() + str.slice(1) + '~~'
})
</script>
<script>
const vm = new Vue({
el: '#app',
data: {
message: 'hello',
info: 'title info',
},
filters: {
capitalize(str) {
return str.charAt(0).toUpperCase() + str.slice(1)
}
}
})
</script>
<script>
const vm2 = new Vue({
el: '#app2',
data: {
abc: 'abc',
},
})
</script>
</body>
</html>
2.3 複数のフィルターを連続して呼び出す
フィルターは次のように連続して呼び出すことができます。
<!--把message 的值。交给 filterA进行处理-->
<!--把 filtcrA 处理的结果,再交给filterB进行处理-->
<!--最终把 filterB处理的结果,作为最终的值渲染到页面上 -->
{
{message | filterA | filterB }}
2.3 複数のフィルターを連続して呼び出す
サンプルコードは次のとおりです。
<!--串联调用多个过滤器-->
<p>{
{text | capitalize | maxLength}}</p>
// 全局过滤器–首字母大写
Vue.filter( ' capitalize", (str) => {
return str.charAt(O).touppercase() + str.slice(1) + '~-')
//全局过滤器–控制文本的最大长度
Vue.filter( 'maxLength". (str)=>{
if (str.length <= 10) return str
return str.slice(o,10)+ '...'
})
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<div id="app">
<p :title="info | capitalize">{
{message | capitalize | maxLength}}</p>
</div>
<script src="./lib/vue-2.6.12.js"></script>
<script>
Vue.filter('capitalize', (str) => {
return str.charAt(0).toUpperCase() + str.slice(1)
})
Vue.filter('maxLength', (str) => {
if (str.length <= 10) return str
return str.slice(0, 10) + '...'
})
</script>
<script>
const vm = new Vue({
el: '#app',
data: {
message: 'hello vue javascript',
info: 'title info',
},
})
</script>
</body>
</html>
2.4 フィルタパラメータの受け渡し
フィルターの本質は JavaScript 関数であるため、次の形式でパラメーターを受け取ることができます。
<!-- arg1和arg2是传递给filterA 的参数-->
<p>{
{message | filterAarg1, arg2)}}</p>
//过滤器处理函数的形参列表中:
//第一个参数。永远都是管道符前面待处理的值
//从第二个参数开始,才是调用过滤器时传递过来的arg1 和arg2参数Vue.filter( "filterA',(msg.arg1,arg2)=> {
//过滤器的代码逻辑...
})
2.4 フィルタパラメータの受け渡し
サンプルコードは次のとおりです。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<div id="app">
<p :title="info | capitalize">{
{message | capitalize | maxLength(5)}}</p>
</div>
<script src="./lib/vue-2.6.12.js"></script>
<script>
Vue.filter('capitalize', (str) => {
return str.charAt(0).toUpperCase() + str.slice(1)
})
Vue.filter('maxLength', (str, len = 10) => {
if (str.length <= len) return str
return str.slice(0, len) + '...'
})
</script>
<script>
const vm = new Vue({
el: '#app',
data: {
message: 'hello vue javascript',
info: 'title info',
},
})
</script>
</body>
</html>
2.5 フィルターの互換性
フィルターは vue 2.x および 1.x でのみサポートされており、フィルター関連の関数は vue 3.x では削除されています。
エンタープライズレベルのプロジェクト開発では:
vue のバージョン 2.x を使用している場合でも、フィルター関連の関数を使用できます。
プロジェクトが Vue のバージョン 3.x にアップグレードされている場合、当局は、計算されたプロパティまたはメソッドを使用して、削除されたフィルター関数を置き換えることを推奨しています。
特定の移行ガイドラインについては、vue 3.x の公式ドキュメントに記載されている手順を参照してください: https://v3.vuejs.org/guide/migration/filters.html#migration-strategy
ブランドリストケース
1.ケース効果
2. 使用されるナレッジポイント
Bootstrap 4.x 関連のナレッジポイント:
カード、フォーム、ボタン、テーブル
Vue の命令とフィルターに関連するナレッジポイント: 補間式、プロパティ バインディング、イベント バインディング、双方向データ バインディング、修飾子、条件付きレンダリング、リスト レンダリング、グローバル フィルター
3. 全体的な実装手順
①基本的なvueインスタンスを作成する
②vueをベースにテーブルデータをレンダリングする
③ブランド追加機能の実装
④ブランド削除機能を実装
⑤ブランドステータス変更機能の実装
3.1 基本的な vue インスタンスを作成する
ステップ 1: vue の js ファイルをインポートします。
ステップ 2: タグ内で el 領域を宣言します。
ステップ 3: vue インスタンス オブジェクトを作成します。
3.2 vueに基づいたテーブルデータのレンダリング
ステップ 1: v-for コマンドを使用して、テーブルのデータをループします。
ステップ 2: ブランドのステータスをスイッチ スイッチ エフェクトとしてレンダリングします。
Switchスイッチエフェクトの公式ドキュメントアドレス: https://v4.bootcss.com/docs/components/forms/#switches
ステップ 3: グローバル フィルターを使用して時間をフォーマットします。
グローバル フィルターを使用して時間をフォーマットします。
グローバル フィルターを使用して時間をフォーマットします。
3.3 ブランドの追加
ステップ 1: フォームのデフォルトの送信動作を防止します。
ステップ 2: 入力入力ボックスに対して v-model 双方向データ バインディングを実行します。 注: ブランド名属性フィールドはデータ データ内で宣言する必要があります。
ステップ 3: クリック イベント ハンドラー関数を [ブランドの追加] ボタンにバインドします。
ステップ 4: データで nextId 属性を宣言し (次に使用可能な ID 値を記録するために使用されます)、メソッドで addNewBrand イベント ハンドラーを宣言します。
ステップ 5: 入力ボックスの keyup イベントをリッスンし、.esc キー修飾子を使用してテキスト ボックスの内容をすばやくクリアします。
3.4 ブランドを削除する
ステップ 1: クリック イベント ハンドラー関数を削除されたリンクにバインドし、そのデフォルトの動作を防止します。
ステップ 2: 次のようにメソッド ノードで、removeBrand イベント処理関数を宣言します。
コンポーネントの基本
単一ページのアプリケーション
1. シングルページアプリケーションとは何ですか?
SPA と呼ばれるシングル ページ アプリケーション (英語名: Single Page Application) は、その名前が示すように、HTML ページが 1 つだけある Web Web サイトを指し、すべての機能と操作がこの 1 ページで完了します。
2. シングルページアプリケーションの特徴
シングルページ アプリケーションは、すべての機能を Web ページに制限し、Web ページの初期化時に対応するリソース (HTML、JavaScript、CSS) のみを読み込みます。
ページがロードされると、SPA はユーザーの操作によってページをリロードしたりジャンプしたりすることはありません。代わりに、JavaScript を使用して HTML のコンテンツを動的に変換し、ページとユーザー間の対話を実現します。
3. シングルページアプリケーションの利点
SPA シングル ページ アプリケーションの最も重要な利点は次の 3 つです。
① 優れたインタラクティブ体験
- 単一ページのアプリケーションのコンテンツを変更しても、ページ全体を再ロードする必要はありません。
- データの取得もAjax経由で非同期で取得
- ページ間のジャンプがなく、「白画面現象」も発生しません。
② フロントエンドとバックエンドの作業分離モードが優れている
- バックエンドは API インターフェイスの提供に重点を置いており、API インターフェイスの再利用が容易になります。
- フロントエンドはページ レンダリングに重点を置いているため、フロントエンド エンジニアリングの開発に役立ちます。
③サーバーへの負荷を軽減する
- サーバーはデータを提供するだけでページ合成やロジック処理は行わないため、スループット能力が数倍に向上します。
4. シングルページアプリケーションの欠点
どのテクノロジーにも独自の制限があり、SPA シングルページ アプリケーションの主な欠点は次のとおりです。
①最初の画面の読み込みが遅い
-
ルートの遅延読み込み
-
コード圧縮
-
CDNの高速化
-
ネットワーク伝送圧縮
②SEOにならない
- SSRサーバーサイドレンダリング
5. Vue SPA プロジェクトをすばやく作成する方法
Vue は、エンジニアリングされた SPA プロジェクトを迅速に作成する 2 つの方法を公式に提供しています。
①viteをベースにSPAプロジェクトを作成
②vue-cliを元にSPAプロジェクトを作成
素早く | ビュー-cli | |
---|---|---|
サポートされている vue バージョン | vue3.xのみをサポートします | 3.x および 2.x をサポート |
webpackベースなのでしょうか? | いいえ | はい |
走行速度 | 素早い | もっとゆっくり |
機能の完全性 | 小さくて精緻(徐々に完成) | 大きくて包括的 |
エンタープライズレベルの開発での使用が推奨されますか? | 現時点では推奨されません | エンタープライズレベルの開発での使用を推奨 |
viteの基本的な使い方
1. vite プロジェクトを作成する
vite に基づいて vue 3.x エンジニアリング プロジェクトを作成するには、次のコマンドを実行します。
npm install vite-app 项目名称
cd 项目名称
npm install
npm run dev
2. プロジェクトの構造を整理する
vite を使用して作成されたプロジェクト構造は次のとおりです。
-
node_modules ディレクトリは、サードパーティの依存関係パッケージを保存するために使用されます。
-
public はパブリック静的リソースディレクトリです
-
src はプロジェクトのソース コード ディレクトリです (プログラマが作成したすべてのコードはこのディレクトリに配置する必要があります)
-
.gitignore は Git の無視ファイルです
-
index.html は、SPA シングル ページ アプリケーション内の唯一の HTML ページです。
-
package.json はプロジェクトのパッケージ管理構成ファイルです
src プロジェクトのソース コード ディレクトリには、次のファイルとフォルダーが含まれます。
で:
-
アセット ディレクトリは、プロジェクト内のすべての静的リソース ファイル (CSS、フォントなど) を保存するために使用されます。
-
コンポーネント ディレクトリは、プロジェクト内のすべてのカスタム コンポーネントを保存するために使用されます。
-
App.vue はプロジェクトのルート コンポーネントです
-
Index.css はプロジェクトのグローバル スタイル シート ファイルです。
-
main.js はプロジェクト全体のパッケージ化エントリ ファイルです。
3. viteプロジェクトの運営プロセス
エンジニアリング プロジェクトでは、vue が行うことは非常に単純です。main.js を介して、index.html の指定された領域に App.vue をレンダリングします。
で:
① App.vue を使用してレンダリングするテンプレート構造を記述します。
②index.html内にel領域を確保する必要がある
③ main.js は、index.html で確保された領域に App.vue をレンダリングします。
3.1 App.vue でテンプレート構造を記述する
App.vue のデフォルトのコンテンツをクリアし、次のテンプレート構造を記述します。
<template>
<h1>这是app.vue根组件</h1>
<h3>abc</h3>
</template>
3.2index.htmlでel領域を確保する
Index.html ページを開き、el 領域が予約されていることを確認します。
<body>
<!-- id 为app的div元素,就是将来vue要控制的区域 -->
<div id="app"></div>
<script type="module" src="/src/main.js"></script>
</body>
3.3 main.js でのレンダリング
vue 3.x の標準的な使用法に従って、App.vue のテンプレート コンテンツをindex.html ページの el 領域にレンダリングします。
// 1.从 vue中按需导入 createApp函数
import { createApp } from 'vue'
// 2.导入待渲染的App 组件
import App from './App.vue'
//3.调用createApp()函数,返回值是"单页面应用程序的实例",
// 用常量 spa_app进行接收,
const app = createApp(App)
//4.调用 mount方法,把App 组件的模板结构,渲染到指定的el区域中
app.mount('#app')
コンポーネント開発のアイデア
1. コンポーネント開発とは何ですか?
コンポーネント開発とは、カプセル化の考え方に基づいてページの再利用可能な部分をコンポーネントにカプセル化することを指し、これによりプロジェクトの開発とメンテナンスが容易になります。例: http://www.ibootstrap.cn/ に示されているエフェクトは、コンポーネント開発のアイデアと一致しています。ユーザーはコンポーネントをドラッグ アンド ドロップすることで、ページ レイアウト構造をすばやく生成できます。
2. コンポーネント開発のメリット
フロントエンド コンポーネント開発の利点は、主に次の 2 つの側面に反映されます。
-
フロントエンドコードの再利用性と柔軟性の向上
-
開発効率の向上とその後のメンテナンス性の向上
3. vueでのコンポーネント開発
Vue は、コンポーネントベースの開発を完全にサポートするフレームワークです。vue で指定されたコンポーネントのサフィックス名は .vue です。以前に見つけた App.vue ファイルは、本質的には vue コンポーネントです。
vueコンポーネントの構成
1.Vueコンポーネントの構造
各 .vue コンポーネントは、次の 3 つの部分で構成されます。
-
テンプレート -> コンポーネントのテンプレート構造
-
スクリプト -> コンポーネントの JavaScript 動作
-
スタイル -> コンポーネントのスタイル
その中で、各コンポーネントにはテンプレート テンプレート構造が含まれている必要がありますが、スクリプトの動作とスタイルはオプションのコンポーネントです。
2. コンポーネントのテンプレートノード
Vue では、各コンポーネントに対応するテンプレート構造を <template> ノードで定義する必要があると規定しています。
<template>
<!-- 当前组件的DOM结构,需要定义到template标签的内部-->
</template>
注: <template> は vue によって提供されるコンテナ タグです。これはラッピングの役割のみを果たし、実際の DOM 要素としてレンダリングされません。
2.1 テンプレートでのディレクティブの使用
コンポーネントの <template> ノードでは、開発者が現在のコンポーネントの DOM 構造をレンダリングできるように、以前に学習した命令構文がサポートされています。コード例は次のとおりです。
<template>
<h1>这是 App 根组件</h1>
<!--使用i该插值表达式-->
<p>生成一个随机数字: {
{(Math.random()*10).toFixed(2)}}</p>
<!--使用v-bind 属性绑定-->
<p :title="new Date().toLocaleTimeString()">vue.js</p>
<!--属性v-on事件绑定-->
<button eclick="showInfo">按钮</button>
</template>
2.2 テンプレート内のルート ノードを定義する
vue 2.x バージョンでは、<template> ノード内の DOM 構造は単一のルート ノードのみをサポートします。
<template>
<div>
<h1>这是app.vue根组件</h1>
<h3>abc</h3>
</div>
</template>
ただし、vue 3.x バージョンでは、<template> は複数のルート ノードの定義をサポートします。
<template>
<h1>这是app.vue根组件</h1>
<h3>abc</h3>
</template>
3. コンポーネントのスクリプトノード
Vue では、コンポーネント内の <script> ノードはオプションであると規定されており、開発者はコンポーネントの JavaScript ビジネス ロジックを <script> ノードにカプセル化できます。<script> ノードの基本構造は次のとおりです。
<script>
// 今后,组件相关的data数据、methods方法等,
// 都需要定义到export default所导出的对象中。
export default {}
</script>
3.1 スクリプト内の名前ノード
name ノードを使用して現在のコンポーネントの名前を定義できます。
<script>
// 今后,组件相关的data数据、methods方法等,
// 都需要定义到export default所导出的对象中。
export default {
// name属性指向的是当前组件的名称《建议:每个单词的首字母大写>
name:'MyApp'
}
</script>
プロジェクトのデバッグに vue-devtools を使用する場合、カスタマイズされたコンポーネント名により各コンポーネントを明確に区別できます。
3.2 スクリプト内のデータノード
vue コンポーネントのレンダリング中に必要なデータは、データ ノードで定義できます。
<script>
// 今后,组件相关的data数据、methods方法等,
// 都需要定义到export default所导出的对象中。
export default {
// name属性指向的是当前组件的名称《建议:每个单词的首字母大写>
name:'MyApp',
data() {
return {
username:'zs',
}
}
}
</script>
コンポーネント内のデータは関数である必要があります
Vue では、コンポーネント内のデータは関数である必要があり、データ オブジェクトを直接指すことはできないと規定しています。したがって、コンポーネントでデータ データ ノードを定義する場合、次の方法は間違っています。
data:{
//组件中,不能直接让data 指向一个数据对象(会报错)
count:0
}
3.3 スクリプト内のメソッドノード
コンポーネント内のイベント処理関数はメソッドノードで定義する必要があります。サンプルコードは次のとおりです。
<template>
<h1>这是app.vue根组件</h1>
<h3>abc ---{
{username}}</h3>
<p>count值是--{
{count}}</p>
<button @click="addCount">+1</button>
</template>
<script>
// 今后,组件相关的data数据、methods方法等,
// 都需要定义到export default所导出的对象中。
export default {
// name属性指向的是当前组件的名称《建议:每个单词的首字母大写>
name:'MyApp',
data() {
return {
count:0,
}
},
methods: {
addCount() {
this.count++
},
},
}
</script>
4. コンポーネントのスタイルノード
Vue では、コンポーネント内の <style> ノードはオプションであると規定されており、開発者は <style> ノードにスタイルを記述して、現在のコンポーネントの UI 構造を美しくできます。<script> ノードの基本構造は次のとおりです。
<style lang="css">
h1{
color:red
}
</style>
<style> タグの lang="css" 属性はオプションであり、使用されるスタイル言語を示します。デフォルトでは、一般的な CSS 構文のみがサポートされており、オプションの値には、less、scss などが含まれます。
4.1 スタイルでサポートする構文を少なくする
より少ない構文を使用してコンポーネントのスタイルを記述したい場合は、次の 2 つの手順で構成できます。
① npm installless -D コマンドを実行して依存関係パッケージをインストールし、less 構文のコンパイル サポートを提供します。 ② lang="less" 属性を <style> タグに追加して、less 構文を使用してコンポーネントのスタイルを記述します。
<template>
<h1>这是<i>App.vue</i>根组件</h1>
<h3>abc ---{
{username}}</h3>
<p>count值是--{
{count}}</p>
<button @click="addCount">+1</button>
</template>
<style lang="less">
h1{
color:red;
i {
color: blue;
}
}
</style>
<script>
// 今后,组件相关的data数据、methods方法等,
// 都需要定义到export default所导出的对象中。
export default {
// name属性指向的是当前组件的名称《建议:每个单词的首字母大写>
name:'MyApp',
data() {
return {
count:0,
}
},
methods: {
addCount() {
this.count++
},
},
}
</script>
コンポーネントの基本的な使い方
1. コンポーネントの登録
コンポーネントは相互に参照できます。たとえば、次のようになります。
vue のコンポーネントの参照原則: 最初に登録してから使用します。
1.1 コンポーネントを登録する 2 つの方法
Vue にコンポーネントを登録するには、「グローバル登録」と「ローカル登録」の 2 つの方法があります。そのうちの 1 つは次のとおりです。
- グローバルに登録されたコンポーネントは、どのグローバル コンポーネントでも使用できます。
- 部分的に登録されたコンポーネントは、現在登録されている範囲内でのみ使用できます。
1.2 コンポーネントをグローバルに登録する
// 1.从 vue中按需导入 createApp函数
import {
createApp } from 'vue'
// 2.导入待渲染的App 组件
import App from './App.vue'
//1.导入需要被全局注册的组件
import Swiper from './components/01-globalReg/Swiper.vue'
import Test from './components/01-globalReg/Test.vue'
//3.调用createApp()函数,返回值是"单页面应用程序的实例"
const app = createApp(App)
//2.调用app . component()方法全局注册组件
app.component('my-swiper', Swiper)
app.component('my-test', Test)
//4.调用 mount方法,把App 组件的模板结构,渲染到指定的el区域中
app.mount('#app')
1.3 グローバル登録コンポーネントの使用
app.component() メソッドを使用して登録されたグローバル コンポーネントは、次のようにラベルの形式で直接使用できます。
<template>
<h1>这是<i>App.vue</i>根组件</h1>
<h3>abc ---{
{username}}</h3>
<p>count值是--{
{count}}</p>
<button @click="addCount">+1</button>
<my-swiper></my-swiper>
<my-test></my-test>
</template>
1.4 部分的に登録されたコンポーネント
<template>
<h1>这是<i>App.vue</i>根组件</h1>
<h3>abc ---{
{username}}</h3>
<p>count值是--{
{count}}</p>
<button @click="addCount">+1</button>
<my-swiper></my-swiper>
<my-search></my-search>
</template>
<script>
import Search from './components/02-privateReg/Search.vue'
export default{
components : {
'my-search': Search
}
}
</script>
1.5 グローバル登録とローカル登録の違い
グローバルに登録されたコンポーネントは、どのグローバル コンポーネントでも使用できます。
部分的に登録されたコンポーネントは、現在登録されている範囲内でのみ使用できます。
アプリケーションシナリオ:
開発中に一部のコンポーネントが頻繁に使用される場合は、グローバル登録をお勧めします。
一部のコンポーネントが特定の状況でのみ使用される場合は、ローカル登録をお勧めします。
1.6 コンポーネント登録時の名前の大文字と小文字について
コンポーネントを登録する場合、コンポーネント登録名を定義するには 2 つの方法があります。
①ケバブケース命名法(my-swiperやmy-searchなどの通称ダッシュ命名法)を使用する
② PascalCase 命名法を使用する (通称 Pascal 命名法、または MySwiper や MySearch などの大きなキャメルケース命名法と呼ばれます)
ダッシュ命名法の特徴:
- ダッシュ名に厳密に従って使用する必要があります
パスカルの命名法の特徴:
- Pascal 名に従って厳密に使用することも、ダッシュ名として使用することもできます。
注: 実際の開発では、より適用しやすい Pascal 命名法を使用してコンポーネントの名前を登録することをお勧めします。
1.7 name 属性を使用してコンポーネントを登録する
コンポーネントの登録時に、コンポーネントの登録名を直接指定するだけでなく、コンポーネントの name 属性を登録コンポーネントの名前として使用することもできます。サンプル コードは次のとおりです。
<template>
<h3>Swiper轮播图</h3>
</template>
<script>
export default {
name:'MySwiper'
}
</script>
import Swiper from './components/01-globalReg/Swiper.vue'
app.component(Swiper,name,Swiper)
//等同于app.component('my-swiper', Swiper)
2. コンポーネント間のスタイルの競合
デフォルトでは、.vue コンポーネントに記述されたスタイルはグローバルに有効になるため、複数のコンポーネント間でスタイルの競合が発生しやすくなります。コンポーネント間のスタイル競合の根本原因は次のとおりです。
① シングルページアプリケーションでは、すべてのコンポーネントの DOM 構造は一意のindex.html ページに基づいてレンダリングされます。
② 各コンポーネントのスタイルは、index.html ページ全体の DOM 要素に影響します。
2.1 考え方: コンポーネントのスタイルの競合の問題を解決する方法
各コンポーネントに一意のカスタム属性を割り当てます。コンポーネント スタイルを記述するときは、属性セレクターを使用してスタイルの範囲を制御します。サンプル コードは次のとおりです。
<template>
<div class="container" data-v-001>
<h3 data-v-001>Swiper轮播图</h3>
</div>
</template>
<script>
export default {
name:'MySwiper'
}
</script>
<style>
.container[data-v-001] {
border:1px solid red;
}
</style>
<template>
<div data-v-002>
<h1 data-v-002>这是App.vue根组件</h1>
<p data-v-002> app中的p标签</p>
<p data-v-002>app中的p标签</p>
<hr data-v-002>
<my-list data-v-002></my-list>
</div>
</template>
<script>
import MyList from './list.vue'
export default {
name:'MyApp',
components: {
MyList
}
}
</script>
<style lang="less">
p[data-v-002] {
color: aqua;
}
</style>
<template>
<div data-v-003>
<h3 data-v-003>这是list.vue组件</h3>
<p data-v-003>这是list.vue中的p标签</p>
<p data-v-003>这是list.vue中的p标签</p>
</div>
</template>
<script>
export default {
name:'MyList',
}
</script>
2.2 スタイルノードのスコープ属性
開発効率と開発エクスペリエンスを向上させるために、Vue はスタイル ノードにスコープ付き属性を提供し、コンポーネント間のスタイルの競合を防ぎます。
<template>
<div >
<h3>这是list.vue组件</h3>
<p>这是list.vue中的p标签</p>
<p>这是list.vue中的p标签</p>
</div>
</template>
<script>
export default {
name:'MyList',
}
</script>
<style lang="less" scoped></style>>
2.3 /深い/スタイルの浸透
スコープ付き属性が現在のコンポーネントのスタイル ノードに追加された場合、現在のコンポーネントのスタイルはそのサブコンポーネントには影響しません。特定のスタイルを子コンポーネントに適用したい場合は、/deep/ Depth セレクターを使用できます。
<style lang="less" scoped>
p {
color: aqua;
}
/deep/.title {
color:aquamarine;
// 加上 /deep/时,生成的选择器格式为[data-v-052242de] .title
}
注: /deep/ は、vue2.x でスタイルの浸透を実現するためのソリューションです。vue3.x では /deep/ の代わりに deep() を使用することをお勧めします。
3. コンポーネントの小道具
コンポーネントの再利用性を向上させるには、vue コンポーネントをカプセル化するときに次の原則に従う必要があります。
コンポーネントの DOM 構造とスタイルは可能な限り再利用する必要があります。
コンポーネントに表示されるデータは、可能な限りコンポーネントのユーザーが提供する必要があります。
ユーザーがコンポーネントに表示するデータを提供しやすくするために、vue コンポーネントは props の概念を提供します。
3.1 コンポーネント prop とは
プロップはコンポーネントのカスタム プロパティであり、コンポーネントのユーザーは、サブコンポーネントで内部的に使用するために、プロップを通じてデータをサブコンポーネントに渡すことができます。コード例は次のとおりです。
<!--通过自定义props,把文章的标题和作者,传递到 my-article 组件中 -->
<my-article title="面朝大海,春暖花开 author="海子"></my-article>
props の役割: 親コンポーネントは、表示するデータを props を介して子コンポーネントに渡します。
小道具の利点: コンポーネントの再利用性が向上します。
//App.vue
<template>
<div>
<h1>这是App.vue根组件</h1>
<hr>
<my-article title="面朝大海,春暖花开" author="海子"></my-article>
</div>
</template>
<script>
import MyArticle from './Article.vue'
export default {
name:'MyApp',
components: {
MyArticle
}
}
</script>
//----------Article.vue
<template>
<div>
<h1>标题:{
{title}}</h1>
<h3>作者:{
{author}}</h3>
</div>
</template>
<script>
export default {
name:'MyArticle',
// 外界可以传递指定的数据到当前的组件中
props:['title','author']
}
</script>
3.2 コンポーネント内で props を宣言する
vue コンポーネントをカプセル化するときに、動的なデータ項目を props カスタム プロパティとして宣言できます。カスタム プロパティは、現在のコンポーネントのテンプレート構造で直接使用できます。サンプルコードは次のとおりです。
<!-- my-article 组件的定义如下:-->
<tcmplate>
<h3>标题:{
{title}}</h3><h5>作者: {
{author}}</h5>
</template>
<script>
export default {
props: ['title' ,"author"],
//父组件传递给my-article组件的数据,必须在props节点中声明
}
</script>
3.3 未宣言のプロパティは使用できない
親コンポーネントが宣言されていない props 属性を子コンポーネントに渡す場合、これらの属性は無視され、子コンポーネントは使用できません。サンプル コードは次のとおりです。
<my-article title="致橡树”author="舒婷"></my-article>
<template>
<h3>标题: {
{title}}</h3>
<h5>作者:{
{author}}</h5>
</template>
export default {
props: ['title'],// author属性没有声明,因此子组件中无法访问到 author 的值
}
</script>
3.4 props の値を動的にバインドする
v-bind 属性バインディングを使用して、props 値をコンポーネントに動的にバインドできます。サンプルコードは次のとおりです。
<!--通过v-bind属性绑定,为title 动态赋予一个变量的值-->
<!--通过v-bind属性绑定,为author 动态赋予一个表达式的值-->
<my-article :title="info.title" :author='post by' + info. author"></my-article>
<template>
<div>
<h1>这是App.vue根组件</h1>
<hr>
<my-article :title="info.title" :author="'post by' +info.author"></my-article>
</div>
</template>
<script>
import MyArticle from './Article.vue'
export default {
name:'MyApp',
data() {
return {
info:{
title:'abc',
author:'123',
}
}
},
components: {
MyArticle
}
}
</script>
3.5 小道具の大文字と小文字の命名
props 属性の名前が「camelCase (キャメルケース命名)」を使用してコンポーネント内で宣言されている場合、属性の値をそれにバインドする方法は 2 つあります。
<template>
<p>发布时问:iipubTime}}</p>
</template>
<script>
export default {
props: [ "pubTime '],
//采用“驼峰命名法"为当前的组件声明了 pubTime属性
</ script>
<!--既可以直接使用“驼峰命名”的形式为组件绑定属性的值-->
<my-article pubTime="1989"></my-article>
<!--也可以使用其等价的“短横线分隔命名”的形式为组件绑定属性的值-->
<my-article pub-time=1989"></my-article>
4. クラスとスタイルのバインディング
実際の開発では、要素のスタイルを動的に操作する必要が生じることがよくあります。したがって、vue を使用すると、開発者は v-bind 属性バインディング命令を通じて、クラス属性の値とインライン スタイルを要素に動的にバインドできます。
4.1 HTML クラスを動的にバインドする
三項式を使用して、クラス名を要素に動的にバインドできます。サンプルコードは次のとおりです。
<h3 class=""thin" :class="isItalic ? 'italic' : """">MyDeep组件</h3>
<button @click="isItalic=!isItalic">Toggle Italic</button>
data() {
rcturn { isItalic: true }
.thin { //字体变细
font-weight: 200;
}
.italic { //倾斜字体
font-style: italic;
}
<template>
<div>
<h3 class="thin" :class="isItalic ? 'italic' : '' "> MyStyle组件</h3>
<button @click="isItalic = !isItalic">Toggle Itali</button>
</div>
</template>
<script>
export default {
name:'MyStyle',
data() {
return {
isItalic:true,
}
}
}
</script>
<style lang="less">
// 字体粗细
.thin {
font-weight:200 ;
}
.italic {
// 倾斜字体
font-style: italic;
}
</style>
4.2 配列構文を使用した HTML クラスのバインド
要素が複数のクラスのクラス名を動的にバインドする必要がある場合は、配列構文形式を使用できます。
<h3 class="thin" :class="[isItalic ? 'italic' : "",isDelete ? 'delete' : ""]">
MyDcep 组件
</h3>
<button eclick="isItalic-!isItalic">Toggle Italic</button><button eclickm"isDelete-!isDelete">Toggle Delete</button>
data(){
return{
isItalic:true,
isDelete:false,
}
}
<template>
<div>
<!-- <h3 class="thin" :class="isItalic ? 'italic' : '' "> MyStyle组件</h3> -->
<h3 class="thin" :class="[isItalic ? 'italic' : '',isDelete ? 'delete' : '']"> MyStyle组件</h3>
<button @click="isItalic = !isItalic">Toggle Itali</button>
<br>
<button @click="isDelete = !isDelete">Toggle delete</button>
</div>
</template>
<script>
export default {
name:'MyStyle',
data() {
return {
isItalic:false,
isDelete:false
}
}
}
</script>
<style lang="less">
// 字体粗细
.thin {
font-weight:200 ;
}
.italic {
// 倾斜字体
font-style: italic;
}
.delete {
text-decoration: line-through;
}
</style>
4.3 HTML クラスとオブジェクト構文のバインド
配列構文を使用してクラスを動的にバインドすると、テンプレート構造が肥大化するという問題が発生します。この時点で、オブジェクト構文を使用して以下を簡素化できます。
<h3 class="thin" :class="[isItalic ? 'italic' : '',isDelete ? 'delete' : '']"> MyStyle组件</h3>
<button @click="isItalic = !isItalic">Toggle Itali</button>
<br>
<button @click="isDelete = !isDelete">Toggle delete</button>
data() {
return {
classObj: {
//对象中,属性名是 class类名,值是布尔值
italic:false,
delete:false,
}
}
}
<template>
<div>
<!-- <h3 class="thin" :class="isItalic ? 'italic' : '' "> MyStyle组件</h3> -->
<!-- <h3 class="thin" :class="[isItalic ? 'italic' : '',isDelete ? 'delete' : '']"> MyStyle组件</h3>
<button @click="isItalic = !isItalic">Toggle Itali</button>
<br>
<button @click="isDelete = !isDelete">Toggle delete</button> -->
<h3 class="thin" :class="classObj"> MyStyle组件</h3>
<button @click="classObj.italic = !classObj.italic">Toggle Itali</button>
<br>
<button @click="classObj.delete = !classObj.delete">Toggle delete</button>
</div>
</template>
<script>
export default {
name:'MyStyle',
data() {
return {
isItalic:false,
isDelete:false,
classObj:{
//对象中,属性名是 class类名,值是布尔值
italic:false,
delete:false,
},
}
}
}
</script>
<style lang="less">
// 字体粗细
.thin {
font-weight:200 ;
}
.italic {
// 倾斜字体
font-style: italic;
}
.delete {
text-decoration: line-through;
}
</style>
4.4 オブジェクト構文を使用したインライン スタイルのバインド
:style のオブジェクト構文は非常に直感的です。CSS に非常によく似ていますが、実際には JavaScript オブジェクトです。CSS プロパティ名は、キャメルケースまたはケバブケースで指定できます (引用符で囲むことを忘れないでください)。
<div :style="{color: active,fontSize: fsize + 'px",'background-color ': bgcolor)">
vue组件
</div>
<button @click="fsizc += 1">字号 + 1</button>
<button @click="fsize -= 1">字号 - 1</button>
data(){
return {
active: 'red',
fsize: 30,
bgcolor: "pink" ,
}
}
<template>
<div>
<!-- <h3 class="thin" :class="isItalic ? 'italic' : '' "> MyStyle组件</h3> -->
<!-- <h3 class="thin" :class="[isItalic ? 'italic' : '',isDelete ? 'delete' : '']"> MyStyle组件</h3>
<button @click="isItalic = !isItalic">Toggle Itali</button>
<br>
<button @click="isDelete = !isDelete">Toggle delete</button> -->
<h3 class="thin" :class="classObj"> MyStyle组件</h3>
<button @click="classObj.italic = !classObj.italic">Toggle Itali</button>
<br>
<button @click="classObj.delete = !classObj.delete">Toggle delete</button>
<hr>
<!-- font-szie要写成fontSzie -->
<div :style="{color:active, fontSize:fsize+'px','background-color':bgcolor}">vue根组件</div>
<button @click="fsize+=1">字号 + 1</button>
<button @click="fsize-=1">字号 - 1</button>
</div>
</template>
<script>
export default {
name:'MyStyle',
data() {
return {
isItalic:false,
isDelete:false,
classObj:{
//对象中,属性名是 class类名,值是布尔值
italic:false,
delete:false,
},
//高亮时的文本颜色
active: 'red',
fsize: 30,
bgcolor: "pink" ,
}
}
}
</script>
<style lang="less">
// 字体粗细
.thin {
font-weight:200 ;
}
.italic {
// 倾斜字体
font-style: italic;
}
.delete {
text-decoration: line-through;
}
</style>
パッケージ化されたコンポーネントの場合
1. ケース効果の梱包要件:
①ユーザーがタイトルタイトルをカスタマイズできるようにする
②ユーザーがbgcolorの背景色をカスタマイズできるようにする
③ユーザーが文字色をカスタマイズできるようにする
④ MyHeader コンポーネントは固定してページの上部に配置する必要があり、z-index は 999 に等しくなります。
使用例は以下のとおりです。
2. 使用されるナレッジポイント
コンポーネントのカプセル化と登録
小道具
スタイルバインディング
3. 全体的な実装手順
MyHeaderコンポーネントを作成する
MyHeader コンポーネントの基本構造をレンダリングする
AppコンポーネントにMyHeaderコンポーネントを登録して使用する
props を介してコンポーネントにデータを渡す
小道具の検証
1. 小道具検証とは何ですか?
不正なデータの問題を防ぐために、コンポーネントをカプセル化するときに外部から渡される props データの正当性を検証することを指します。
配列型の props ノードを使用するデメリット: 各 props に特定のデータ型を指定できません。
2. オブジェクトタイプの Props ノード
オブジェクト型の props ノードを使用すると、各 prop のデータ型を確認できます。
//app.vue
<template>
<div>
<h1>App组件</h1>
</div>
<hr>
<!-- <my-count count="abc" :state="3"></my-count> -->
<my-count count=12 :state="true"></my-count>
</template>
<script>
import MyCount from './count.vue'
export default {
name: 'MyApp',
components: {
MyCount
}
}
</script>
//count.vue
<template>
<div>
<p>数量:{
{count}}</p>
<p>状态:{
{state}}</p>
</div>
</template>
<script>
export default {
name:'MyCount',
// props:['count','state']
props: {
count:Number,
state:Boolean
}
}
</script>
<style lang="less" scoped></style>
3. 小道具の検証
オブジェクト タイプの props ノードは、次のようなさまざまなデータ検証スキームを提供します。
① 基本的な型チェック
② 複数の種類が考えられる
③必須項目の確認
④ 属性のデフォルト値
⑤カスタム検証機能
3.1 基本的な型チェック
コンポーネントの prop 属性の基本検証タイプを直接指定して、コンポーネントのユーザーが間違ったタイプのデータをコンポーネントにバインドしないようにすることができます。
export default {
props: { //支持的8种基础关型
propA: string, //字符串类型
propB: Number, //数字类型
propC: Boolean, //布尔值类型
propD: Array, //数组类型
propE: Object, //对象类型
propF: Date, //日期类型
propG: Function,//函数类型
propH: Symbol //符号类型
}
}
3.2 複数の可能なタイプ
特定の prop 属性値の型が一意でない場合は、配列の形式で複数の可能な型を指定できます。サンプル コードは次のとおりです。
export default {
props: {
/// propA属性的值可以是"字符串"或"数字"
propA:[String,Number],
},
}
3.3 必須フィールドの確認
コンポーネントの prop 属性が必要な場合、コンポーネントのユーザーは属性の値をコンポーネントに渡す必要があります。このとき、次の方法で必須フィールドとして設定できます。
export default {
props: {
// 通过“配置对象"的形式,来定义propB属性的“验证规则”
propB:{
type:String,//当前属性的值必须是String字符串类型
erquired:true //当前属性的值是必填项,如果使用者没指定 propB属性的值,则在终端进行警告提示
},
},
}
<template>
<div>
<p>数量:{
{count}}</p>
<p>状态:{
{state}}</p>
</div>
</template>
<script>
export default {
name:'MyCount',
// props:['count','state']
props: {
count:{
type:[String,Number],
required:true
},
state:Boolean,
info:[String,Number]
}
}
</script>
<style lang="less" scoped></style>
3.4 属性のデフォルト値
コンポーネントをカプセル化するときに、prop 属性のデフォルト値を指定できます。サンプルコードは次のとおりです。
export default {
props: {
// 通过“配置对象"的形式,来定义propB属性的“验证规则”
propC:{
type:Number,
default:100 //如果使用者没有指定propC的值,则propC属性的默认值为100
},
},
}
3.5 カスタム検証機能
コンポーネントをカプセル化するときに、prop 属性のカスタム検証関数を指定して、prop 属性の値をより正確に制御できます。
export default {
props: {
// 通过“配置对象"的形式,来定义propB属性的“验证规则”
propD:{
//通过 validator函数,对propD属性的值进行校验,“属性的值"可以通过形参value进行接收
validator(value){
//propD属性的值,必须匹配下列字符串中的一个
// validator函数的返回值为true表示验证通过,false表示验证失败
return [ "success", "warning". "danger " ].indexOf(value) !== -1
},
},
},
}
計算されたプロパティ
1. 計算プロパティとは何ですか?
計算プロパティは基本的に、データの変更をリアルタイムで監視し、コンポーネントが DOM をレンダリングするときに使用する計算された新しい値を返す関数です。
2. 計算プロパティの宣言方法
計算プロパティは、コンポーネントの計算オプションで関数の形式で宣言する必要があります。サンプル コードは次のとおりです。
<input type='text' v-model.nmuber='count'/>
<p>{
{count}} 乘以2的值为:{
{plus}}</p>
data() {
return {count:1}
},
computed: {
plus() {
//计算属性。监听 data中 count值的变化,自动计算出count * 2 之后的新值
return this.count * 2
},
}
注: 計算プロパティは計算の結果を取得することに重点を置いているため、計算プロパティには戻り値が必要です。
<template>
<div>
<input type="text" v-model.number="count">
<p>{
{count}} 乘以2的值为:{
{plus}}</p>
</div>
</template>
<script>
export default {
name: 'MyCount',
data() {
return {
count:1,
}
},
computed:{
plus() {
return this.count * 2
}
}
}
</script>
3. 計算プロパティ使用時の注意点
① 計算属性は計算ノードで定義する必要があります
② 計算される属性は関数関数でなければなりません
③ 計算されたプロパティには戻り値が必要です
④ 計算された属性は通常の属性として使用する必要があります
4. 計算されたプロパティとメソッド
メソッドと比較して、計算プロパティは計算結果をキャッシュし、計算プロパティの依存関係が変更された場合にのみ計算結果を再計算します。したがって、計算されたプロパティのパフォーマンスが向上します。
5. 計算されたプロパティのケース
ケース要件、計算されたプロパティを使用した動的計算:
①チェックした商品の総数
②選択した商品の合計金額
③決済ボタンの無効状態
カスタムイベント
1. カスタム イベントとは何ですか?
コンポーネントをカプセル化する場合、コンポーネントのユーザーがコンポーネント内の状態の変化を監視できるようにするには、コンポーネントのカスタム イベントを使用する必要があります。
2. カスタムイベントを使用するための 3 つのステップ
コンポーネントをカプセル化する場合:
①カスタムイベントを宣言する
② カスタムイベントをトリガーする
コンポーネントを使用する場合:
③カスタムイベントを聞く
2.1 カスタム イベントを宣言する
開発者がカスタム コンポーネント用にカプセル化したカスタム イベントは、事前に Emits ノードで宣言する必要があります。サンプル コードは次のとおりです。
<template>
<h3>Counter组件</h3>
<button> +1 </button>
</template>
<script>
export default {
//my-counter组件的自定义事件,必须事先声明到 emits节点中
emits:['change']
}
</script>
2.2 カスタム イベントをトリガーする
放出ノードの下で宣言されたカスタム イベントは、 this.$emit('カスタム イベントの名前') メソッドを通じてトリガーできます。サンプル コードは次のとおりです。
<template>
<h3>Counter组件</h3>
<button @click="onBtnClick"> +1 </button>
</template>
<script>
export default {
//my-counter组件的自定义事件,必须事先声明到 emits节点中
emits:['change'],
methods: {
onBtnClick() {
this.$emit('change')
//当点击+1按钮时,调用this.$cmitO)方法,触发自定义的changc事件
}
}
}
</script>
2.3 カスタム イベントのリッスン
カスタム コンポーネントを使用する場合、v-on の形式でカスタム イベントをリッスンできます。サンプルコードは次のとおりです。
<my-counter @change='getCount'>
methods: {
getCount() {
console.log('监听到了count值的变化')
}
}
//App.vue
<template>
<div>
<h1>app根组件</h1>
</div>
<hr>
<my-counter @count-change="getCount"></my-counter>
</template>
<script>
import MyCounter from './Counter.vue'
export default {
name:'MyApp',
methods:{
getCount() {
console.log('触发了countChange自定义事件');
}
},
components:{
MyCounter,
}
}
</script>
<style>
</style>
//Counter.vue
<template>
<div>Count的值是:{
{count}}</div>
<button @click="add"> +1</button>
</template>
<script>
export default {
name:'MyCounter',
//声明自定义事件
emits:['countChange'],
data() {
return {
count:0,
}
},
methods:{
add() {
this.count++
// this .$emito触发自定义事件
this.$emit('countChange')
}
}
}
</script>
<style>
</style>
3. カスタムイベントパラメータの受け渡し
this.$emit() メソッドを呼び出してカスタム イベントをトリガーする場合、2 番目のパラメーターを通じてカスタム イベントのパラメーターを渡すことができます。サンプル コードは次のとおりです。
<template>
<h3>Counter组件</h3>
<button @click="onBtnClick"> +1 </button>
</template>
<script>
export default {
//my-counter组件的自定义事件,必须事先声明到 emits节点中
emits:['change'],
methods: {
onBtnClick() {
this.$emit('change',this.count)
//触发白定义事件时,通过第二个参数传参
},
},
}
</script>
<template>
<div>
<h1>app根组件</h1>
</div>
<hr>
<my-counter @count-change="getCount"></my-counter>
</template>
<script>
import MyCounter from './Counter.vue'
export default {
name:'MyApp',
methods:{
getCount(val) {
console.log('触发了countChange自定义事件',val);
}
},
components:{
MyCounter,
}
}
</script>
<style>
</style>
<template>
<div>Count的值是:{
{count}}</div>
<button @click="add"> +1</button>
</template>
<script>
export default {
name:'MyCounter',
//声明自定义事件
emits:['countChange'],
data() {
return {
count:0,
}
},
methods:{
add() {
this.count++
// this .$emito触发自定义事件
this.$emit('countChange',this.count)
}
}
}
</script>
<style>
</style>
コンポーネントの v-model
1. コンポーネントで v-model を使用する必要があるのはなぜですか?
v-model は双方向のデータ バインディング命令であり、コンポーネントの内部と外部のデータの同期を維持する必要がある場合、コンポーネントで v-model 命令を使用できます。概略図は次のとおりです。
- 外部データの変更はカウンター コンポーネントに自動的に同期されます。
- カウンタ コンポーネント内のデータの変更も、外部の世界に自動的に同期されます。
2. コンポーネントで v-model を使用する手順
① 親コンポーネントは、v-bind: 属性バインディングを通じて子コンポーネントにデータを渡します。
②子コンポーネントでは、親コンポーネントから渡されたデータをpropsで受け取ります。
<template>
<div>App根组件------{
{count}}</div>
<button @click="count += 1">+1</button>
<hr>
<my-counter :number="count"></my-counter>
</template>
<script>
import MyCounter from './Counter.vue'
export default {
name:"MyApp",
data() {
return {
count:0,
}
},
components: {
MyCounter
}
}
</script>
<style>
</style>
<template>
<div>
<p>count值是:{
{number}}</p>
</div>
</template>
<script>
export default {
name:'MyCounter',
props:['number']
}
</script>
<style>
</style>
① v-bind: ディレクティブの前に v-model ディレクティブを追加します。
② Declareは、サブコンポーネント内のカスタムイベントをupdate:xxxの形式で発行します。
③ $emit() を呼び出してカスタム イベントをトリガーし、親コンポーネントのデータを更新します
<template>
<div>App根组件------{
{count}}</div>
<button @click="count += 1">+1</button>
<hr>
<my-counter v-model:number="count"></my-counter>
</template>
<script>
import MyCounter from './Counter.vue'
export default {
name:"MyApp",
data() {
return {
count:0,
}
},
components: {
MyCounter
}
}
</script>
<style>
</style>
<template>
<div>
<p>count值是:{
{number}}</p>
<button @click="add">+1</button>
</div>
</template>
<script>
export default {
name:'MyCounter',
props:['number'],
emits:['update:number'],
methods: {
add() {
this.$emit('update:number',this.number + 1)
}
}
}
</script>
<style>
</style>
タスクリストのケース
1.ケース効果
2. 使用されるナレッジポイント
① vite プロジェクトの作成
②コンポーネントのカプセル化と登録
③小道具
④スタイルバインディング
⑤ 計算された特性
⑥カスタムイベント
⑦コンポーネント上のv-model
3. 全体的な実装手順
① viteを使ってプロジェクトを初期化する
②プロジェクト構成を整理する
③ todo-listコンポーネントをカプセル化する
④ todo-inputコンポーネントをカプセル化する
⑤ todoボタンコンポーネントをカプセル化する
ウォッチリスナー
1. 時計とは何ですか?
リスナー監視リスナーを使用すると、開発者はデータの変更を監視し、データの変更に基づいて特定の操作を実行できます。たとえば、ユーザー名の変更を監視し、ユーザー名が使用可能かどうかを判断するリクエストを開始します。
2. ウォッチリスナーの基本構文
開発者は、監視ノードの下に独自のリスナーを定義する必要があります。コード例は次のとおりです。
export default {
data() {
return {username:''}
},
watch: {
//监听username的值的变化,
//形参列表中,第一个值是"变化后的新值",第二个值是"变化之前的旧值”
username(newVal,oldVal) {
console.log(newVal,oldVal)
},
},
}
<template>
<div>
<h3>watch侦听器的用法</h3>
<input type="text" class="form-control" v-model.trim="username">
</div>
</template>
<script>
export default {
name:'MyWatch',
data() {
return {
username: ''
}
},
watch: {
username(newVal,oldVal) {
console.log(newVal,oldVal)
}
}
}
</script>
<style>
</style>
3. watch を使用してユーザー名が利用可能かどうかを検出します
ユーザー名の値の変更をリッスンし、axios を使用して Ajax リクエストを開始し、現在入力されているユーザー名が使用可能かどうかを確認します。
import axios from axios
export default {
name:'MyWatch',
data() {
return {
username: ''
}
},
watch: {
async username(newVal,oldVal) {
console.log(newVal,oldVal)
const {data:res} = await axios('https://www.escook.cn/api/finduser/'+newVal)
console.log(res)
}
}
}
4. 即時オプション
デフォルトでは、コンポーネントが最初にロードされた後は、監視リスナーは呼び出されません。監視リスナーをすぐに呼び出す必要がある場合は、immediate オプションを使用する必要があります。コード例は次のとおりです。
watch: {
//1.监听username值的变化
username:{
//2.handle属性是固定写法,但username变化时,调用handle
async handler(newVal,oldVal) {
console.log(newVal,oldVal)
const {data:res} = await axios('https://www.escook.cn/api/finduser/'+newVal)
console.log(res)
},
//3.表示组件加载完毕后立即调用一次当前的watch侦听器
immediate:true
},
}
<template>
<div>
<h3>watch侦听器的用法</h3>
<input type="text" class="form-control" v-model.trim="username">
</div>
</template>
<script>
import axios from 'axios'
export default {
name:'MyWatch',
data() {
return {
username: 'admin'
}
},
watch: {
// async username(newVal,oldVal) {
// console.log(newVal,oldVal)
// const {data:res} = await axios('https://www.escook.cn/api/finduser/'+newVal)
// console.log(res)
// }
username: {
async handler(newVal,oldVal) {
console.log(newVal,oldVal)
const {data:res} = await axios('https://www.escook.cn/api/finduser/'+newVal)
console.log(res)
},
immediate:true
}
}
}
</script>
<style>
</style>
5.ディープオプション
watch がオブジェクトをリッスンしているときに、オブジェクト内のプロパティ値が変化すると、それを監視できなくなります。このとき、deep オプションを使用する必要があります。コード例は次のとおりです。
data() {
return {
username: 'admin',
info:{
username:'zs'
//info中包含username属性
}
}
},
watch: {
info: {
async handler(newVal) {
const {data:res} = await axios('https://www.escook.cn/api/finduser/'+newVal.username)
console.log(res)
},
deep:true //霄要使用deep选项,否则username值的变化无法被监听到
},
}
<template>
<div>
<h3>watch侦听器的用法</h3>
<input type="text" class="form-control" v-model.trim="info.username">
</div>
</template>
<script>
import axios from 'axios'
export default {
name:'MyWatch',
data() {
return {
username: 'admin',
info:{
username:'zs'
}
}
},
watch: {
// async username(newVal,oldVal) {
// console.log(newVal,oldVal)
// const {data:res} = await axios('https://www.escook.cn/api/finduser/'+newVal)
// console.log(res)
// }
// username: {
// async handler(newVal,oldVal) {
// console.log(newVal,oldVal)
// const {data:res} = await axios('https://www.escook.cn/api/finduser/'+newVal)
// console.log(res)
// },
// immediate:true
// }
info: {
async handler(newVal) {
const {data:res} = await axios('https://www.escook.cn/api/finduser/'+newVal.username)
console.log(res)
},
deep:true
},
}
}
</script>
<style>
</style>
6. オブジェクトの単一属性の変更を監視する
オブジェクトの 1 つのプロパティの変更だけをリッスンしたい場合は、次のように監視リスナーを定義できます。
data() {
return {
username: 'admin',
info:{
username:'zs'
//info中包含username属性
}
}
},
watch: {
'info.username': {
async handler(newVal) {
const {data:res} = await axios('https://www.escook.cn/api/finduser/'+newVal.username)
console.log(res)
},
deep:true //霄要使用deep选项,否则username值的变化无法被监听到
},
}
7. 計算されたプロパティとリスナー
計算されたプロパティとリスナーは、さまざまなアプリケーション シナリオに焦点を当てています。
計算プロパティは、複数の値の変化を監視することに重点を置き、最終的に新しい値を計算して返します。
リスナーは単一データの変更を監視することに重点を置き、最終的には戻り値なしで特定のビジネス処理を実行します。
コンポーネントのライフサイクル
1. コンポーネントの動作プロセス
コンポーネントのライフサイクルとは、コンポーネントの作成 -> 実行 (レンダリング) -> 破棄までのプロセス全体を指し、期間に重点を置きます。
2. さまざまな時点でコンポーネントを監視する方法
vue フレームワークには、さまざまな時点でのコンポーネントのライフ サイクル関数が組み込まれており、コンポーネントの実行時にライフ サイクル関数が自動的に呼び出されます。例えば:
①コンポーネントがメモリ上に作成されると、作成された関数が自動的に呼び出されます
② コンポーネントがページ上に正常にレンダリングされると、実装された関数が自動的に呼び出されます。
③ コンポーネントが破壊されると、アンマウントされた関数が自動的に呼び出されます。
<template>
<div>
<h1>App根组件</h1>
<hr>
<button @click="flag = !flag">Toggle</button>
<!-- 3.以标签形式使用组件 -->
<life-cycle v-if="flag"></life-cycle>
</div>
</template>
<script>
import LifeCycle from './life-cycle.vue'
export default {
name:'MyApp',
data() {
return{
flag:true
}
},
// 2.components注册组件
components:{
LifeCycle,
},
}
</script>
<style>
</style>
<template>
<div>
<h3>LifeCycle组件</h3>
</div>
</template>
<script>
export default {
name:'LifeCycle',
// 组件在内存中创建完毕
created() {
console.log('created:组件在内存中创建完毕');
},
// 组件第一次被渲染到页面
mounted() {
console.log('mounted:组件第一次被渲染到页面');
},
// 组件被销毁完毕
unmounted() {
console.log('unmounted:组件被销毁完毕');
}
}
</script>
<style lang="less" scoped>
</style>
3. コンポーネントのアップデートを監視する方法
コンポーネントのデータが更新されると、vue はコンポーネントの DOM 構造を自動的に再レンダリングして、ビューによって表示されるデータがモデル データ ソースと一致していることを確認します。
コンポーネントが再レンダリングされると、更新されたライフサイクル関数が自動的に呼び出されます。
<template>
<div>
<h3>LifeCycle组件-------{
{count}}</h3>
<button @click="count += 1">+1</button>
</div>
</template>
<script>
export default {
name:'LifeCycle',
data() {
return {
count:0,
}
},
// 组件在内存中创建完毕
created() {
console.log('created:组件在内存中创建完毕');
},
// 组件第一次被渲染到页面
mounted() {
console.log('mounted:组件第一次被渲染到页面');
},
// 组件被重新渲染完毕了
updated() {
console.log('updated:组件被重新渲染完毕了');
},
// 组件被销毁完毕
unmounted() {
console.log('unmounted:组件被销毁完毕');
}
}
</script>
<style lang="less" scoped>
</style>
4. コンポーネントの主なライフサイクル機能
注: 実際の開発では、
ライフサイクル機能 | 実行タイミング | ステージ | 実行数 | アプリケーションシナリオ |
---|---|---|---|---|
作成した | コンポーネントがメモリ内に作成された後 | 作成段階 | 唯一の時間 | 初期データの Ajax リクエストを送信する |
取り付けられた | コンポーネントがページ上に初めてレンダリングされた後 | 作成段階 | 唯一の時間 | DOM要素を操作する |
更新しました | コンポーネントがページ上で再レンダリングされた後 | ランニングフェーズ | 0回以上 | - |
アンマウントされた | コンポーネントが破壊された後 (ページとメモリ) | 破壊段階 | 唯一の時間 | - |
created は最も一般的に使用されるライフサイクル関数です。
5. コンポーネント内のすべてのライフサイクル機能
質問: beforeCreate で初期データの ajax リクエストを送信しないのはなぜですか?
6. 完全なライフサイクル図
コンポーネントのライフサイクル実行プロセスをさらに理解するには、vue の公式ドキュメントに記載されている「ライフ サイクルの図」を参照してください: https://www.vue3js.cn/docs/zh/guide/instance.html#Life Cycle Illustration
コンポーネント間のデータ共有
1. コンポーネント間の関係
プロジェクト開発において、コンポーネント間の関係は次の 3 種類に分類されます。
①父と子の関係
②兄弟愛
③子孫関係
2. 親コンポーネントと子コンポーネント間のデータ共有
親コンポーネントと子コンポーネント間のデータ共有は次のように分割されます。
①親→子共有データ
②子→親共有データ
③ 親 <-> 子の双方向データ同期
2.1 親コンポーネントは子コンポーネントとデータを共有します
親コンポーネントは、v-bind プロパティ バインディングを通じて子コンポーネントとデータを共有します。同時に、子コンポーネントはデータを受信するために props を使用する必要があります。サンプルコードは次のとおりです。
//父组件
<template>
<div>
<h1>App根组件---{
{count}}</h1>
<button @click="count += 1">+1</button>
<hr>
<my-son :num="count"></my-son>
</div>
</template>
<script>
import MySon from './son.vue'
export default {
name:"MyApp",
data() {
return {
count: 0
}
},
components: {
MySon,
},
}
</script>
<style>
</style>
//子组件
<template>
<div>
<h3>Son子组件----{
{num}}</h3>
</div>
</template>
<script>
export default {
name:'MySon',
props:['num']
}
</script>
<style lang="less" scoped>
</style>
2.2 子コンポーネントは親コンポーネントとデータを共有します
子コンポーネントは、カスタム イベントを通じて親コンポーネントとデータを共有します。サンプルコードは次のとおりです。
<template>
<div>
<h1>App根组件---{
{count}}</h1>
<button @click="count += 1">+1</button>
<hr>
<my-son :num="count" @numchange="getNum"></my-son>
</div>
</template>
<script>
import MySon from './son.vue'
export default {
name:"MyApp",
data() {
return {
count: 0
}
},
methods:{
getNum (num) {
this.count = num
}
},
components: {
MySon,
},
}
</script>
<style>
</style>
<template>
<div>
<h3>Son子组件----{
{num}}</h3>
<button @click="add">+1</button>
</div>
</template>
<script>
export default {
name:'MySon',
props:['num'],
emits:['numchange'],
methods: {
add() {
this.$emit('numchange',this.num+1)
}
}
}
</script>
<style lang="less" scoped>
</style>
2.3 親コンポーネントと子コンポーネント間のデータの双方向同期
子コンポーネントの使用中、親コンポーネントは v-model ディレクティブを使用して、コンポーネントの内部と外部のデータの双方向同期を維持できます。
<template>
<div>
<h1>App根组件---{
{count}}</h1>
<button @click="count += 1">+1</button>
<hr>
<!-- <my-son :num="count" @numchange="getNum"></my-son> -->
<my-son v-model:num="count"></my-son>
</div>
</template>
<script>
import MySon from './son.vue'
export default {
name:"MyApp",
data() {
return {
count: 0
}
},
// methods:{
// getNum (num) {
// this.count = num
// }
// },
components: {
MySon,
},
}
</script>
<style>
</style>
<template>
<div>
<h3>Son子组件----{
{num}}</h3>
<button @click="add">+1</button>
</div>
</template>
<script>
export default {
name:'MySon',
props:['num'],
// emits:['numchange'],
emits:['update:num'],
methods: {
add() {
// this.$emit('numchange',this.num+1)
this.$emit('update:num',this.num+1)
}
}
}
</script>
<style lang="less" scoped>
</style>
3. 兄弟コンポーネント間のデータ共有
兄弟コンポーネント間でデータを共有するためのソリューションは EventBus です。サードパーティのパッケージ mitt を使用して、eventBus オブジェクトを作成し、兄弟コンポーネント間でデータ共有を実現できます。概略図は次のとおりです。
3.1 mit 依存関係パッケージをインストールする
プロジェクトで次のコマンドを実行して、mit 依存関係パッケージをインストールします。
npm install [email protected] -S
3.2 パブリック EventBus モジュールを作成する
次のようにプロジェクト内にパブリックのeventBusモジュールを作成します。
//eventBus
//导入mitt包
import mitt from 'mitt'
//创建EventBus的实例对象
const bus = mitt()
//将EventBus的实例对象共享出去
export default bus
3.3 データ受信側のイベントをカスタマイズする
データ受信側で、bus.on('イベント名', イベント処理関数) メソッドを呼び出してカスタム イベントを登録します。サンプルコードは次のとおりです。
export default {
nname:'MyRight',
data() {
return {
num:0,
}
},
created() {
// 调用bus.on()方法注册一个自定义事件,通过事件处理函数的形参接收数据
bus.on('countChange',count =>{
this.num = count
})
}
}
3.4 データ送信側と送信側でイベントをトリガーする
データ送信側で、bus.emit('イベント名', 送信されるデータ) メソッドを呼び出して、カスタム イベントをトリガーします。サンプルコードは次のとおりです。
import bus from './eventBus.js'
export default {
name:'MyLeft',
data() {
return {
count:0,
}
},
methods: {
add() {
this.count++
bus.emit('countChange',this.count)
}
}
}
<template>
<div>
<h1>App根组件----{
{count}}</h1>
<!-- <button @click="count += 1">+1</button> -->
<hr>
<level-two></level-two>
</div>
</template>
<script>
import LevelTwo from './level-two.vue'
export default {
name:'MyApp',
data() {
return {
color:'red',
count: 1
}
},
provide() {
return {
// 返回要共享的数据对象
color:this.color,
count:this.count
}
},
components: {
LevelTwo,
}
}
</script>
<style lang="less" scoped>
</style>
<template>
<div>
<h3>Lever Two 二级组件</h3>
<hr>
<level-three></level-three>
</div>
</template>
<script>
import LevelThree from './level-three.vue'
export default {
name:'LevelTwo',
components: {
LevelThree,
}
}
</script>
<style lang="less" scoped>
</style>
<template>
<div>
<h5>Level Three 三级组件---{
{color}}---{
{count}}</h5>
</div>
</template>
<script>
export default {
name:'LevelThree',
inject:['color','count']
}
</script>
<style lang="less" scoped>
</style>
4. 子孫関係コンポーネント間のデータ共有
子孫関係コンポーネント間でデータを共有するということは、親ノードのコンポーネントがその子孫コンポーネントとデータを共有することを意味します。このとき、コンポーネント間の入れ子関係はより複雑になるため、provide (データ送信用) と inject (受信者用) を使用して、子孫関係コンポーネント間でのデータ共有を実現できます。
4.1 親ノードはプロバイドを通じてデータを共有します
親ノードのコンポーネントは、provide メソッドを通じてその子孫コンポーネントとデータを共有できます。
export default {
data() {
return {
color:'red'//1.定义"父组件"要向"子孙组件共享的数招
}
},
provide() {
//2.provide函数return的对象中,包含了"要向子孙组件共享的数据
return {
color: this.color,
}
}
}
4.2 子孫ノードはインジェクトを通じてデータを受信します
子孫ノードは、注入配列を使用して、親ノードから下位に共有されたデータを受信できます。サンプルコードは次のとおりです。
<template>
<div>
<h3>子孙组件-----{
{color}}</h3>
</div>
</template>
<script>
export default {
//子孙组件,使用inject接收父节点向下共享的color数据,并在页面上使用
inject:['color']
}
</script>
4.3 親ノードは応答データを外部と共有します
親ノードが Provide を使用してデータを下方向に共有する場合、計算関数と組み合わせて応答データを下方向に共有できます。サンプルコードは次のとおりです。
//1.从 vue中按需导入computed函数
import {computed} from 'vue'
export default {
data() {
return {
color:'red',
count: 1
}
},
provide() {
return {
color: computed(() => this.color),
}
},
}
4.4 子孫ノードは応答性の高いデータを使用する
親ノードが応答データを共有する場合、子孫ノードは .value の形式で使用する必要があります。サンプルコードは次のとおりです。
<template>
<div>
<h5>Level Three 三级组件---{
{color}}---{
{count.value}}</h5>
</div>
</template>
<script>
export default {
name:'LevelThree',
inject:['color','count']
}
</script>
5. vuex
vuex は、コンポーネント間の究極のデータ共有ソリューションです。エンタープライズ レベルの Vue プロジェクト開発では、vuex を使用すると、コンポーネント間のデータ共有が効率的かつ明確になり、保守が容易になります。
5.1 vuex の基本的な使い方
vuex 依存関係パッケージをインストールする
npm install vuex --save
vuex パッケージをインポートする
import Vuex from 'vuex'
Vue.use(Vuex)
ストアオブジェクトの作成
const store = new Vuex.Store({
//state 中存放的就是全局共享的数据
state:{count:0}
})
ストア オブジェクトを vue インスタンスにマウントします
new Vue ({
el:'#app',
render:h => h(app),
router,
//将创建的共享数据对象,挂载到vue实例中
//所有的组件,就可以直接从store中获取全局的数据了
store
})
6. まとめ
父と子の関係
① 親→子の属性バインディング
②子→親イベントバインディング
③ 子コンポーネントの親 <-> v-model
兄弟愛
④イベントバス
子孫関係
⑤提供&注入
グローバルなデータ共有
⑥ vuex
vue 3.x のグローバル設定 axios
1. axios をグローバルに設定する理由は何ですか?
実際のプロジェクト開発では、axios はデータ要求を開始するためにほぼすべてのコンポーネントで使用されます。このとき、次の 2 つの問題が発生します。
① 各コンポーネントは axios (肥大化したコード) をインポートする必要があります
② リクエストを送信するたびに、完全なリクエスト パスを入力する必要があります (後のメンテナンスに役立ちません)
2. axios をグローバルに設定する方法
main.js エントリ ファイルで、app.config.globalProperties を通じて axios をグローバルにマウントします。サンプル コードは次のとおりです。
//main.js
// 1.从 vue中按需导入 createApp函数
import { createApp } from 'vue'
// 2.导入待渲染的App 组件
// import App from './App.vue'
// import App from './components/03-style/App.vue'
// import App from './components/04-props/App.vue'
// import App from './components/05-class&style/App.vue'
// import App from './components/10-watch/App.vue'
import App from './components/15-network/App.vue'
import axios from 'axios'
//1.导入需要被全局注册的组件
import Swiper from './components/01-globalReg/Swiper.vue'
import Test from './components/01-globalReg/Test.vue'
//3.调用createApp()函数,返回值是"单页面应用程序的实例"
const app = createApp(App)
//2.调用app . component()方法全局注册组件
app.component('my-swiper', Swiper)
// app.component(Swiper,name,Swiper)
app.component('my-test', Test)
axios.defaults.baseURL = 'https://www.escook.cn'
app.config.globalProperties.$http = axios
//4.调用 mount方法,把App 组件的模板结构,渲染到指定的el区域中
app.mount('#app')
//App.vue
<template>
<div>
<h1>App根组件</h1>
<hr>
<div class="box">
<get-info></get-info>
<post-info></post-info>
</div>
</div>
</template>
<script>
import GetInfo from './GetInfo.vue'
import PostInfo from './PostInfo.vue'
export default {
name:"MyApp",
// 注册组件
components:{
GetInfo,
PostInfo
}
}
</script>
<style lang="less" scoped></style>
//GetInfo.vue
<template>
<div>
<h3>Get Info 组件</h3>
<hr>
<button @click="getinfo">发起GET请求</button>
</div>
</template>
<script>
export default {
name:'GetInfo',
methods: {
async getinfo() {
const {data:res} = await this.$http.get('/api/get',{
params: {
name:'ls',
age:33
}
})
console.log(res)
}
}
}
</script>
<style lang="less" scoped>
</style>
//PostInfo.vue
<template>
<div>
<h3>Post Info 组件</h3>
<hr>
<button @click="postinfo">发起POST请求</button>
</div>
</template>
<script>
export default {
name:'PostInfo',
methods: {
async postinfo() {
const {data:res} = await this.$http.post('/api/post',{name:'zs',age:20})
console.log(res)
}
}
}
</script>
<style lang="less" scoped>
</style>
ショッピングカートケース
-
ケース効果
-
実装手順
① プロジェクトの基本構造を初期化する
② EsHeaderコンポーネントをカプセル化する
③axiosによる商品リストデータのリクエスト(GETリクエスト、アドレスはhttps://www.escook.cn/api/cart)
④ EsFooterコンポーネントをカプセル化する
⑤ EsGoodsコンポーネントのカプセル化
⑥ EsCounterコンポーネントのカプセル化
参照参照
1. 参照参照とは何ですか?
Ref は、開発者が jQuery に依存せずに DOM 要素またはコンポーネントへの参照を取得できるようにするために使用されます。
各 Vue コンポーネント インスタンスには、対応する DOM 要素またはコンポーネントへの参照を保存する $refs オブジェクトが含まれています。デフォルトでは、コンポーネントの $refs は空のオブジェクトを指します。
<template>
<div>
<h3>MyRef 组件</h3>
<button @click="getRef">获取$refs引用</button>
</div>
</template>
<script>
export default {
methods:{
getRef() {
//this代表当前组件的实例对象,this.$refs默认指向空对象
console.log(this)
}
}
}
</script>
2. ref を使用して DOM 要素を参照する
ref を使用してページ上の DOM 要素を参照する場合は、次のように実行できます。
<template>
<div>
<h3 ref='myh3'>MyRef 组件</h3>
<button @click="getRef">获取$refs引用</button>
</div>
</template>
<script>
export default {
methods:{
getRef() {
//this代表当前组件的实例对象,this.$refs默认指向空对象
console.log(this.$refs.myh3)
//操作DOM元素,把文本颜色改为红色
this.$refs.myh3.style.color = 'red'
}
}
}
</script>
3. ref を使用してコンポーネント インスタンスを参照する
ref を使用してページ上のコンポーネント インスタンスを参照する場合は、次のように実行できます。
<!--使用ref属性,为对应的"组件"添加引用名称-->
<my-counter ref="counterRef"></my-counter>
<button @click="getRef">获取$refs 引用</button>
methods: {
getRef() {
//通过this.$refs.引用的名称可以引用组件的实例 console.log(this.$refs.counterRef)
//引用到组件的实例之后,就可以调用组件上的 methods方法 this.$refs.counterRef.add()
},
}
4. テキスト ボックスとボタンのオンデマンド切り替えを制御する
ブール値 inputVisible を使用して、コンポーネント内のテキスト ボックスとボタンのオンデマンド切り替えを制御します。サンプルコードは次のとおりです。
<template>
<input type='text' v-if='inputVisible'>
<button v-eles @click="showinput">展示input输入框</button>
</template>
export default {
data() {
return {
//控制文本框和按钮的按需切换
inputVisible:false,
}
},
methods: {
showinput() {
thisinputVisible = true
}
}
}
</script>
5. テキスト ボックスに自動的にフォーカスを移します。
テキスト ボックスが表示された後、すぐにフォーカスを取得したい場合は、テキスト ボックスに ref 参照を追加し、ネイティブ DOM オブジェクトの .focus() メソッドを呼び出します。サンプルコードは次のとおりです。
<input type='text' class="form-control" v-if='inputVisible' ref="ipt" >
<!-- v-eles @click="showinput" -->
<button v-else @click="showinput">展示input输入框</button>
methods: {
showinput() {
this.inputVisible = true
//获取文本框的DOM引用。并调用.focus(使其自动获得焦点
this.$refs.ipt.focus()
}
}
6. this.$nextTick(cb) メソッド
コンポーネントの $nextTick(cb) メソッドは、次の DOM 更新サイクルまで cb コールバックの実行を延期します。一般的な理解は、コンポーネントの DOM が非同期で再レンダリングされるのを待ってから、cb コールバック関数を実行するというものです。これにより、cb コールバック関数が最新の DOM 要素で動作できるようになります。
<input type='text' class="form-control" v-if='inputVisible' ref="ipt" >
<!-- v-eles @click="showinput" -->
<button v-else @click="showinput">展示input输入框</button>
methods: {
showinput() {
this.inputVisible = true
//获取文本框的DOM引用。并调用.focus()使其自动获得焦点
this.$nextTick(() => {
this.$refs.ipt.focus()
})
}
}
動的コンポーネント
1. 動的コンポーネントとは何ですか?
動的コンポーネントとは、コンポーネントの表示と非表示を動的に切り替えることを指します。vue は組み込みを提供します
<component> コンポーネントは、コンポーネントの動的レンダリングを実装するために特別に使用されます。
①はコンポーネントのプレースホルダーです
② is 属性でレンダリングするコンポーネント名を動的に指定する
③ <component is="レンダリングするコンポーネント名">< /component>
2. 動的コンポーネントレンダリングの実装方法
サンプルコードは次のとおりです。
data() {
return {
comName: "my-dynamic-1'
// 1.当前要渲染的组件的名称)
}
}
<template>
<-- 3,点击按钮,动态切换组件的名称-->
<button @click="comName='my-dynamic-1"">组件1</button> <button @click="comName= 'my-dynamic-2"">组件2</button> <!--2。通过is属性,动态指定要渲染的组件的名称-->
<component :is="comName ></component>
</template>
3. キープアライブを使用して状態を維持する
デフォルトでは、動的コンポーネントを切り替えるときにコンポーネントの状態は維持されません。現時点では、vue の組み込み <keep-alive> コンポーネントを使用して、動的コンポーネントの状態を維持できます。サンプルコードは次のとおりです。
<keep-alive>
<component :is = 'comName'></component>
</keep-alive>
スロット
1. スロットとは何ですか?
スロットは、コンポーネント パッケージャー用に vue によって提供される機能です。開発者は、コンポーネントをカプセル化するときにユーザーがスロットとして指定することが予想される未定義のパーツを定義できます。
スロットは、コンポーネントのパッケージ化中にユーザー用に予約されたコンテンツのプレースホルダーと考えることができます。
2. スロットの基本的な使い方を体験する
コンポーネントをカプセル化する場合、slot 要素を使用してスロットを定義し、ユーザー用にコンテンツ プレースホルダーを予約できます。サンプルコードは次のとおりです。
<template>
<p>这是MyCom1组件的第1个p标签</p>
<!--通过slot标签,为用户预留内容占位符(插槽) -->
<slot></slot>
<p>这是MyCom1组件的最后一个p标签</p>
</template>
<my-com-1>
<!--在使用MyCom1组件时,为插槽指定具体的内容-->
<P>---用户自定义的内容---</p>
</my-com-1>
2.1 予約スロットのないコンテンツは破棄されます
コンポーネントをパッケージ化するときにスロットが予約されていない場合、ユーザーが提供したカスタマイズはすべて破棄されます。サンプルコードは次のとおりです。
<template>
<p>这是MyCom1组件的第1个p标签</p>
<!--封装组件时吗,没有预留任何插槽 -->
<p>这是MyCom1组件的最后一个p标签</p>
</template>
<my-com-1>
<!--在使用MyCom1组件时,为插槽指定具体的内容-->
<P>---用户自定义的内容---</p>
</my-com-1>
2.2 フォールバックコンテンツ
コンポーネントをパッケージ化するときに、予約されたスロットにフォールバック コンテンツ (デフォルト コンテンツ) を提供できます。コンポーネントのコンシューマがスロットにコンテンツを提供しない場合、フォールバック コンテンツが有効になります。サンプルコードは次のとおりです。
<template>
<p>这是MyCom1组件的第1个p标签</p>
<!--通过slot标签,为用户预留内容占位符(插槽) -->
<slot>这是后备内容</slot>
<p>这是MyCom1组件的最后一个p标签</p>
</template>
3. 名前付きスロット
コンポーネントをカプセル化するときに複数のスロット ノードを予約する必要がある場合は、各スロットに特定の名前を指定する必要があります。このように特定の名前が付けられたスロットを「名前付きスロット」と呼びます。サンプルコードは次のとおりです。
<div class="container">
<header>
<!--我们希望把页头放这里-->
<slot name="header"></slot>
</header>
<main>
<!--我们希望把主要内容放这里-->
<slot></slot>
</main>
<footer>
<!--我们希望把页脚放这里-->
<slot name="footer"></slot>
</footer>
</div>
注: 名前が指定されていないスロットには、「default」という暗黙の名前が付けられます。
3.1 名前付きスロットのコンテンツの提供
名前付きスロットにコンテンツを提供する場合、<template> 要素で v-slot ディレクティブを使用し、その名前をパラメータとして v-slot に提供できます。サンプルコードは次のとおりです。
<my-com-2>
<template v-slot:header>
<h1>滕王阁序</h1>
</template>
<template v-slot : default>
<p>豫章故郡,洪都新府。</p>
<p>星分翼轸,地接衡庐。</p>
<p>襟三江而带五湖,控蛮荆而引瓯越。</p>
</template>
<template v-slot:footer>
<p>落款:王勃</p>
</template>
</my-com-2>
3.2 名前付きスロットの短縮形
v-on や v-bind と同様、v-slot にも省略形があり、パラメーター (v-slot:) より前のすべてが文字 # に置き換えられます。たとえば、v-slot:header は #header として書き換えることができます。
4. スコープスロット
コンポーネントをカプセル化するプロセスでは、props データを予約されたスロットにバインドできます。この種の props データは「スコープ スロット」と呼ばれます。サンプルコードは次のとおりです。
<div>
<h3>这是TEST组件</h3>
<slot :info="infomation"></slot>
</div>
<!--使用自定义组件-->
<my-test>
<template v-slot:default="scope">
{
{ scope }}
</template>
</my-test>
4.1 スコープ スロットの Prop を分解する
スコープ スロットによって外部から提供されるデータ オブジェクトの場合、分割割り当てを使用してデータ受信プロセスを簡素化できます。サンプルコードは次のとおりです。
<my-table>
<!-- v-slot:可以简写成#-->
<!-- 作用域插槽对外提供的数据对象,可以通过“解构赋值"简化接收的过程->
<template #default="{ user , info }">
<!--【使用】作用域插槽的数据-->
<td>i{ user.id }}</td>
<td>{
{ user.name }}</td>
<td>{
{ user.state }</td>
</template>
</my-table>
4.2 スコープスロットの宣言
MyTable コンポーネントをカプセル化するプロセスでは、テーブルの各行のデータをスコープ スロットを通じてコンポーネントのユーザーに渡すことができます。サンプルコードは次のとおりです。
<!--表格主体区域-->
<tbody>
<!--循环渲染表格数据-->
<tr v-for="item in list" :key="item.id">
<!-- 下面的 slot是一个【作用域插槽】-->
<slot :user="item"></slot>
</tr>
</tbody>
4.3 スコープ付きスロットの使用
MyTable コンポーネントを使用する場合、セルのレンダリング方法をカスタマイズし、スコープ スロットによって提供されるデータを受け取ります。サンプルコードは次のとおりです。
カスタム命令
1. カスタム ディレクティブとは何ですか?
Vue は、v-for、v-model、v-if などの一般的に使用される組み込み命令を公式に提供しています。さらに、Vue では開発者が命令をカスタマイズすることもできます。
vue のカスタム命令は、次の 2 つのカテゴリに分類されます。
- プライベートカスタムディレクティブ
- グローバルカスタムディレクティブ
2. プライベートカスタム命令を宣言するための構文
各 vue コンポーネントでは、プライベート カスタム ディレクティブをディレクティブ ノードの下で宣言できます。サンプルコードは次のとおりです。
directives: {
//自定义一个私有指令
focus: {
//当被绑定的元素插入到DOM中时,自动触发mounted函数 mounted(el) {
el.focus() //让被绑定的元素自动获得焦点
}
}
}
3. カスタム命令を使用する
カスタム命令を使用する場合は、v- 接頭辞を追加する必要があります。サンプルコードは次のとおりです。
<!--声明自定义指令时,指令的名字是focus -->
<!--使用自定义指令是,需要加上v-指令前缀-->
<input v-focus />
4. グローバルカスタムディレクティブを宣言するための構文
グローバルに共有されるカスタム命令は、「シングルページ アプリケーションのインスタンス オブジェクト」を通じて宣言する必要があります。サンプル コードは次のとおりです。
const app = vue.createApp({})
//注册一个全局自定义指令`v-focus '
app.directive( 'focus ', {
//当被绑定的元素插入到DOM中时,自动触发 mounted函数
mounted(el) {
// Focus the element
el.focus()
}
})
5. 機能のアップデート
マウントされた関数は、要素が初めて DOM に挿入されたときにのみ呼び出されます。マウントされた関数は、DOM が更新されたときにはトリガーされません。更新された関数は、DOM の更新が完了するたびに呼び出されます。サンプルコードは次のとおりです。
app.directive( 'focus ', {
mounted(el) {
//第一次插入DOM时触发这个函数
el.focus()
},
updated(el) {//每次DOM更新时都会触发updated函数
el.focus(
}
})
注: vue2 プロジェクトでカスタム命令を使用する場合、[マウント -> バインド] [更新 -> 更新]
6. 機能の略称
マウントされた関数と更新された関数のロジックがまったく同じである場合は、次の形式に短縮できます。
app.directive( 'focus', (el) =>{
//在mounted 和 updated时都会触发相同的业务处理
el.focus()
})
7. コマンドのパラメータ値
命令をバインドする場合、特定のパラメータ値を「等号」の形式で命令にバインドできます。サンプルコードは次のとおりです。
<!--在使用v-color 指令时,可以通过“等号"绑定指令的值-->
<input type="text" v-model.number="count" v-focus v-color=" ' red'">
<p v-color=" ' cyan' ">{
{count}}</p>
<button @click=" count++">+1</button>
//自定义v-color 指令
app.directive( 'color ' , (el, binding) =>{
// binding.value就是通过"等号"为指令绑定的值
el.style.color = binding.value
})
テーブルケース
1.ケース効果
2. 使用されるナレッジポイント
コンポーネントのカプセル化
名前付きスロット
スコープスロット
カスタム命令
3. 導入手順
①プロジェクトの基本構造を構築する
② 製品リストのデータ請求
③ MyTableコンポーネントをカプセル化する
④削除機能の実装
⑤タグ追加機能の実装
ルーティング
フロントエンドルーティングの概念と原理
1. ルーティングとは
ルーティング(英語: router )とは対応関係である。ルートは 2 つのカテゴリに分類されます。
①バックエンドルーティング
② フロントエンドルーティング
2. 復習: バックエンドルーティング
バックエンドルーティングとは、リクエストメソッド、リクエストアドレス、ファンクション処理機能の対応関係を指します。Node.js コースでは、エクスプレス ルーティングの基本的な使用方法は次のとおりです。
const express = require( 'express ")
const router = express.Router()
router.get( " /userlist ', function(req,res) {产路由的处理函数*/ })
router.post( " ladduser " , function(req,res) { /*路由的处理函数*/ })
module.exports = router
3. SPA とフロントエンド ルーティング
SPAとは、WebサイトにHTMLページが1つだけあり、すべてのコンポーネントの表示や切り替えがこの1ページ内で完結することを意味します。現時点では、異なるコンポーネント間の切り替えは、フロントエンド ルーティングを通じて実装する必要があります。
結論: SPA プロジェクトでは、異なる機能間の切り替えはフロントエンドのルーティングに依存します。
4. フロントエンドルーティングとは何ですか?
わかりやすい概念:ハッシュアドレスとコンポーネントの対応。
5. フロントエンドルーティングの仕組み
① ユーザーがページ上のルーティングリンクをクリックした
② これにより、URL アドレスバーのハッシュ値が変化します。
③ フロントエンドルーティングがハッシュアドレスの変更を監視
④ フロントエンドルーティングは、現在のハッシュアドレスに対応するコンポーネントをブラウザにレンダリングします。
6. シンプルなフロントエンドルーティングを実装する
ステップ 1: MyHome、MyMovie、MyAbout の 3 つのコンポーネントをインポートして登録します。サンプルコードは次のとおりです。
import MyHome from './MyHome.vue'
import MyMovie from './MyMovie.vue'
import MyAbout from './MyAbout.vue'
export default {
components: {
MyHome,
MyMovie,
MyAbout,
},
}
ステップ 2: ラベルの is 属性を通じて、表示するコンポーネントを動的に切り替えます。サンプルコードは次のとおりです。
<template>
<h1>App组件</h1>
<component :is="comName"></component>
</template>
export default {
data() {
return {
comName: 'my-home ',
//要展示的组件的名称}
},
}
}
ステップ 3: コンポーネント構造で次の 3 つのリンクを宣言し、別のリンクをクリックして、ブラウザのアドレス バーのハッシュ値を切り替えます。
<a href="#/home">Home</a>
<a href="# /movie">Moviec</a>
<a href="#/about">About</a>
ステップ 4: 作成したライフサイクル関数で、ブラウザーのアドレス バーのハッシュ アドレスの変化を監視し、表示されるコンポーネントの名前を動的に切り替えます。
created(){
windaw.onhashchange = ()> {
switch (location.hash){
case '#/home' :
//点击了“首页"的链接
this.comName = 'my-home"
break
case '#/movie':
//点击了“电影""的链接
this.comName = 'my-movie‘
break
case '#/about' :
//点击了“关于"的链接
this.comName = 'my-about"
break
}
}
}
vue-router の基本的な使用方法
1.vue-routerとは何ですか
vue-router は、vue.js によって提供される公式のルーティング ソリューションです。vue プロジェクトと組み合わせてのみ使用でき、SPA プロジェクト内のコンポーネントの切り替えを簡単に管理できます。
2.vue-routerのバージョン
vue-router には現在バージョン 3.x と 4.x があります。で:
vue-router 3.x は vue2 と組み合わせてのみ使用できます
vue-router 4.x は vue3 と組み合わせてのみ使用できます
vue-router 3.x の公式ドキュメントのアドレス: https://router.vuejs.org/zh/
vue-router 4.x の公式ドキュメントのアドレス: https://next.router.vuejs.org/
3.vueルーター
4.x を使用するための基本的な手順
①vue-routerをプロジェクトにインストールする
② ルーティングコンポーネントを定義する
③ ルーティングリンクとプレースホルダーを宣言する
④ルーティングモジュールの作成
⑤ ルーティングモジュールのインポートとマウント
3.1 プロジェクトに vue-router をインストールする
vue3 プロジェクトでは、vue-router 4.x のみをインストールして使用できます。インストールコマンドは以下の通り
npm install vue-router@next -s
3.2 ルーティングコンポーネントの定義
プロジェクトに MyHome.vue、MyMovie.vue、MyAbout.vue の 3 つのコンポーネントを定義し、将来的には vue-router を使用して表示と切り替えを制御する予定です。
3.3 ルーティング リンクとプレースホルダーの宣言
<router-link> タグを使用してルート リンクを宣言し、<router-view> タグを使用してルート プレースホルダを宣言できます。サンプルコードは次のとおりです。
<template>
<h1>App 组件</h1>
<!--声明路由链接-->
<router-link to="/home">首页</router-link> :
<router-link to="/movie">电影</router-link>
<router-link to="/about">关于</router-link>
<!--声明路由占位符-->
<router-view></router-view>
</template>
3.4 ルーティングモジュールの作成
プロジェクト内に router.js ルーティング モジュールを作成し、次の 4 つの手順に従ってルーティング インスタンス オブジェクトを作成して取得します。
①vue-routerからオンデマンドで2つのメソッドをインポート
②ルーティングによる制御が必要なコンポーネントをインポートする
③ルーティングインスタンスオブジェクトの作成
④ルーティングインスタンスオブジェクトを外部と共有する
⑤main.jsにルーティングモジュールをインポートしてマウントする
vue-router からオンデマンドで 2 つのメソッドをインポートします
//创建router.js
//1.从 vue-router中按需导入两个方法
//createRouter方法用于创建路由的实例对象
//createwebHashHistory用于指定路由的工作模式(hash模式)
import { createRouter, createWebHashHistory } from 'vue-router'
ルーティングによって制御する必要があるコンポーネントをインポートする
// 2.导入组件,这些组件将要以路由的方式,来控制它们的切换
import Home from './MyHome.vue'
import Movie from './MyMovie.vue'
import About from './MyAbout.vue'
ルーティングインスタンスオブジェクトの作成
//3.创建路由实例对象
const router = createRouter({
// 3.1通过history属性指定路由的工作模式
history: createwebHashHistory(),
// 3.2 通过routes数组,指定路由规则
routes: [
// path 是 hash 地址,component是要展示的组件
{ path: '/home', component: Home },
{ path: '/movie', component: Movie },
{ path: '/about', component: About },
],
})
ルーティング インスタンス オブジェクトを外部と共有する
// 4.向外共享路由实例对象,
//供其它模块导入并使用
export default router
main.js にルーティング モジュールをインポートしてマウントします。
import { createApp } from "vue '
import App from './App. vue"import './index.css'
// 1.导入路由模块
import router from './router"
const app = creatcApp(App)
// 2.挂载路由模块
//app.use()方法用来挂载"第三方的插件模块”
app.use(router)
app.mount( ' #app ')
vue-router の高度な使用法
1.ルートリダイレクション
ルーティング リダイレクトとは、ユーザーがアドレス A にアクセスすると、特定のコンポーネント ページを表示するためにアドレス C に強制的にジャンプすることを意味します。ルーティング ルールのリダイレクト属性を使用して新しいルーティング アドレスを指定すると、ルーティングのリダイレクトを簡単に設定できます。
const router = createRouter({
// 3.1通过history属性指定路由的工作模式
history: createWebHashHistory(),
// 3.2 通过routes数组,指定路由规则
routes: [
// path 是 hash 地址,component是要展示的组件
{ path: '/', redirect: "/home" },
{ path: '/home', component: Home },
{ path: '/movie', component: Movie },
{ path: '/about', component: About },
],
})
2. ルートのハイライト表示
アクティブ化されたルーティング リンクは、次の 2 つの方法で強調表示できます。
① デフォルトの強調表示されたクラスを使用する
②ルートハイライトクラスのカスタマイズ
2.1 デフォルトの強調表示されたクラス class
アクティブ化されたルーティング リンクには、デフォルトで router-link-active というクラス名が適用されます。開発者は、このタイプの名前セレクターを使用して、アクティブなルーティング リンクの強調表示スタイルを設定できます。
/*在index.css全局样式表中,重新router-link-active 的样*/
.routcr-link-active {
background-color: red;
color : white;
font-weight: bold;
}
2.2 ルート強調表示クラスをカスタマイズする
ルートのインスタンス オブジェクトを作成するとき、開発者は、linkActiveClass 属性に基づいてルート リンクがアクティブ化されるときに使用されるクラス名をカスタマイズできます。
const router = createRouter({
history: createwebHashHistory(),
//指定被激活的路由链接,会应用router-active 这个类名,
//默认的 router-link-active类名会被覆盖掉
linkActiveClass : 'router-active',
routes: [
{ path: ' / ' , redirect: "/home’ }.
{ path: '/home ',component: Home },
{path: ' /movie ', component: Movie },
{ path: ' labout ', component: About },
],
})
3. ネストされたルーティング
ルーティングによってコンポーネントのネストされた表示を実装することをネストされたルーティングと呼びます。
① サブルートリンクとサブルートプレースホルダーの宣言
② 親ルーティング ルール内で、children 属性を介してネストされた子ルーティング ルールを宣言します。
3.1 サブルート リンクとサブルート プレースホルダーの宣言
About.vue コンポーネントで、tab1 と tab2 のサブルート リンクとサブルート プレースホルダーを宣言します。サンプルコードは次のとおりです。
<template>
<div>
<h3>MyAbout组件</h3>
<hr>
<!-- 说明子路由链接 -->
<router-link to="'/about/tab1"></router-link>
<router-link to="'/about/tab2"></router-link>
<!-- 在关于页面中,声明两个子路由链接 -->
<router-view></router-view>
</div>
</template>
3.2 Children 属性を使用してサブルーティング ルールを宣言する
router.js ルーティング モジュールで、必要なコンポーネントをインポートし、children 属性を使用して子ルーティング ルールを宣言します。サンプルコードは次のとおりです。
router:{
path:'/about',
component:about,
children:[
{
path:'tab1',component:Tab1
},
{
path:'tab2',component:Tab2
}
]
}
4. 動的ルートマッチング
考え方: 次の 3 つのルーティング リンクがあります。
<router-link to="/movie/1">电影1</router-link>
<router-link to="/movie/2">电影2</router-link>
<router-link to="/movie/3">电影3</router-link>
以下の 3 つのルーティング ルールを定義することは可能ですか? 実現可能ですが、再利用性は低いです
{path:'/movie/1", component: Movie }
{path:'/movie/2", component: Movie }
{path:"/movie/3", component: Movie }
4.1 動的ルーティングの概念
動的ルーティングとは、ハッシュアドレスの可変部分をパラメータ項目として定義することで、ルーティングルールの再利用性を向上させます。vue-router で英語のコロン (:) を使用してルーティング パラメータを定義します。サンプルコードは次のとおりです。
//路由中的动态参数以︰进行声明,冒号后面的是动态参数的名称
{path:'/movie/:id',component:Movie}
//字以下3个路由规则,合并成了一个,提高了路由规则的复用性
{path:'/movie/1',component:Movie}
{path:'/movie/2',component:Movie}
{path:'/movie/3',component:Movie}
4.2 $route.params パラメータ オブジェクト
動的ルート マッチングを通じてレンダリングされたコンポーネントでは、$route.params オブジェクトを使用して動的マッチング パラメーター値にアクセスできます。
<template>
<h3>MyMovie组件 --- {
{$route.params.id}}</h3>
</template>
<script>
export default {
name:'MyMovie',
}
</script>
4.3 小道具を使用してルーティングパラメータを受け取る
ルーティング パラメーターの取得形式を簡素化するために、vue-router ではルーティング ルールで props パラメーターの受け渡しを有効にすることができます。サンプルコードは次のとおりです。
//1.在定义路由规则中,声明props:ture选项
// 即可在Movic组件中,以props 的形式接收到路由规则匹配到的参数项
{path:'/momvie/:id',component:Movie,props:ture}
<template>
<div>
<h3>MyMovie组件 --- {
{id}}</h3>
</div>
</template>
<script>
export default {
props:['id'],//使用props接收路由规则中匹配到的参数项
}
</script>
5. プログラムによるナビゲーション
APIを呼び出してナビゲーションを実現する方法をプログラマティックナビゲーションと呼びます。同様に、リンクをクリックして移動する方法は、宣言型ナビゲーションと呼ばれます。例えば:
- 通常の Web ページ内のリンクをクリックしたり、vue プロジェクト内をクリックしたりすることは、宣言型ナビゲーションです。
- 通常の Web ページで location.href を呼び出して新しいページにジャンプする方法は、プログラムによるナビゲーションです。
5.1 vue-router のプログラムによるナビゲーション API
vue-router は多くのプログラムによるナビゲーション API を提供します。最も一般的に使用される 2 つの API は次のとおりです: ① this.$router.push('hash address')
- 指定したハッシュアドレスにジャンプして、対応するコンポーネントを表示します
② this.$router.go(値n)
- 前後のナビゲーション履歴を実現
5.2 $router.push
this.$router.push() メソッドを呼び出すと、指定されたハッシュ アドレスにジャンプして、対応するコンポーネント ページを表示できます。サンプルコードは次のとおりです。
<template>
<div>
<h3>MyHome 组件</h3>
<button type="button" class="btn btn-primary" @click="goToMovie(3)">导航到Movie页面</button>
</div>
</template>
<script>
export default {
name: 'MyHome',
methods: {
goToMovie(id) {
this.$router.push('/movie/${id}')
},
},
}
</script>
<style lang="less" scoped></style>
5.2 $router.go
this.$router.go() メソッドを呼び出して、閲覧履歴を前後に移動します。サンプルコードは次のとおりです。
<template>
<div>
<h3>MyHome 组件</h3>
<button type="button" class="btn btn-primary" @click="goBack)">后退</button>
</div>
</template>
<script>
export default {
name: 'MyHome',
props:["id"],
methods: {
goBack() {
this.$router.go(-1)
},
},
}
</script>
<style lang="less" scoped></style>
6. 名前付きルート
name 属性を使用してルーティング ルールの名前を定義する方法は、名前付きルーティングと呼ばれます。サンプルコードは次のとおりです。
注: 名前付きルートの名前の値は繰り返すことができず、一意である必要があります。
6.1 名前付きルートを使用した宣言型ナビゲーションの実装
to 属性の値を <router-link> タグに動的にバインドし、name 属性を通じてジャンプ先のルーティング ルールを指定します。この期間中、params 属性を使用して、ジャンプ中に伝送されるルーティング パラメーターを指定することもできます。サンプルコードは次のとおりです。
6.2 名前付きルートを使用したプログラムによるナビゲーションの実装
プッシュ関数を呼び出すときに構成オブジェクトを指定します。name はジャンプ先のルーティング ルール、params は転送されるルーティング パラメータです。
7. ナビゲーションガード
ナビゲーション ガードはルートへのアクセスを制御します。概略図は次のとおりです。
7.1 グローバル ナビゲーション ガードを宣言する方法
グローバル ナビゲーション ガードは、各ルーティング ルールをインターセプトして、各ルートのアクセス許可を制御します。グローバル ナビゲーション ガードは次のように定義できます。
7.2 ガード法の 3 つの形式パラメータ
グローバル ナビゲーション ガードのガード メソッドは 3 つの仮パラメータを受け取ります。形式は次のとおりです。
const router = createRouter({...})
//全局前置守卫
router.beforeEach((to,from,next)=>{
//to目标路由对象
//from当前导航正要离开的路由对象
//next上一个函数。表示放行
})
知らせ:
① ガードメソッドで次のパラメータが宣言されていない場合、デフォルトでユーザーはすべてのルートにアクセスできます。② 次の仮パラメータがガード メソッドで宣言されている場合は、 next() 関数を呼び出す必要があります。そうしないと、ユーザーはどのルートにもアクセスできなくなります。
7.3 next 関数を呼び出す 3 つの方法
次の関数の 3 つの呼び出しメソッドの最終結果を分析するには、概略図を参照してください。
直接リリース: next()
現在のページに強制的に留まらせる: next(false)
強制的にログイン ページにジャンプします: next('/login')
7.4 トークンを使用してバックエンド ホームページへのアクセス権を制御する
バックステージ管理ケース
1.ケース効果
2. 事例で使用したナレッジポイント
- 名前付きルート
- ルートリダイレクト
- ナビゲーションガード
- ネストされたルーティング
- 動的ルートマッチング
- プログラムによるナビゲーション
vue-cli、コンポーネント ライブラリ、axios、プロキシ
ビュー-cli
1.vue-cliとは何ですか
vue-cli (通称: vue Scaffolding) は、vue エンジニアリング プロジェクトを迅速に生成するために vue によって公式に提供されるツールです。
特徴:
① 箱から出してすぐに使えます
②Webpackベース
③機能が豊富で拡張が容易
④ vue2、vue3プロジェクトの作成をサポート
vue-cliの中国語公式サイトホームページ:https://cli.vuejs.org/zh/
2.vue-cliをインストールする
vue-cli は Node.js に基づいて開発されたツールであるため、npm を使用してグローバルに利用可能なツールとしてインストールする必要があります。
#全局安装vue-cli
npm install -g @vue/cli
#查看vue-cli的版本,检验vue-cli是否安装成功
vue --version
2.1 Windows PowerShell が vue コマンドを認識しない問題を解決する
デフォルトでは、PowerShell で vue --version コマンドを実行すると、次のエラー メッセージが表示されます。
解決策は次のとおりです。
①PowerShellを管理者として実行
② set-ExecutionPolicy RemoteSigned コマンドを実行する
③ Y という文字を入力し、Enter キーを押します。
3. プロジェクトを作成する
vue-cli は、プロジェクトを作成する 2 つの方法を提供します。
#教育【命令行】的方式创建vue项目
vue create 项目名称
#OR
#基于【可视化模板】创建vue项目
vue ui
4. vue ui に基づいて vue プロジェクトを作成する
ステップ 1: ターミナルで vue ui コマンドを実行して、作成されたプロジェクトのビジュアル パネルをブラウザで自動的に開きます。
ステップ 2: 詳細ページでプロジェクト名を入力します。
ステップ 3: プリセットページで手動設定項目を選択します
ステップ 4: 機能ページでインストールする必要がある機能を確認します (Vue バージョン (不要)、Babel、CSS プリプロセッサ、使用する設定ファイルを選択します)
ステップ 5: 構成ページで vue のバージョンと必要なプリプロセッサを確認する
ステップ 6: 次回プロジェクトを作成するときに以前の構成を直接再利用できるように、今作成したすべての構成をプリセット (テンプレート) として保存します。
ステップ 7: プロジェクトを作成し、依存パッケージを自動的にインストールします。
4. vue ui に基づいて vue プロジェクトを作成する
vue ui の本質: ビジュアル パネルを通じてユーザーの構成情報を収集した後、プロジェクトはコマンド ラインに基づいてバックグラウンドで自動的に初期化されます。
プロジェクトが作成されると、自動的にプロジェクト ダッシュボードに入ります。
5. コマンドラインに基づいて vue プロジェクトを作成します
ステップ 1: ターミナルで vue create Demon2 コマンドを実行し、対話型コマンド ラインに基づいて vue プロジェクトを作成します。
ステップ 2: インストールする機能を選択する
ステップ 3: 上矢印と下矢印を使用して vue のバージョンを選択し、Enter キーを使用して選択を確認します
ステップ 4: 上下の矢印を使用して、使用する CSS プリプロセッサを選択し、Enter キーを使用して選択を確認します。
ステップ 5: 上矢印と下矢印を使用してプラグインの構成情報を保存する方法を選択し、Enter キーを使用して選択を確認します。
ステップ 6: 以前の設定をプリセットとして保存するかどうか:
ステップ 7: プロジェクトに依存関係パッケージをインストールする方法を選択します。
ステップ 8: プロジェクトの作成を開始し、依存パッケージを自動的にインストールする
ステップ 9: プロジェクトの作成が完了します。
6. vue2 プロジェクトの基本構造を整理する
7. main.js のメインコードを分析する
8. vue2 プロジェクトでルーティングを使用する
vue2 プロジェクトでは、vue-router のバージョン 3.x のみをインストールして使用できます。
バージョン 3 とバージョン 4 のルーティングの主な違いは、ルーティング モジュールの作成方法が異なることです。
8.1 復習: バージョン 4.x ルーティング用のルーティング モジュールを作成する方法
8.2 学習: バージョン 3.x ルーティング用のルーティング モジュールを作成する方法
ステップ 1: vue2 プロジェクトにルーティングの 3.x バージョンをインストールします。
ステップ 2: src -> コンポーネント ディレクトリで、ルーティング スイッチングを使用する必要があるコンポーネントを作成します。
ステップ 3: src ディレクトリにルーター -> Index.js ルーティング モジュールを作成します: vue-cli
ステップ 4: main.js にルーティング モジュールをインポートし、ルーター属性: vue-cli を介してマウントします。
ステップ 5: App.vue ルート コンポーネントで、ルートを宣言するプレースホルダーを使用します。
コンポーネントライブラリ
1.vueコンポーネントライブラリとは
実際の開発では、フロントエンド開発者は、他の人がダウンロードして使用できるように、カプセル化された .vue コンポーネントを npm パッケージとして整理、パッケージ化、公開できます。このように直接ダウンロードしてプロジェクトで使用できる既製のコンポーネントは、vue コンポーネント ライブラリと呼ばれます。
2. vueコンポーネントライブラリとブートストラップの違い
この 2 つには、次のような本質的な違いがあります。
Bootstrap は純粋な原材料 (CSS スタイル、HTML 構造、JS 特殊効果) のみを提供するため、開発者によるさらなるアセンブリと変換が必要です。
vue コンポーネント ライブラリは、vue 構文に従い、すぐに使用できる高度にカスタマイズされた既製コンポーネントです。
3. 最も一般的に使用される vue コンポーネント ライブラリ
①PC版
- エレメントUI(https://element.eleme.cn/#/zh-CN)
- ビューUI(http://v1.iviewui.com/)
②モバイル端末
Mint UI(http://mint-ui.github.io/#!/zh-cn)
ヴァント(https://vant-contrib.gitee.io/vant/#/zh-CN/)
4. 要素UI
Element UI は、Ele.me フロントエンド チームによってオープンソース化された PC 側の vue コンポーネント ライブラリです。vue2 および vue3 プロジェクトでの使用をサポートします。
vue2 プロジェクトは古いバージョンの Element UI (https://element.eleme.cn/#/zh-CN) を使用します。
vue3 プロジェクトは、Element Plus の新しいバージョン (https://element-plus.gitee.io/#/zh-CN) を使用します。
4.2 vue2 プロジェクトに element-ui をインストールする
次のターミナル コマンドを実行します。
要素 ui の導入
開発者は、すべての element-ui コンポーネントを一度に完全に導入することも、必要に応じて必要に応じて使用される element-ui コンポーネントのみを導入することもできます。
完全な導入: 操作は簡単ですが、使用されていない追加コンポーネントが導入されるため、プロジェクトのサイズが大きくなりすぎます。
オンデマンド導入: 操作は比較的複雑ですが、使用するコンポーネントのみが導入されるため、プロジェクトのボリュームを最適化できます。
4.3 完全な導入
main.js に次の内容を記述します。
4.4 オンデマンドでの導入
babel-plugin-component の助けを借りて、プロジェクトのサイズを削減するために必要なコンポーネントのみを導入できます。ステップ 1、babel-plugin-component をインストールします。
ステップ 2. ルート ディレクトリの babel.config.js 設定ファイルを変更し、次のようにプラグイン ノードを追加します。
ステップ 3. ボタンなどの一部のコンポーネントのみを導入する場合は、main.js に次の内容を記述する必要があります。
4.5 コンポーネントのインポートと登録を独立したモジュールにカプセル化する
src ディレクトリに新しい element-ui/index.js モジュールを作成し、次のコードを宣言します。
アクシオスインターセプター
1. 復習: vue3 プロジェクトで axios をグローバルに構成する
2. vue2 プロジェクトで axios をグローバルに構成する
Axios は、main.js エントリ ファイル内の Vue コンストラクターのプロトタイプ オブジェクトを通じてグローバルに設定する必要があります。
3. インターセプターとは何ですか?
インターセプター (英語: Interceptors) は、ajax リクエストが行われ、応答が受信されるたびに自動的にトリガーされます。
応用シナリオ: ① トークン ID 認証 ② ローディング効果 ③ etc...
4. リクエストインターセプターの構成
リクエスト インターセプターは、axios.interceptors.request.use (成功コールバック、失敗コールバック) を通じて設定できます。サンプルコードは次のとおりです。
注: 失敗コールバック関数は省略できます。
4.1 リクエストインターセプタ – トークン認証
4.2 リクエストインターセプター – ローディング効果の表示
要素 ui によって提供されるローディング エフェクト コンポーネント (https://element.eleme.cn/#/zh-CN/component/loading) を利用すると、ローディング エフェクトの表示を簡単に実現できます。
5. 応答インターセプターの構成
応答インターセプターは、axios.interceptors.response.use (成功コールバック、失敗コールバック) を通じて設定できます。サンプルコードは次のとおりです。
5.1 レスポンスインターセプター – ローディングエフェクトをオフにする
Loading インスタンスが提供する close() メソッドを呼び出すことで、Loading エフェクトをオフにすることができます。サンプルコードは次のとおりです。
プロキシ クロスドメインプロキシ
1. 復習: インターフェースのクロスドメインの問題
vue プロジェクトが実行されるアドレス: http://localhost:8080/ API インターフェイスが実行されるアドレス: https://www.escook.cn/api/users 現在の API インターフェイスでは CORS クロスドメイン リソースが有効になっていないため、共有の場合、デフォルトでは、上記のインターフェイスは正常にリクエストできません。
2. プロキシを介してインターフェイス上のクロスドメインの問題を解決する
vue-cli を通じて作成されたプロジェクトでクロスドメイン インターフェイスの問題が発生した場合、プロキシを通じて解決できます。
① axios のリクエストルートパスを vue プロジェクトの実行アドレスに設定します (インターフェースリクエストはクロスドメインではなくなりました)
② vue プロジェクトは、要求されたインターフェイスが存在しないことを検出し、要求をプロキシに転送します。
③ プロキシは、リクエストのルート パスを devServer.proxy 属性の値に置き換え、実際のデータ リクエストを開始します。
④エージェントは要求されたデータをaxiosに転送します。
3. プロジェクトでプロキシ プロキシを設定します。
ステップ 1. main.js エントリ ファイルで、axios のリクエスト ルート パスを現在の Web プロジェクトのルート パスに変更します。
ステップ 2. プロジェクトのルート ディレクトリに vue.config.js 構成ファイルを作成し、次の構成を宣言します。 注:
① devServer.proxy が提供するプロキシ機能は、開発およびデバッグフェーズでのみ有効です。
② プロジェクトがオンラインで起動される場合、API インターフェイス サーバーは CORS クロスドメイン リソース共有を有効にする必要があります。
ユーザーリストの場合
1.ケース効果
2. 使用されるナレッジポイント
vue-cli は vue2 プロジェクトを作成します
要素 ui コンポーネント ライブラリ
アクシオスインターセプター
プロキシ クロスドメイン インターフェイス プロキシ
vuer-ルータールーティング
3. 全体的な実装手順
①初期化プロジェクト
② ユーザーテーブルデータのレンダリング
③グローバルフィルターに基づく処理時間フォーマット
④ ユーザーの追加操作を実施する
⑤ ユーザーの削除操作を実施する
⑥ ルーティングで詳細ページへジャンプ