文章目錄
- 1.計算屬性computed
- 2.監聽watch
- 3.過濾器filter
- 4.表單、複選框
- 4.1. 多選checkbox
- 4.2. 單選radio
- 4.3.下拉select
- 5.修飾符
- 6.元件化
- 7.生命周期鈎子函數
1.計算屬性computed
什麼是計算屬性:屬性不是具體值,而是通過一個函數計算出來的,随時變化
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
<div id="app">
<p>原始字元串: {{ message }}</p>
<p>計算後反轉字元串: {{ reversedMessage }}</p>
<p>計算後反轉字元串: {{ reversedMessage2() }}</p>
</div>
<script src="./node_modules/vue/dist/vue.js"></script>
<script>
var vm = new Vue({
el: '#app',
data: {
message: 'Runoob!'
},
computed: {
// 計算屬性的 getter
reversedMessage: function () {
// `this` 指向 vm 執行個體
return this.message.split('').reverse().join('')
}
},
methods: {
reversedMessage2: function () {
return this.message.split('').reverse().join('')
}
}
})
</script>
</body>
</html>
這裡可以比較一下計算和method之間的差別
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
<div id="div">
<p>{{message}}</p>
<button id="btn" v-on:click="change">點選翻譯成中文</button>
</div>
<script src="./node_modules/vue/dist/vue.js"></script>
<!--引入vue js 外部檔案-->
<script> //vue js 代碼寫在這裡
var a = new Vue({
el: "#div",
data: { message: "good good study" },
methods: {
change: function () {
alert("測試");
this.message = "天天向上"
}
}
});
</script>
</body>
</html>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
<div id="div">
<input v-model="firstName">
<input v-model="lastName">
<br />
<p>{{fullName}}</p>
</div>
<body>
<script src="./node_modules/vue/dist/vue.js"></script>
<script>
var vm = new Vue({
el: '#div',
data: {
firstName: 'zheng',
lastName: 'zeling'
},
computed: {
fullName: function () {
return this.firstName + ' ' + this.lastName
}
}
})
</script>
</html>
因為 input 框使用了 v-model 雙向綁定了 firstName 這個資料值,是以當修改輸入框内容時,firstName 也跟随變化;而又因為 computed 計算屬性 fullName 的傳回值依賴于 firstName,是以一旦 firstName 發生變化,fullName 馬上被觸發
computed (計算屬性) 和 methods (方法) 的差別:
我們可以将同一函數定義為一個方法而不是一個計算屬性。兩種方式的最終結果确實是完全相同的。然而,不同的是計算屬性是基于它們的依賴進行緩存的。隻在相關依賴發生改變時它們才會重新求值。這就意味着隻要 message 還沒有發生改變,多次通路 reversedMessage 計算屬性會立即傳回之前的計算結果,而不必再次執行函數。
也就是說:
函數執行需要 資料屬性裡面的 message 值作為參數。
● 如果使用 methods 執行函數,vue 每次都要重新執行一次函數,不管message 的值是否有變化;
● 如果使用computed 執行函數,隻有當message 這個最初的資料發生變化時,函數才會被執行。(依賴-監測資料變化)
2.監聽watch
監聽屬性 watch,我們可以通過 watch 來響應資料的變化。
以下執行個體通過使用 watch 實作計數器:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
<div id="app">
<p style="font-size:25px;">計數器: {{ counter }}</p>
<button @click="counter++" style="font-size:25px;">點我</button>
</div>
<script src="./node_modules/vue/dist/vue.js"></script>
<script type="text/javascript">
var vm = new Vue({
el: '#app',
data: {
counter: 1
}
});
vm.$watch('counter', function (nval, oval) { // new old
alert('計數器值的變化 :' + oval + ' 變為 ' + nval + '!');
});
</script>
</body>
</html>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
<div id="app">
<!-- 某些結果是基于之前資料實時計算出來的,我們可以利用計算屬性。來完成 -->
<ul>
<li>西遊記; 價格:{{xyjPrice}},數量:<input type="number" v-model="xyjNum"> </li>
<li>水浒傳; 價格:{{shzPrice}},數量:<input type="number" v-model="shzNum"> </li>
<li>總價:{{totalPrice}}</li>
{{msg}}
</ul>
</div>
<script src="./node_modules/vue/dist/vue.js"></script>
<script>
//watch可以讓我們監控一個值的變化。進而做出相應的反應。
new Vue({
el: "#app",
data: {
xyjPrice: 99.98,
shzPrice: 98.00,
xyjNum: 1,
shzNum: 1,
msg: ""
},
computed: {
totalPrice(){
return this.xyjPrice*this.xyjNum + this.shzPrice*this.shzNum
}
},
watch: {
xyjNum: function(newVal,oldVal){
if(newVal>=3){
this.msg = "庫存超出限制";
this.xyjNum = 3
}else{
this.msg = "";
}
}
},
})
</script>
</body>
</html>
3.過濾器filter
定義filter元件後,管道符後面跟具體過濾器{{
user.gender
|
gFilter
}}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
<!-- 過濾器常用來處理文本格式化的操作。過濾器可以用在兩個地方:雙花括号插值和 v-bind 表達式 -->
<div id="app">
<ul>
<li v-for="user in userList">
{{user.id}} ==> {{user.name}} ==> {{user.gender == 1?"男":"女"}} ==>
{{user.gender | genderFilter}} ==> {{user.gender | gFilter}}
</li>
</ul>
</div>
<script src="./node_modules/vue/dist/vue.js"></script>
<script>
// 全局過濾器
Vue.filter("gFilter", function (val) {
if (val == 1) {
return "男~~~";
} else {
return "女~~~";
}
})
let vm = new Vue({
el: "#app",
data: {
userList: [
{ id: 1, name: 'jacky', gender: 1 },
{ id: 2, name: 'peter', gender: 0 }
]
},
filters: { // 局部過濾器,隻可以在目前vue執行個體中使用
genderFilter(val) {
if (val == 1) {
return "男";
} else {
return "女";
}
}
}
})
</script>
</body>
</html>
4.表單、複選框
https://www.runoob.com/vue2/vue-forms.html
4.1. 多選checkbox
雖然v-model指定了同個值,但是會收內建數組。示範:https://www.runoob.com/try/try.php?filename=vue2-form2
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
<div id="app">
<p>單個複選框:</p>
<input type="checkbox" id="checkbox" v-model="checked">
<label for="checkbox">{{ checked }}</label>
<p>多個複選框:</p>
<input type="checkbox" id="runoob" value="Runoob" v-model="checkedNames">
<label for="runoob">Runoob</label>
<input type="checkbox" id="google" value="Google" v-model="checkedNames">
<label for="google">Google</label>
<input type="checkbox" id="taobao" value="Taobao" v-model="checkedNames">
<label for="taobao">taobao</label>
<br>
<span>選擇的值為: {{ checkedNames }}</span>
</div>
<script src="./node_modules/vue/dist/vue.js"></script>
<script>
new Vue({
el: '#app',
data: {
checked : false,
checkedNames: []
}
})
</script>
</body>
</html>
4.2. 單選radio
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
<div id="app">
<input type="radio" id="runoob" value="Runoob" v-model="picked">
<label for="runoob">Runoob</label>
<br>
<input type="radio" id="google" value="Google" v-model="picked">
<label for="google">Google</label>
<br>
<span>選中值為: {{ picked }}</span>
</div>
<script src="./node_modules/vue/dist/vue.js"></script>
<script>
new Vue({
el: '#app',
data: {
picked: 'Runoob'
}
})
</script>
</body>
</html>
4.3.下拉select
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
<div id="app">
<select v-model="selected" name="fruit">
<option value="">選擇一個網站</option>
<option value="www.runoob.com">Runoob</option>
<option value="www.google.com">Google</option>
</select>
<div id="output">
選擇的網站是: {{selected}}
</div>
</div>
<script src="./node_modules/vue/dist/vue.js"></script>
<script>
new Vue({
el: '#app',
data: {
selected: ''
}
})
</script>
</body>
</html>
5.修飾符
.lazy
在預設情況下, v-model 在 input 事件中同步輸入框的值與資料,但你可以添加一個修飾符 lazy ,進而轉變為在 change 事件中同步:
<!-- 在 "change" 而不是 "input" 事件中更新 -->
<input v-model.lazy="msg" >
.number
如果想自動将使用者的輸入值轉為 Number 類型(如果原值的轉換結果為 NaN 則傳回原值),可以添加一個修飾符 number 給 v-model 來處理輸入值:
<input v-model.number="age" type="number">
這通常很有用,因為在 type=“number” 時 HTML 中輸入的值也總是會傳回字元串類型。
.trim
如果要自動過濾使用者輸入的首尾空格,可以添加 trim 修飾符到 v-model 上過濾輸入:
<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">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
<div id=app>
<!-- 在 "change" 而不是 "input" 事件中更新 -->
<input v-model.lazy="msg">
{{msg}}
<input v-model="age" type="number">
{{age}}
<input v-model.trim="msg">
{{msg}}
</div>
<script src="./node_modules/vue/dist/vue.js"></script>
<script>
let vm=new Vue({
el: "#app",
data: {
age: 100,
msg: "hello"
}
});
</script>
</body>
</html>
6.元件化
在大型應用開發的時候,頁面可以劃分成很多部分。往往不同的頁面,也會有相同的部分。例如可能會有相同的頭部導航。
但是如果每個頁面都自開發,這無疑增加了我們開發的成本。是以我們會把頁面的不同分拆分成立的元件,然後在不同頁面就可以共享這些元件,避免重複開發。
在vue裡,所有的vue執行個體都是元件
- 元件其實也是一個vue執行個體,是以它在定義時也會接收:data、methods、生命周期函數等
- 不同的是元件不會與頁面的元素綁定(是以不寫el),否則就無法複用了,是以沒有el屬性。
- 但是元件渲染需要html模闆,是以增加了template屬性,值就是HTML模闆
- data必須是一個函數,不再是一個對象。
- 全局元件定義完畢,任何vue執行個體都可以直接在HTML中通過元件名稱來使用元件了
下面的html内容是在說:
-
這個塊跟下面的<div id="app">
對象綁定new Vue
- vue對象裡指定了
屬性,是指:标簽裡有子标簽,’components
’:button-counter
代表有個元件叫buttonCounter
,可以填充标簽buttonCounter
<button-counter>
Vue元件的使用
參考:
https://cn.vuejs.org/v2/guide/components.htmlhttps://www.runoob.com/vue2/vue-component.html
-
全局元件
參考:https://cn.vuejs.org/v2/guide/components-registration.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
<div id="app">
<button v-on:click="count++">我被點選了 {{count}} 次</button>
<counter></counter>
<counter></counter>
<counter></counter>
<counter></counter>
<counter></counter>
<hr/>
</div>
<script src="./node_modules/vue/dist/vue.js"></script>
<script>
// 定義一個名為 button-counter 的新元件
//1、全局聲明注冊一個元件
Vue.component('counter', {
data: function () { // data是函數
return {
count: 0
}
},
template: '<button v-on:click="count++">You clicked me {{ count }} times.</button>' // 渲染的模闆
});
new Vue({
el: "#app",
data: {
count: 1
}
});
</script>
</body>
</html>
局注冊的元件可以用在其被注冊之後的任何 (通過
new Vue
) 新建立的
Vue
根執行個體,也包括其元件樹中的所有子元件的模闆中。
這裡還應該注解的是data那個屬性,在元件中需要以函數的方式寫\
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
<div id="app">
<button v-on:click="count++">我被點選了 {{count}} 次</button>
<counter></counter>
<counter></counter>
<counter></counter>
<counter></counter>
<counter></counter>
<hr/>
<button-counter></button-counter>
</div>
<script src="./node_modules/vue/dist/vue.js"></script>
<script>
// 定義一個名為 button-counter 的新元件
//1、全局聲明注冊一個元件
Vue.component('counter', {
data: function () { // data是函數
return {
count: 0
}
},
template: '<button v-on:click="count++">You clicked me {{ count }} times.</button>' // 渲染的模闆
});
//2、局部聲明一個元件
const buttonCounter = {
template: `<button v-on:click="count++">我被點選了 {{count}} 次~~~</button>`,
data() {
return {
count: 1
}
}
};
new Vue({
el: "#app",
data: {
count: 1
},components: {
'button-counter': buttonCounter
}
});
</script>
</body>
</html>
7.生命周期鈎子函數
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
<div id="app">
<span id="num">{{num}}</span>
<button @click="num++">贊!</button>
<h2>{{name}},有{{num}}個人點贊</h2>
</div>
<script src="../node_modules/vue/dist/vue.js"></script>
<script>
let app = new Vue({
el: "#app",
data: {
name: "張三",
num: 100
},
methods: {
show() {
return this.name;
},
add() {
this.num++;
}
},
beforeCreate() {
console.log("=========beforeCreate=============");
console.log("資料模型未加載:" + this.name, this.num);
console.log("方法未加載:" + this.show());
console.log("html模闆未加載:" + document.getElementById("num"));
},
created: function () {
console.log("=========created=============");
console.log("資料模型已加載:" + this.name, this.num);
console.log("方法已加載:" + this.show());
console.log("html模闆已加載:" + document.getElementById("num"));
console.log("html模闆未渲染:" + document.getElementById("num").innerText);
},
beforeMount() {
console.log("=========beforeMount=============");
console.log("html模闆未渲染:" + document.getElementById("num").innerText);
},
mounted() {
console.log("=========mounted=============");
console.log("html模闆已渲染:" + document.getElementById("num").innerText);
},
beforeUpdate() {
console.log("=========beforeUpdate=============");
console.log("資料模型已更新:" + this.num);
console.log("html模闆未更新:" + document.getElementById("num").innerText);
},
updated() {
console.log("=========updated=============");
console.log("資料模型已更新:" + this.num);
console.log("html模闆已更新:" + document.getElementById("num").innerText);
}
});
</script>
</body>
</html>