1、視圖更新注意事項
直接修改數組中的某個值是不會出發視圖更新的。比如:
this.books[0] = ‘Python’;
這種情況應該改成用splice或者是用Vue.set方法來實現:
Vue.set(this.books,0,‘Python’);
如果動態的給對象添加屬性,也不會觸發視圖更新。只能通過Vue.set來添加。比如:
<div id="app">
<ul>
<li v-for="(value,name) in person">{{name}}:{{value}}</li>
</ul>
<script>
let vm = new Vue({
el: "#app",
data: {
person: {"username": '邏輯教育'}
},
methods: {
changePerson: function(event){
Vue.set(this.person,'age',18)
}
}
});
</script>
</div>
2、事件綁定
事件綁定就是在HTML元素中,通過v-on綁定事件的。事件代碼可以直接放到v-on後面,也可以寫成一個函數。
<div id="app">
<p>{{count}}</p>
<button v-on:click="count+=1">加</button>
<button v-on:click="subtract(10)">減10</button>
</div>
<script>
let vm = new Vue({
el: "#app",
data: {
count: 0
},
methods: {
subtract: function(value){
this.count -= value;
}
}
});
</script>
傳入event參數
如果在事件處理函數中,想要獲取原生的DOM事件,那麼在html代碼中,調用的時候,可以傳遞一個$event參數。
<button v-on:click="subtract(10,$event)">減10</button>
...
<script>
...
methods: {
subtract: function(value,event){
this.count -= value;
console.log(event); //相當於打印輸出
//alert(123) 彈出窗口顯示123
}
}
...
</script>
3、計算屬性和監聽器
一般情況下屬性都是放到data中的,但是有些屬性可能是需要經過一些邏輯計算後才能得出來,那麼我們可以把這類屬性變成計算屬性。比如以下:
<!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">
<label>長:</label>
<!-- type="number" 只能輸入數字 -->
<!-- v-model 雙向綁定 不能省略 -->
<input type="number" name="length" v-model:value="length">
<label>寬:</label>
<input type="number" name="width" v-model:value="width">
<label>面積:</label>
<input type="number" readonly v-bind:value="area">
</div>
</body>
</html>
<!--vue引入 必須聯網-->
<script src="https://cdn.jsdelivr.net/npm/vue"></script>
<script>
new Vue({
el:"#app",
data:{
length:0, //和上面的v-model:value 雙向綁定,爲了獲取當前值
width:0,
},
//計算屬性
computed:{
area:function(){
console.log(this.length, this.width)
return this.length*this.width
}
}
})
</script>
計算屬性更加智能,他是基於它們的響應式依賴進行緩存的。也就是說只要相關依賴(比如以上例子中的area)沒有發生改變,那麼這個計算屬性的函數不會重新執行,而是直接返回之前的值。這個緩存功能讓計算屬性訪問更加高效。(即之前運行過的結果會被緩存下來,後面如果繼續計算,可以直接返回緩存的值)
計算屬性的set:
計算屬性默認只有get,不過在需要時你也可以提供一個set,但是提供了set就必須要提供get方法。
示例代碼如下:
<!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">
<div>
<label>省:</label>
<input type="text" v-model:value="province">
<label>市:</label>
<input type="text" v-model:value="city">
<label>區:</label>
<input type="text" v-model:value="area">
<label>詳細地址:</label>
<input type="text" v-model:value="address">
</div>
</div>
</body>
</html>
<!--vue引入 必須聯網-->
<script src="https://cdn.jsdelivr.net/npm/vue"></script>
<script>
new Vue({
el:"#app",
data:{
length:0, //和上面的v-model:value 雙向綁定,爲了獲取當前值
width:0,
province:'',
city:'',
area:'',
//address:'', 這裏不能設置
},
//計算屬性
computed:{
address:{
get:function(){
var result = ""
if(this.province){
result =this.province + "省"
}
if(this.city){
result +=this.city + "市"
}
if(this.area){
result +=this.area + "區"
}
return result
},
set:function(value){
//console.log(value)
var result = value.split(/省|市|區/) //正則表達
if(result && result.length > 0){
this.province=result[0]
}
if(result && result.length > 1){
this.city=result[1]
}
if(result && result.length > 2){
this.area=result[2]
}
}
}
}
})
</script>
4、監聽屬性
監聽屬性可以針對某個屬性進行監聽,只要這個屬性的值發生改變了,那麼就會執行相應的函數。示例代碼如下:
<!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">
<label>搜索:</label>
<input type="text" name="keyword" v-model:value="keyword">
<p>結果:</p>
<p>{{answer}}</p>
</div>
</body>
</html>
<!--vue引入 必須聯網-->
<script src="https://cdn.jsdelivr.net/npm/vue"></script>
<script>
new Vue({
el:"#app",
data:{
keyword:"", //注意這裏是:,不是=
answer:'',
},
//監聽屬性
watch:{
keyword:function(new_value, value){
console.log(value)
console.log(new_value)
this.answer="加載中。。。"
//定時器
setTimeout(() => {
this.answer="搜索結果" + new_value
}, 1000); //延遲1000ms之後執行
}
}
})
</script>
5、表單輸入綁定
v-model指定可以實現表單值與屬性的雙向綁定。即表單元素中更改了值會自動的更新屬性中的值,屬性中的值更新了會自動更新表單中的值。
綁定的屬性和事件:
v-model在內部爲不同的輸入元素使用不同的屬性並拋出不同的事件:
- text和textarea元素使用value屬性和input事件。
- checkbox和radio使用checked屬性和change事件。
- select字段將value作爲prop並將change作爲事件。
表單元素綁定
- input綁定
- textarea綁定
- checkbox綁定
- radio綁定
- select綁定
實例如下:
<!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">
<!-- input綁定 -->
<input type="text" v-model:value="message" placeholder="請輸入...">
<!-- textarea綁定 -->
<textarea name="" v-model:value="message" cols="30" rows="10"></textarea>
<p>輸入的內容是:{{message}}</p>
<!-- checkbox綁定 -->
<input type="checkbox" value="Jack" v-model="checkedNames">
<label for="jack">Jack</label>
<input type="checkbox" value="John" v-model="checkedNames">
<label for="john">John</label>
<input type="checkbox" value="Mike" v-model="checkedNames">
<label for="mike">Mike</label>
<br>
<span>Checked names: {{ checkedNames }}</span>
<!-- radio綁定 -->
<input type="radio" value="男" v-model="gender">
<label>男</label>
<br>
<input type="radio" value="女" v-model="gender">
<label>女</label>
<br>
<span>Picked: {{ gender }}</span>
<!-- select綁定 -->
<select v-model="selected">
<option disabled value="">請選擇</option>
<!-- 如果有value值 選擇的就是value值 -->
<option value="1">A</option>
<option>B</option>
<option>C</option>
</select>
<span>Selected: {{ selected }}</span>
</div>
</body>
</html>
<!--vue引入 必須聯網-->
<script src="https://cdn.jsdelivr.net/npm/vue"></script>
<script>
new Vue({
el:"#app",
data:{
message:'',
checkedNames:[],
gender:'',
selected:'',
}
})
</script>
6、修飾符
-
.lazy
在默認情況下,v-model在每次input事件觸發後將輸入框的值與數據進行同步 (除了上述輸入法組合文字時)。你可以添加lazy修飾符,從而轉變爲使用change事件進行同步: -
.number
如果想自動將用戶的輸入值轉爲數值類型,可以給v-model添加number修飾符
這通常很有用,因爲即使在type="number"時,HTML輸入元素的值也總會返回字符串。如果這個值無法被parseFloat()解析,則會返回原始的值。
<input v-model.number="age" type="number">
- .trim
如果要自動過濾用戶輸入的首尾空白字符,可以給 v-model 添加 trim 修飾符
<input v-model.trim="msg">
<!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">
<!-- .lazy修飾符 -->
<input type="text" v-model:value.lazy="message" placeholder="請輸入...">
<!-- 下面的語句時常用的 -->
<input type="text" v-model.lazy="message" placeholder="請輸入...">
<!-- .number 如果想自動將用戶的輸入值轉爲數值類型,可以給v-model添加number修飾符 -->
<input v-model.number="age" type="number">
<p>輸入內容是:{{message}}</p>
<!-- .trim 如果要自動過濾用戶輸入的首尾空白字符,可以給 v-model 添加 trim 修飾符 -->
<input type='text' v-model.trim="msg">
<p>{msg}</p>
</div>
</body>
</html>
<!--vue引入 必須聯網-->
<script src="https://cdn.jsdelivr.net/npm/vue"></script>
<script>
new Vue({
el:"#app",
data:{
message:"",
age:"",
msg:"",
}
})
</script>
7、自定義組件
有時候有一組html結構的代碼,並且這個上面可能還綁定了事件。然後這段代碼可能有多個地方都被使用到了,如果都是拷貝來拷貝去,很多代碼都是重複的,包括事件部分的代碼都是重複的。那麼這時候我們就可以把這些代碼封裝成一個組件,以後在使用的時候就跟使用普通的html元素一樣,拿過來用就可以了。
基本使用
<!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">
<button_count> </button_count>
<!-- 可以多次調用,代碼已經封裝,代碼簡化 -->
<button_count> </button_count>
<button_count> </button_count>
<button_count> </button_count>
</div>
</body>
</html>
<!--vue引入 必須聯網-->
<script src="https://cdn.jsdelivr.net/npm/vue"></script>
<script>
//自定義組件 button_count標籤名字
Vue.component('button_count',{
template:'<button @click="count += 1">點擊了{{count}}次</button>', //button_count中封裝的內容模板就是這句
data:function(){ //這裏的data寫法不同於new vue中的,需要是函數
return { //這裏需要{}
count:0
}
}
})
new Vue({
el:"#app",
data:{
}
})
</script>
以上我們創建了一個叫做button-count的組件,這個組件實現了能夠記錄點擊了多少次按鈕的功能。後期如果我們想要使用,就直接通過button-count使用就可以了。然後因爲組件是可複用的Vue實例,所以它們與new Vue接收相同的選項,例如data、computed、watch、methods以及生命週期鉤子等。僅有的例外是像el這樣根實例特有的選項。另外需要注意的是:組件中的data必須爲一個函數!