Vue 常用指令
vue.js官方給自己的定為是數據模板引擎,並給出了一套渲染數據的指令。本文詳細介紹了vue.js的常用指令。
Vue.js 使用了基於 HTML 的模板語法,最簡單的使用vue的方式是渲染數據,渲染數據最常見的形式就是使用“Mustache”語法 (雙大括號) 的文本插值。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>vue插值</title>
</head>
<body>
<div id="app-01">
{{ message }}
</div>
<!--安裝方式一-->
<script src="../../statics/vue.js"></script>
<!--安裝方式二-->
<!--<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.16/vue.min.js"></script>-->
<script>
// 原生js
let odiv = document.getElementById("app-01");
odiv.innerText = "Hello Vue!";
// vue的核心之一是允許采用簡潔的模板語法來將數據渲染進DOM系統
let app01 = new Vue({
el: "#app-01",
data: {
message: "Hello Vue!"
}
});
</script>
</body>
</html>
首先創建一個vue實例,並在創建實例的過程中傳入一個對象。
該對象的第一個屬性名為el,它的值是我們需要渲染的目標標簽,我們通過屬性查找定位這個標簽。
該對象的第二個屬性名為data,里面就是我們要渲染給瀏覽器標簽的數據,另外還有其他屬性,我們在后面的章節中一一介紹。
看了上面的代碼,可能大家覺得vue也不過如此,原生js代碼兩行就能完成的事情,vue需要6行代碼來實現,還是原生js比較簡潔,其實,上面的代碼只是給大家演示了掛檔的技術,究竟是汽車比較快,還是騎馬比較好,我們通過后面的不斷學習,來解釋這個問題。
接下來,我們來介紹踩油門的技術。
上面的代碼中,我們演示了如何將數據渲染進DOM標簽,vue幫助我們找到標簽並且渲染,對於程序員來說,我們不再需要重復的找標簽,綁定事件,然后再找標簽,再綁定事件這樣的工作了,vue幫我們都做好了,我們只需要關注具體的數據,以及業務邏輯。這也是vue給自己的定位,數據模板引擎。
它是引擎,引擎幫助我們驅動數據渲染到模板。
所以,vue的大部分內容,都是為了渲染數據用的,接下來,我們介紹vue中用來渲染數據的常用指令。
一、vue.js模板語法之常用指令
常用指令: v-html
雙大括號語法無法渲染HTML標簽,我們需要使用v-html。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>v-html</title>
</head>
<body>
<div id="app01">
<div v-html="vue"></div>
</div>
<script src="./vue.js"></script>
<script>
let app01 = new Vue({
el: "#app01",
data: {
vue: '<h1>Hello Vue!</h1>'
}
})
</script>
</body>
</html>
常用指令:v-text
類似雙大括號語法渲染數據的另一種方式是使用v-text。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>v-html</title>
</head>
<body>
<div id="app01">
<div v-text="name"></div>
</div>
<script src="./vue.js"></script>
<script>
let app01 = new Vue({
el: "#app01",
data: {
name: "dogfa"
}
})
</script>
</body>
</html>
常用指令:v-for
接下來,我們看看數組和對象的渲染方式
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>v-for</title>
<script src="../vue模板語法之插值/vue.js"></script>
</head>
<body>
<div id="app01">
<h2>dogfa的愛好</h2>
<ul>
<li v-for="item in qianqian">{{ item }}</li>
</ul>
<h2>學生的愛好</h2>
<ul>
<li v-for="stu in students">{{ stu.name }}的愛好是{{ stu.hobby}}</li>
</ul>
</div>
<script>
let app01 = new Vue({
el: "#app01",
data: {
qianqian: [
"學習",
"逛街",
"美甲"
],
students: [
{
name: "dogfa",
hobby: "girls"
},
{
name: "djb",
hobby: "girls"
},
{
name: "oldniu",
hobby: "study"
}
]
}
})
</script>
</body>
</html>
常用指令:v-if
渲染數據的時候,同樣也可以使用條件判斷,我們來看看。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>v-if</title>
<script src="./vue.js"></script>
</head>
<body>
<div id="app01">
<div v-if="role == 'shanshan'">
<h2>歡迎小美女</h2>
</div>
<div v-else-if="role == 'longting'">
<h2>歡迎小龍女</h2>
</div>
<div v-else>
<h2>滾~~~</h2>
</div>
</div>
<script>
// 請注意看HTML標簽元素,v-if底層使用appendChild實現
let app01 = new Vue({
el: "#app01",
data: {
role: "shanshan"
}
})
</script>
</body>
</html>
通過上面的代碼我們可以看出,v-if的作用是控制標簽的顯示,它通過判斷添加標簽,底層采用的是appendChild來實現的,下面我們來看一個同樣也是控制標簽顯示的另一個指令v-show。
常用指令:v-show
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>v-show</title>
<script src="./vue.js"></script>
</head>
<body>
<div id="app01">
<h1 v-show="isShow">Hello Vue!</h1>
</div>
<script>
// v-show的實現原理是通過控制樣式的display
let app01 = new Vue({
el: "#app01",
data: {
isShow: true
}
})
</script>
</body>
</html>
與v-if不同的是,v-show通過樣式的display控制標簽的顯示。
v-if和v-show的性能比較
我們簡單比較一下二者的區別:
實現方式:v-if底層采用的是appendChild來實現的,v-show通過樣式的display控制標簽的顯示,正因為實現方式上面有差異,導致了他們的加載速度方面產生了差異;
加載性能:v-if加載速度更快,v-show加載速度慢
切換開銷:v-if切換開銷大,v-show切換開銷小
v-if是惰性的,它是“真正”的條件渲染,因為它會確保在切換過程中條件塊內的事件監聽器和子組件適當地被銷毀和重建,v-show 也是惰性的:如果在初始渲染時條件為假,則什么也不做——直到條件第一次變為真時,才會開始渲染條件塊。
v-show 就簡單得多——不管初始條件是什么,元素總是會被渲染,並且只是簡單地基於 CSS 進行切換。
一般來說,v-if有更高的切換開銷,而v-show有更高的初始渲染開銷。因此,如果需要非常頻繁地切換,則使用v-show較好,如果在運行時條件很少改變,則使用v-if較好。
常用指令:v-bind
綁定屬性,不多說了,注意冒號后面跟標簽的屬性,屬性后面的等號指向數據,它可以簡寫為 :class, :href。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>v-bind</title>
<style>
.active {
background-color: #2b84da;
}
</style>
<script src="./vue.js"></script>
</head>
<body>
<div id="app01">
<a v-bind:href='link' v-bind:class="{active: isActive}">去百度</a>
</div>
<script>
// 綁定屬性,簡寫冒號:
let app01 = new Vue({
el: "#app01",
data: {
link: "https://www.luffycity.com",
isActive: true
}
})
</script>
</body>
</html>
常用指令:v-on
另一個非常重要的指令是v-on,使用v-on我們可以在標簽上面綁定事件,注意我們新建的vue實例app01中多了一個屬性,methods,在methods中,是我們具體事件的實現方式。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>v-on</title>
<style>
</style>
<script src="./vue.js"></script>
</head>
<body>
<div id="app01">
<!--方式一: 綁定一個事件-->
<a v-bind:href='link'
v-bind:class="{active: isActive}"
v-on:click="myClick"
>去百度</a>
<!--方式二: 綁定多個事件-->
<button v-on="{click: myClick,
mouseenter: mouseEnter,
mouseleave: mouseLeave}">
點我今晚吃雞~~~
</button>
</div>
<script>
// 綁定屬性,簡寫冒號:
let app01 = new Vue({
el: "#app01",
data: {
link: "https://www.baidu.com",
isActive: false
},
methods: {
myClick: function () {
console.log("大吉大利,今晚吃雞~~~")
},
mouseEnter: function () {
console.log("鼠標來了~~~");
},
mouseLeave: function () {
console.log("鼠標走了~~~");
}
}
})
</script>
</body>
</html>
常用指令:v-model
上面演示的是通過vue實例將數據渲染進模板,並且在控制台,我們修改數據之后,修改后的數據能夠及時(官方稱之為響應式)的渲染到模板層,那么,如果有這樣的需求,比如有一個input標簽,當用戶修改渲染的原始數據后,打印修改后的數據,簡單說,我們需要vue實例可以幫我們渲染數據並響應式的監聽數據修改,同時我們還需要監聽用戶行為,如果用戶在標簽上面修改了數據(之前的修改,指的是通過vue實例app01進行的數據修改),我們需要獲取到數據,針對這個需求,我們可以使用v-mode指令。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>v-model</title>
</head>
<body>
<div id="app01">
<p>請選擇你的性別</p>
<br>
<input v-model="name"/>
<p><input type="text" v-model="name"/></p>
<p>
<input type="checkbox" value="男" v-model="gender"/>
<input type="checkbox" value="女" v-model="gender"/>
</p>
<br>
{{ name }}
{{ gender }}
<p>請選擇你的女朋友</p>
<select name="" id="" v-model="girlFriends">
<option>dogfa</option>
<option>djb</option>
<option>oldniu</option>
</select>
<br>
{{ girlFriends }}
<p>
<textarea v-model="article"></textarea>
</p>
<br>
{{ article }}
</div>
<script src="./vue.js"></script>
<script>
let app01 = new Vue({
el: "#app01",
data: {
name: "dogfa",
gender: [],
girlFriends: [],
article: "這是一篇文章",
}
})
</script>
</body>
</html>
常用指令:指令修飾符
用戶可以輸入任何數據類型,但有時候,我們需要限定用戶輸入的數據類型,可以在指令后面加上number修飾符。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="./vue.js"></script>
</head>
<body>
<div id="app01">
<table border="1">
<thead>
<tr>
<th>學科</th>
<th>成績</th>
</tr>
</thead>
<tbody>
<tr>
<td>Python基礎</td>
<td><input type="text" v-model.number="python"/></td>
</tr>
<tr>
<td>前端</td>
<td><input type="text" v-model.lazy="web"/></td>
</tr>
<tr>
<td>Django</td>
<td><input type="text" v-model.trim="django"/></td>
</tr>
</tbody>
</table>
</div>
<script>
let app01 = new Vue({
el: "#app01",
data: {
python: 75,
web: 98,
django: 88
}
})
</script>
</body>
</html
常用指令:計算屬性
計算屬性用來監聽多個數據,每次頁面加載,計算屬性中的函數立即執行,但是只要原數據不被修改,那么,就不會觸發重新計算,計算屬性會使用計算后的緩存結果,只當原數據修改時,才會重新計算並將結果緩存起來。計算屬性的計算結果可以當做data中的數據一樣使用。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="./vue.js"></script>
</head>
<body>
<div id="app01">
<table border="1">
<thead>
<tr>
<th>學科</th>
<th>成績</th>
</tr>
</thead>
<tbody>
<tr>
<td>Python基礎</td>
<td><input type="text" v-model.number="python"/></td>
</tr>
<tr>
<td>前端</td>
<td><input type="text" v-model.trim="web"/></td>
</tr>
<tr>
<td>Django</td>
<td><input type="text" v-model.lazy="django"/></td>
</tr>
<tr>
<td>總分</td>
<td>{{ python + web + django }}</td>
</tr>
<tr>
<td>平均分</td>
<td>{{ avgScore }}</td>
</tr>
</tbody>
</table>
</div>
<script>
// 計算屬性放在緩存當中,只有數據修改時才重新計算
let app01 = new Vue({
el: "#app01",
data: {
python: 75,
web: 98,
django: 88
},
computed: {
sumScore: function () {
return this.python + this.web + this.django;
},
avgScore: function () {
return this.sumScore/3;
}
}
})
</script>
</body>
</html>
計算屬性是通過過濾多個數據之后的結果,不一定是data中已存在的數據。
常用指令:偵聽屬性
計算屬性用來監聽多個屬性,我們也可以使用它來監聽一個屬性,但是頁面加載即執行計算並不符合我們的需求,如何只在數據被修改后出發相應事件,vue提供給我們的是watch,即偵聽屬性。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="../statics/vue.min.js"></script>
</head>
<body>
<div id="app">
<p>Original message: {{ message }}</p>
<p>Computed message: {{ reversedMessage }}</p>
<p>Full name: {{ fullName }}</p>
<p><input type="text" v-model="firstName"/></p>
<p><input type="text" v-model="lastName"/></p>
</div>
<script>
new Vue({
el: "#app",
data: {
message: "Hello Vue!",
firstName: "Foo",
lastName: "Bar",
fullName: "Foo Bar",
},
computed: {
reversedMessage: {
get: function () {
console.log(1);
// 多次刷新reversedMessage不會改變, 除非message發生改變
return this.message.split('').reverse().join('');
}
}
},
watch: {
firstName: function (value) {
console.log(value);
this.fullName = value + ' ' + this.lastName
},
lastName: function (value) {
console.log(value);
this.fullName = this.firstName + ' ' + value
}
}
})
</script>
</body>
</html>
偵聽屬性必須是data中的已存在的數據。
常用指令:自定義指令
遇到一些復雜的需求,vue提供的指令不能完美的處理,有時候我們需要自定義指令,針對這一需求,vue提供了自定義指令,如下所示:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>自定義屬性</title>
<style>
.box {
width: 100px;
height: 100px;
border: 1px;
background-color: #ff0000;
}
</style>
<script src="./vue.js"></script>
</head>
<body>
<div id="app01" class="box" v-pos.left.bottom="post">
</div>
<script>
Vue.directive("pos", function (el, bindding) {
let decorators = bindding.modifiers;
if (bindding.value) {
el.style['position'] = 'fixed';
for (let key in decorators) {
el.style[key] = 0;
}
} else {
el.style.position = "static";
}
});
// 自定義屬性
let app01 = new Vue({
el: "#app01",
data: {
post: true
}
})
</script>
</body>
</html>
el是我們自定義指令所在的DOM元素;
bindding是自定義指令的一些具體數據,請記住,最重要的一點是,不管是現在還是將來,任何情況下,我們都需要根據數據進行業務處理,所以,此處最關鍵的也是數據,即bindding.value。
常用指令:獲取DOM元素
某些情況下,我們需要直接獲取DOM元素,並對元素進行一些加工處理。vue提供給我們$refs來獲取DOM元素
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>獲取DOM</title>
<script src="./vue.js"></script>
</head>
<body>
<div id="app01">
<div ref="myBox">dogfa</div>
<button v-on:click="dogfa">點擊dogfa變紅</button>
</div>
<script>
// 錯誤實例button放在div外面
let app01 = new Vue({
el: "#app01",
methods: {
dogfa: function () {
this.$refs.myBox.style.color = "red";
}
}
})
</script>
</body>
</html>
在DOM元素上面綁定了ref之后,vue根實例上面就會出現$refs變量,它是一個object類型,key為ref后面的自定義名稱,而value為DOM元素。我們通過this.$refs拿到object,之后就可以通過自定義的key名,來找到DOM元素
二、案例:todoList
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>使用Vue實現todoList</title>
<script src="../statics/vue.min.js"></script>
<style>
* {
margin: 0;
padding: 0;
}
.container {
width: 500px;
height: auto;
margin: 0 auto;
}
.container .header {
text-align: center
}
li {
list-style-type: none
}
div.left {
float: left;
margin-left: 50px;
}
div.right {
float: right;
margin-right: 50px;
}
li {
margin-top: 5px;
}
</style>
</head>
<body>
<div id="app">
<div class="container">
<!--頭部添加待辦-->
<div class="header">
<input id="addthings" @keyup.enter="todoEnter" v-model="todo">
<span @click="todoEnter">添加待辦</span>
</div>
<!--已辦和待辦最外層的盒子-->
<div class="box">
<!--已辦事項-->
<div class="left">
<span>待辦事項</span>
<div class="todos">
<ul>
<li v-for="(todo, index) in todoThings" :key="index">
<input type="radio" name="todo" v-on:click="addThing(index)"><span>{{ todo }}</span>
</li>
</ul>
</div>
</div>
<!--待辦事項-->
<div class="right">
<span>已辦事項</span>
<div class="dones">
<ul>
<li v-for="(done, index) in doneThings" :key="index">
<input type="radio" name="done" v-on:click="delThing(index)"><span>{{ done }}</span>
</li>
</ul>
</div>
</div>
</div>
</div>
</div>
<script>
new Vue({
el: "#app",
data: {
todo: '',
addDone: '',
todoThings: ['寫代碼', '五道口吃火鍋', '超市買雞蛋', '圖書館看書', '看電影', '看演唱會', '游泳', '跑步'],
doneThings: ['看書', '寫博客', '散步', '跟朋友聊天', '打電話給父母', '學炒菜', '洗衣服', '打掃房間']
},
methods: {
todoEnter: function () {
if (this.todo) {
this.todoThings.push(this.todo);
this.todo = '';
}
},
addThing: function (index) {
event.currentTarget.checked = false;
things = this.todoThings.splice(index, 1)[0];
this.doneThings.push(things);
},
delThing: function (index) {
event.currentTarget.checked = false;
things = this.doneThings.splice(index, 1)[0];
this.todoThings.push(things);
}
}
})
</script>
</body>
</html>
三、案例:輪播圖
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="../statics/vue.min.js"></script>
<style>
* {
margin: 0;
padding: 0;
}
.container {
margin: 0 auto;
width: 800px;
height: 500px;
position: relative;
top: 80px;
}
.img {
width: 800px;
height: 500px;
position: absolute;
}
img {
width: 800px;
height: 500px;
}
.circle {
width: 130px;
height: 2px;
position: absolute;
left: 50%;
margin-left: -65px;
bottom: 30px;
}
.circle span {
padding: 1px 10px;
background-color: #c2ccd1;
border-radius: 50%;
margin-left: 5px;
cursor: pointer;
}
.circle span.current {
background-color: #F90;
}
</style>
</head>
<body>
<div id="app">
<div class="container">
<div class="img"><img :src="imageArray[currentIndex].imgSrc" v-on="{ mouseenter: mouseEnter, mouseleave: mouseLeave}"></div>
<div class="circle">
<span v-for="(circle, index) in circleCount" :class="{current: currentIndex===index}" v-on:click="changePic(index)"></span>
</div>
</div>
</div>
<script>
new Vue({
el: "#app",
data: {
imageArray: [
{ id: 1, imgSrc: "../images/timg1.jpg" },
{ id: 2, imgSrc: "../images/timg2.jpg" },
{ id: 3, imgSrc: "../images/timg3.jpg" },
{ id: 4, imgSrc: "../images/timg4.jpg" },
{ id: 5, imgSrc: "../images/timg5.jpg" },
],
currentIndex: 0,
circleCount: 5
},
methods: {
prevImg: function () {
this.currentIndex = this.currentIndex - 1;
if (this.currentIndex < 0) {
this.currentIndex = this.imageArray.length - 1;
}
},
nextImg: function () {
this.currentIndex = this.currentIndex + 1;
if (this.currentIndex === this.imageArray.length) {
this.currentIndex = 0;
}
},
mouseEnter: function () {
clearInterval(this.interval);
},
mouseLeave: function () {
this.setInterVal();
},
setInterVal: function () {
this.interval = setInterval(() => {
this.currentIndex = this.currentIndex + 1;
if (this.currentIndex === this.imageArray.length) {
this.currentIndex = 0;
}
}, 3000)
},
changePic: function (index) {
this.currentIndex = index;
}
},
created(){
this.setInterVal();
}
})
</script>
</body>
</html>
四、案例:音樂播放器
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>使用Vue實現音樂播放器</title>
<script src="../statics/vue.min.js"></script>
<style>
* {
margin: 0;
padding: 0;
}
.active {
background-color: red;
}
</style>
</head>
<body>
<div id="app">
<audio :src="songs[currentIndex].songSrc" controls="controls" loop="loop" autoplay="autoplay"></audio>
<ul>
<li v-for="song in songs" :key="song.id" @click="playSong(song.id)" :class="{ active: song.id===currentIndex+1 }">
<h2>歌手:{{ song.artist }}</h2>
<p>歌名:{{ song.name }}</p>
</li>
</ul>
</div>
<script>
new Vue({
el: "#app",
data: {
songs: [
{ id: 1, songSrc: '../medias/不再讓你孤單.mp3', artist: "李必勝", name: '不再讓你孤單' },
{ id: 2, songSrc: '../medias/漂洋過海來看你.mp3', artist: "Pizza Li", name: '漂洋過海來看你' },
{ id: 3, songSrc: '../medias/成都.mp3', artist: '必勝', name: '成都' },
{ id: 4, songSrc: '../medias/晚風.mp3', artist: 'Pizza', name: '晚風' },
],
currentIndex: 0
},
methods: {
playSong(index) {
this.currentIndex = index - 1;
}
}
})
</script>
</body>
</html>
好了,以上就是vue常用指令介紹。
