1.屬性綁定v-bind(:)
v-bind
是 Vue 2 中用于動態綁定屬性的核心指令,它支持多種語法和用法,能夠靈活地綁定 DOM 屬性、組件 prop,甚至動態屬性名。通過 v-bind
,可以實現數據與視圖之間的高效同步,是構建動態界面的重要工具。
<template><div class="demo-container"><!-- 基礎屬性綁定 --><div :id="dynamicId">動態 ID 的 div</div><!-- 綁定多個屬性 --><div :="{ id: dynamicId, title: dynamicTitle, class: 'my-class' }">綁定多個屬性</div><!-- 動態屬性名 --><div :[attributeName]="attributeValue">動態屬性名綁定</div><!-- 布爾屬性綁定 --><button :disabled="isDisabled">點擊我</button><!-- 綁定組件的 prop --><child-component :message="parentMessage" :title.sync="parentTitle"></child-component></div>
</template><script>
// 定義子組件
const ChildComponent = {props: {message: String,title: String},template: `<div><h3>子組件</h3><p>從父組件接收到的 message: {{ message }}</p><p>從父組件接收到的 title: {{ title }}</p><button @click="updateTitle">更新父組件的 title</button></div>`,methods: {updateTitle() {// 使用 $emit 觸發父組件的更新this.$emit('update:title', '新的標題');}}
};export default {name: "demo",components: {ChildComponent},data() {return {dynamicId: 'my-dynamic-id', // 動態 IDdynamicTitle: '這是一個標題', // 動態標題attributeName: 'class', // 動態屬性名attributeValue: 'my-class', // 動態屬性值isDisabled: false, // 布爾屬性parentMessage: 'Hello from parent!', // 父組件的 messageparentTitle: '初始標題' // 父組件的 title};}
};
</script><style scoped>
.demo-container {margin: 20px;padding: 20px;border: 1px solid #ccc;
}
.my-class {color: blue;font-weight: bold;
}
button {margin-top: 10px;
}
</style>
1.1示例代碼中的父子組件通信
-
父組件向子組件傳遞數據
-
父組件在模板中使用
:message="parentMessage"
和:title.sync="parentTitle"
。 -
Vue 會將
parentMessage
和parentTitle
的值傳遞給子組件的message
和title
。 -
子組件通過
props
接收這些值,并可以在模板中使用。
-
-
子組件向父組件傳遞事件
-
子組件在模板中有一個按鈕,點擊按鈕時調用
updateTitle
方法。 -
updateTitle
方法通過this.$emit('update:title', '新的標題')
觸發一個自定義事件update:title
,并傳遞新值'新的標題'
。 -
父組件監聽到
update:title
事件后,會自動更新parentTitle
的值為'新的標題'
。
-
1.2面試問題:
-
如何實現父子組件之間的數據傳遞?
-
父組件如何向子組件傳遞數據?
-
子組件如何向父組件傳遞事件?
回答要點:
-
父組件向子組件傳遞數據: 使用
props
。-
父組件通過
v-bind
將數據綁定到子組件的props
。 -
子組件通過
props
接收父組件傳遞的數據。
-
-
子組件向父組件傳遞事件: 使用
$emit
。-
子組件通過
this.$emit
觸發一個自定義事件,并傳遞數據。 -
父組件通過監聽子組件的事件來接收數據。
<!-- 父組件 --> <template><div><child-component :message="parentMessage" @update:title="handleTitleUpdate"></child-component></div> </template><script> import ChildComponent from './ChildComponent.vue';export default {components: {ChildComponent},data() {return {parentMessage: 'Hello from parent!',parentTitle: 'Initial Title'};},methods: {handleTitleUpdate(newTitle) {this.parentTitle = newTitle;}} }; </script>
<!-- 子組件 --> <template><div><p>Message from parent: {{ message }}</p><button @click="updateTitle">Update Parent Title</button></div> </template><script> export default {props: {message: String},methods: {updateTitle() {this.$emit('update:title', 'New Title');}} }; </script>
-
.sync
修飾符的作用-
簡化父子組件之間的雙向綁定。
-
-
2.事件綁定?v-on(@)
v-on
是 Vue.js 中用于綁定事件監聽器的指令,它允許你為 DOM 元素或組件綁定事件處理函數。通過 v-on
,你可以監聽用戶的交互行為(如點擊、輸入等),并在事件觸發時執行特定的邏輯。
<template><div><h1>事件綁定示例</h1><button @click="handleClick">點擊我</button><input type="text" @input="handleInput($event)"><a href="https://example.com" @click.prevent="handleLinkClick">鏈接</a><div @click="handleDivClick"><button @click.stop="handleButtonClick">點擊我</button></div><input type="text" @keyup.enter="handleSubmit"></div>
</template><script>
export default {methods: {handleClick() {alert('按鈕被點擊了!');},handleInput(event) {console.log('輸入框的值:', event.target.value);},handleLinkClick() {alert('鏈接被點擊了,但不會跳轉!');},handleDivClick() {alert('div 被點擊了!');},handleButtonClick() {alert('按鈕被點擊了,但不會觸發 div 的點擊事件!');},handleSubmit() {alert('回車鍵被按下,表單提交!');}}
};
</script>
2.1基本用法
1. 監聽原生 DOM 事件
v-on
可以用來監聽原生 DOM 事件,例如 click
、input
、mouseover
等。
<button @click="handleClick">點擊我</button>
2. 監聽組件事件
v-on
也可以用來監聽自定義組件的事件。子組件通過 $emit
觸發事件,父組件通過 v-on
監聽這些事件。
<child-component @custom-event="handleCustomEvent"></child-component>
-
custom-event
是子組件觸發的自定義事件。 -
handleCustomEvent
是父組件中定義的事件處理函數。
3. 傳遞事件參數?
在事件處理函數中,你可能需要訪問事件對象(例如獲取輸入框的值或鼠標的位置)。可以通過 $event
獲取事件對象。
<input type="text" @input="handleInput($event)">
4. 傳遞額外參數
除了事件對象,你還可以傳遞其他參數到事件處理函數。
<button @click="handleClick('Hello', $event)">點擊我</button>methods: {handleClick(message, event) {console.log(message); // 輸出 "Hello"console.log(event.type); // 輸出 "click"}
}
5.事件修飾符
Vue 為 v-on
提供了一些事件修飾符,用于更方便地處理常見的事件行為。
?.stop
:阻止事件冒泡
-
點擊按鈕時,
handleButtonClick
會被觸發,但不會觸發handleDivClick
。
<div @click="handleDivClick"><button @click.stop="handleButtonClick">點擊我</button>
</div>
.prevent
:阻止默認行為
-
點擊鏈接時,不會跳轉到
https://example.com
,因為默認行為被阻止了。
<a href="https://example.com" @click.prevent="handleLinkClick">鏈接</a>
.capture
:使用事件捕獲模式
-
在事件冒泡階段,
handleDivClick
會在handleButtonClick
之前被觸發。
<div @click.capture="handleDivClick"><button @click="handleButtonClick">點擊我</button>
</div>
.self
:只觸發綁定元素自身的事件
-
只有直接點擊按鈕時,
handleButtonClick
才會被觸發。
<div @click="handleDivClick"><button @click.self="handleButtonClick">點擊我</button>
</div>
.once
:事件只觸發一次
-
handleClick
只會在第一次點擊時被觸發,之后的點擊不會觸發。
2.2總結
v-on
是 Vue 中非常強大的指令,用于綁定事件監聽器。它支持以下功能:
-
監聽原生 DOM 事件和自定義組件事件。
-
傳遞事件對象和額外參數。
-
使用事件修飾符(如
.stop
、.prevent
、.capture
等)簡化事件處理邏輯。 -
使用鍵盤修飾符(如
.enter
、.tab
等)處理鍵盤事件。
?3.雙向綁定v-model
v-model
是 Vue 中實現雙向數據綁定的核心指令,它允許你將表單輸入和應用狀態進行同步。通過 v-model
,表單元素的值會自動與 Vue 實例的數據保持一致,同時用戶對表單的修改也會實時更新到數據中,反之亦然。這種雙向綁定機制是 Vue 的一大特色,極大地簡化了表單處理邏輯。
3.1基本用法
<template><div class="v-model-demo"><h2>v-model 雙向綁定示例</h2><!-- 輸入框 --><div><label for="text-input">輸入框:</label><input id="text-input" v-model="message" placeholder="輸入內容"><p>輸入的內容是:{{ message }}</p></div><!-- 多行文本框 --><div><label for="textarea">多行文本框:</label><textarea id="textarea" v-model="multiLineMessage" placeholder="輸入多行內容"></textarea><p>輸入的內容是:</p><p style="white-space: pre">{{ multiLineMessage }}</p></div><!-- 單個復選框 --><div><label><input type="checkbox" v-model="singleCheckbox"> 單個復選框</label><p>復選框是否選中:{{ singleCheckbox }}</p></div><!-- 多個復選框 --><div><label><input type="checkbox" v-model="checkedCities" value="北京"> 北京</label><label><input type="checkbox" v-model="checkedCities" value="上海"> 上海</label><label><input type="checkbox" v-model="checkedCities" value="廣州"> 廣州</label><p>選中的城市:{{ checkedCities }}</p></div><!-- 單選按鈕 --><div><label><input type="radio" v-model="picked" value="A"> A</label><label><input type="radio" v-model="picked" value="B"> B</label><p>選中的選項是:{{ picked }}</p></div><!-- 下拉選擇框 --><div><label for="select">下拉選擇框:</label><select id="select" v-model="selected"><option disabled value="">請選擇</option><option value="北京">北京</option><option value="上海">上海</option><option value="廣州">廣州</option></select><p>選中的城市是:{{ selected }}</p></div></div>
</template><script>
export default {name: "VModelDemo",data() {return {message: "", // 輸入框綁定的數據multiLineMessage: "", // 多行文本框綁定的數據singleCheckbox: false, // 單個復選框綁定的數據checkedCities: [], // 多個復選框綁定的數據picked: "", // 單選按鈕綁定的數據selected: "" // 下拉選擇框綁定的數據};}
};
</script><style scoped>
.v-model-demo {margin: 20px;font-family: Arial, sans-serif;
}
label {margin-right: 10px;
}
p {margin: 10px 0;
}
textarea {width: 100%;height: 100px;
}
select {width: 100%;
}
</style>
v-model
?的工作原理
v-model
實際上是一個語法糖,它背后做了以下幾件事:
-
綁定
value
屬性:-
對于
<input>
和<textarea>
,v-model
會綁定value
屬性。 -
對于
<select>
,v-model
會綁定value
屬性到選中的<option>
。 -
對于
<input type="checkbox">
和<input type="radio">
,v-model
會綁定value
屬性到對應的值。
-
-
監聽
input
或change
事件:-
v-model
會監聽表單元素的input
事件(對于<input>
和<textarea>
)或change
事件(對于<select>
、<input type="checkbox">
和<input type="radio">
)。 -
當事件觸發時,它會自動更新綁定的數據。
-
3.2v-model
?修飾符?
<template><div class="v-model-modifiers-demo"><h2>v-model 修飾符示例</h2><!-- .lazy 修飾符 --><div><label for="lazy-input">輸入框(.lazy):</label><input id="lazy-input" v-model.lazy="lazyMessage" placeholder="輸入內容"><p>輸入的內容是:{{ lazyMessage }}</p><!--.lazy 修飾符:- 默認情況下,v-model 在每次 input 事件觸發時更新數據。- 使用 .lazy 修飾符后,數據會在 change 事件觸發時更新,即用戶離開輸入框時。--></div><!-- .number 修飾符 --><div><label for="number-input">輸入框(.number):</label><input id="number-input" v-model.number="numberValue" type="number" placeholder="輸入數字"><p>輸入的數字是:{{ numberValue }}</p><!--.number 修飾符:- 默認情況下,v-model 會將輸入框的值作為字符串處理。- 使用 .number 修飾符后,輸入框的值會自動轉換為數字類型。--></div><!-- .trim 修飾符 --><div><label for="trim-input">輸入框(.trim):</label><input id="trim-input" v-model.trim="trimMessage" placeholder="輸入內容"><p>輸入的內容是:{{ trimMessage }}</p><!--.trim 修飾符:- 默認情況下,v-model 會保留輸入框的首尾空格。- 使用 .trim 修飾符后,輸入框的值會自動去除首尾空格。--></div></div>
</template><script>
export default {name: "VModelModifiersDemo",data() {return {lazyMessage: "", // .lazy 修飾符綁定的數據numberValue: 0, // .number 修飾符綁定的數據trimMessage: "" // .trim 修飾符綁定的數據};}
};
</script><style scoped>
.v-model-modifiers-demo {margin: 20px;font-family: Arial, sans-serif;
}
label {margin-right: 10px;
}
p {margin: 10px 0;
}
input {width: 100%;padding: 8px;margin-bottom: 10px;
}
</style>
-
輸入框(.lazy):
-
用戶輸入內容時,數據不會立即更新,直到用戶離開輸入框(觸發
change
事件)。 -
{{ lazyMessage }}
會顯示最終的輸入內容。
-
-
輸入框(.number):
-
用戶輸入數字時,數據會自動轉換為數字類型。
-
{{ numberValue }}
會顯示數字類型的值。
-
-
輸入框(.trim):
-
用戶輸入內容時,首尾空格會被自動去除。
-
{{ trimMessage }}
會顯示去除首尾空格后的內容。
-
3.3自定義組件中的?v-model
?
在自定義組件中,v-model
默認綁定的是子組件的 value
屬性和 input
事件。如果你需要自定義 v-model
的行為,可以通過 props
和 $emit
來實現。
<template><div><custom-input v-model="message"></custom-input><p>輸入的內容是:{{ message }}</p></div>
</template><script>
import CustomInput from './CustomInput.vue';export default {components: {CustomInput},data() {return {message: ''};}
};
</script>
<!-- CustomInput.vue -->
<template><input:value="value"@input="$emit('input', $event.target.value)"placeholder="輸入內容">
</template><script>
export default {props: ['value']
};
</script>
-
工作原理
-
父組件傳遞數據到子組件:
-
父組件通過
v-model="message"
將message
的值傳遞給子組件的value
prop
。 -
子組件的
value
prop
會接收這個值,并將其綁定到輸入框的value
屬性上。
-
-
子組件向父組件發送數據:
-
當用戶在輸入框中輸入內容時,
input
事件被觸發。 -
子組件通過
$emit('input', $event.target.value)
將用戶輸入的值發送回父組件。 -
父組件監聽到
input
事件后,會更新message
的值。
-
-
雙向綁定:
-
父組件的
message
和子組件的輸入框內容始終保持同步。 -
用戶在輸入框中輸入的內容會實時更新到父組件的
message
中。 -
父組件的
message
如果發生變化,輸入框的內容也會自動更新。
-
4.計算屬性?Computed
在 Vue 2 中,計算屬性(Computed Properties)是一種非常強大的功能,它允許你基于 Vue 實例的數據動態計算值。計算屬性是響應式的,當依賴的響應式數據發生變化時,計算屬性會自動重新計算并更新。
計算屬性通常用于以下場景:
-
基于現有數據派生新數據:例如,將用戶的輸入轉換為大寫或計算總價。
-
簡化模板邏輯:避免在模板中編寫復雜的邏輯。
-
緩存計算結果:計算屬性會緩存結果,只有當依賴的數據發生變化時才會重新計算。
計算屬性通過 computed
選項定義。計算屬性的值由一個函數返回,這個函數的返回值會自動綁定到模板中。
<template><div><p>原字符串:{{ message }}</p><p>大寫字符串:{{ upperCaseMessage }}</p></div>
</template><script>
export default {data() {return {message: 'hello'};},computed: {upperCaseMessage() {return this.message.toUpperCase();}}
};
</script>
?
-
data
:定義了響應式數據message
。 -
computed
:定義了計算屬性upperCaseMessage
。-
upperCaseMessage
是一個函數,返回message
的大寫形式。 -
計算屬性的值會自動更新,當
message
發生變化時,upperCaseMessage
也會重新計算。
-
計算屬性的緩存機制
計算屬性是基于它們的依賴進行緩存的。只有當依賴的響應式數據發生變化時,計算屬性才會重新計算。這意味著如果你的依賴數據沒有變化,計算屬性的值不會重新計算,從而提高性能。
計算屬性與方法的區別
計算屬性和方法都可以基于數據動態計算值,但它們有一些關鍵區別:
-
緩存機制:
-
計算屬性:會緩存結果,只有當依賴的響應式數據發生變化時才會重新計算。
-
方法:每次調用都會重新計算,不會緩存結果。
-
-
使用場景:
-
計算屬性:適用于基于現有數據派生新數據的場景,尤其是需要緩存結果的場景。
-
方法:適用于需要動態執行的邏輯,例如事件處理函數。
-
?