解讀Vue實例的屬性及模板渲染
1 概述
Vue.js是通過new Vue({...})來聲明一個實例的,在這個實例中包含了當前頁面的HTML結(jié)構(gòu)、數(shù)據(jù)和事件。
Vue實例是MVVM模式中的ViewModel,實現(xiàn)了數(shù)據(jù)和視圖的雙向綁定。
在實例化時可以傳入一個選項對象,它包含數(shù)據(jù)、模板、掛載元素、方法、生命周期鉤子函數(shù)等選項。
2 el:與DOM元素綁定
el是element的簡寫,用來和DOM元素進行綁定,對應(yīng)的是DOM元素的id屬性值(類似id選擇器)。
用法如下:
<div id="xxx"></div>
<script>
var vm = new Vue({
el: "#xxx" // xxx為id名
})
</script>3 data:定義雙向綁定的數(shù)據(jù)
在Vue實例中初始化的data中的所有數(shù)據(jù)會自動進行監(jiān)聽綁定,可以使用兩個大括號 {{}} 來綁定data中的數(shù)據(jù)。
用法如下:
<div id="xxx"></div>
<script>
var vm = new Vue({
el: "#xxx",
data: {
健: 值
}
})
</script>健為屬性的名稱,值為初始值。
示例代碼:
<div id="app">
<h2>{{message}}</h2>
<input type="text" v-model="message">
</div>
<script>
var vm = new Vue({
el: "#app",
data: {
message: "橘貓吃不胖"
}
})
</script>
如果在輸入框中輸入其他內(nèi)容,h2標簽也會顯示該內(nèi)容,vue與h2標簽的綁定是單向的,與input標簽的綁定是雙向的。

注:data中的數(shù)據(jù)都是淺拷貝。這意味著,如果修改原來的對象也會改變data,從而觸發(fā)更新事件。
4 computed:計算屬性
computed是計算屬性,當我們要用到的屬性不存在,需要通過已有屬性計算得來,這時使用計算屬性。computed底層借助了Object.defineproperty方法提供的getter和setter來實現(xiàn)。
使用方法可以跟data中的屬性一樣使用,注意用的時候不要加“()”。
它是data屬性的補充。在進行數(shù)據(jù)綁定的時候,對數(shù)據(jù)要進行一定的處理才能展示到HTML頁面上。
雖然Vue提供了非常好的表達式綁定方法,但是只能應(yīng)對低強度的需求。
用法如下:
<div id="xxx"></div>
<script>
var vm = new Vue({
el: "#xxx",
computed: {
方法名: function () {}
}
})
</script>例如,把一個日期按照規(guī)定格式進行輸出,可能就需要對日期對象做一些格式化。
Vue提供的計算屬性(computed)允許開發(fā)者編寫一些方法,協(xié)助進行綁定數(shù)據(jù)的操作。
<div id="app">
<table>
<tr>
<td>姓名:</td>
<td>{{name}}</td>
</tr>
<tr>
<td>生日:</td>
<td>{{getBirthday}}</td>
</tr>
</table>
</div>
<script>
var vm = new Vue({
el: "#app",
data: {
name: "橘貓吃不胖",
birthday: 1014228510514 // 傳了一個毫秒數(shù)
},
computed: { // 計算屬性,對data中的數(shù)據(jù)進行處理
getBirthday: function () { // getBirthday就是表格中的{{getBirthday}},其本質(zhì)是一個屬性
let date = new Date(this.birthday);
return date.getFullYear() + "年" + (date.getMonth() + 1) + "月" + date.getDate() + "日";
}
}
})
</script>
每一個計算屬性都包含一個getter和一個setter。
上面的示例是計算屬性的默認用法, 只是利用了getter來讀取。在需要時,也可以提供一個setter函數(shù), 當手動修改計算屬性的值就像修改一個普通數(shù)據(jù)那樣時,就會觸發(fā)setter函數(shù),執(zhí)行一些自定義的操作。
getter函數(shù)執(zhí)行的時機:
(1)初次讀取時會執(zhí)行一次
(2)當依賴的數(shù)據(jù)發(fā)生改變時會被再次調(diào)用
計算屬性computed優(yōu)勢:與methods實現(xiàn)相比,它的內(nèi)部有緩存機制,計算屬性只有在它相關(guān)依賴發(fā)生改變時才會重新求值,效率更高,調(diào)試方便。
注意:
(1)計算屬性最終會出現(xiàn)在Vue實例vm上,直接讀取使用即可
(2)如果計算屬性要被修改,那必須寫set函數(shù)去響應(yīng)修改,且set中要引起計算時依賴的數(shù)據(jù)發(fā)生改變
示例:在輸入框中分別輸入姓和名,最后將全名顯示在頁面上,感受getter方法;在控制臺中修改全名,感受setter方法。
<div id="app">
姓:<input type="text" v-model="xing"><br><br>
名:<input type="text" v-model="ming"><br><br>
你的姓名是:{{fullName}}
</div>
<script>
var vm = new Vue({
el: "#app",
data: {
xing: "", // 初始值為空
ming: ""
},
computed: {
fullName: {
get() {
return this.xing + "-" + this.ming; // 返回值為全名
},
set(value) {
let arr = value.split("-");
this.xing = arr[0];
this.ming = arr[1];
}
}
}
})
</script>如下所示,在輸入框中輸入姓和名,會將全名顯示在下方。

如果在控制臺中修改全名,會修改掉輸入框中的值。

5 methods:定義Vue實例的方法
methods需要搭配v-on指令來監(jiān)聽DOM事件,我們在methods對象中定義方法,最終會在Vue實例上,其中的this會指向Vue的實例vm,因此其中配置的函數(shù)不可以使用箭頭函數(shù),否則會改變this的指向。
用法如下:
<div id="xxx"></div>
<script>
var vm = new Vue({
el: '#xxx',
methods: {
方法名: function () { }
}
})
</script>示例代碼:
<div id="app">
<p>原始字符串:"{{ message }}"</p>
<p>反向字符串:"{{ reversedMessage()}}"</p>
</div>
<script>
var vm = new Vue({
el: '#app',
data: {
message: '橘貓吃不胖'
},
methods: {
reversedMessage: function () {
return this.message.split('').reverse().join('')
}
}
})
</script>
6 Vue中的三種模板
6.1 html模板
- html模板:基于DOM的模板,模板都是可解析的有效的HTML插值
- 文本:使用{{ }}語法,作用:替換實例上的屬性值,當值改變時,插值內(nèi)容處會自動更新
- 原生的html:雙大括號輸出的是文本,不會解析html(想要解析html,可以使用指令v-html)
- 屬性:使用v-bind進行綁定,可以響應(yīng)變化
<div id="wrap">
<p>你的名字是{{list.name}}</p>
</div>
<script>
var list = {
name: "donna",
age: 20
}
var vm = new Vue({
el: "#wrap",
data: { list }
});
</script>
6.2 字符串模板
先定義字符串模板,然后在vue 的選項對象里面利用template綁定。字符串模板的優(yōu)先級會比html模板高,如果html和字符串模板中都有內(nèi)容,會用字符串模板里的內(nèi)容替換html模板。需要注意的是定義的字符串模板中根節(jié)點只能有一個。還有字符串用 ` 引起來是可以換行的。
示例代碼:
<div id="app"></div>
<script>
let obj = {
content: "橘貓吃不胖"
}
let str = `<div>Hello {{content}}</div>`;
new Vue({
el: "#app",
data: obj,
template: str
})
</script>
除了用變量定義模板字符串,還可以用script標簽,給script 標簽定義id,根節(jié)點只能有一個,將html結(jié)構(gòu)寫在一對script標簽中,設(shè)置type=“x-template”,模板將會替換掛載的元素。掛載元素的內(nèi)容都將被忽略。Vue實例的template屬性設(shè)置為給定的script標簽
示例代碼:
<div id="app"></div>
<script type="x-template" id="test">
<div>
<p>姓名:{{obj.name}}</p>
</div>
</script>
<script>
let obj = {
name: "張三"
}
new Vue({
el: "#app",
data: { obj },
template: "#test"
})
</script>
6.3 render函數(shù)模板
render(createElement){
createElement(標簽名,[數(shù)據(jù)對象],子元素)//子元素為數(shù)組或?qū)ο?
}數(shù)據(jù)對象的屬性:
class:{ }, //綁定class
style:{ }, //綁定樣式,
attrs:{ }, //添加行間屬性
domProps:{ }, //DOM元素屬性
on:{ }, //綁定事件示例代碼:
<div id="app"></div>
<style>
.bg {
background-color: pink;
}
</style>
<script>
new Vue({
el: "#app",
render(createElement) {
return createElement(
"ul",
{
class: { bg: true },
style: { listStyle: "none" },
attrs: {
name: "tt"
}
},
[
createElement("li", "蘋果"),
createElement("li", "香蕉"),
createElement("li", "橘子")
]
)
}
})
</script>
7 watch屬性
watch屬性用來觀察和響應(yīng)Vue實例上的數(shù)據(jù)變動,watch屬性是一個配置對象,它有兩個屬性:一個是鍵,一個是值。
鍵是需要觀察的表達式,值可以為以下形式:
- 對應(yīng)的回調(diào)函數(shù),回調(diào)函數(shù)得到的參數(shù)為新值和舊值。
- 方法名稱的字符串(通過
methods聲明) - 包含額外選項的對象。當使用對象語法時,回調(diào)函數(shù)應(yīng)被聲明在
handler中。額外的選項包含:
| 選項 | 說明 |
|---|---|
| immediate | 在初始化時立即調(diào)用回調(diào)函數(shù)handler。第一次調(diào)用時,舊值將為undefined |
| deep | 如果源是對象或數(shù)組,則強制深度遍歷源,以便在深度變更時觸發(fā)回調(diào) |
| flush | 調(diào)整回調(diào)的刷新時機 |
| onTrack / onTrigger | 調(diào)試偵聽器的依賴關(guān)系 |
new Vue({
...
watch: {
// 值為回調(diào)函數(shù)形式,newVal表示新的值,oldVal表示舊的值
要監(jiān)視的數(shù)據(jù): function (newVal, oldVal) { }
// 值為方法名形式:
要監(jiān)視的數(shù)據(jù): "methods中聲明的方法名"
// 值為包含額外選項的對象:
要監(jiān)視的數(shù)據(jù): {
immediate: xxx,
handler(newVal, oldVal) {},
deep: xxx,
}
}
})示例:點擊按鈕給屬性a做減法,監(jiān)聽新值與舊值。
<div id="app">
<button @click="a--">減1</button>
<p>{{message}}</p>
</div>
<script>
new Vue({
el: "#app",
data: {
a: 10,
message: " ",
},
watch: {
a: function (val, oldVal) {
this.message = "a的原值是:" + oldVal + ",a的新值是:" + val;
}
}
})
</script>

或者使用Vue實例中的$watch(),也可以達到監(jiān)視效果,該方法的返回值是一個取消觀察函數(shù),用來停止觸發(fā)回調(diào),用法如下:
// 完整形式
const vm = new Vue({ })
// unwatch:取消觀察函數(shù)
let unwatch = vm.$watch("要監(jiān)視的對象", {
immediate: true, // 配置一些屬性
...
handler(newVal, oldVal) { // 回調(diào)函數(shù)
unwatch(); // 停止監(jiān)聽對象
}
})
// 簡寫形式
const vm = new Vue({ })
// unwatch:取消觀察函數(shù)
let unwatch = vm.$watch("要監(jiān)視的對象", function (newVal, oldVal) {}
})
示例:點擊按鈕給屬性a做減法,監(jiān)聽新值與舊值。當值為5時,停止監(jiān)聽。
<div id="app">
<button @click="a--">減1</button>
<p>{{message}}</p>
</div>
<script>
const vm = new Vue({
el: "#app",
data: {
a: 10,
message: " ",
}
})
let unwatch = vm.$watch("a", {
handler(val, oldVal) {
if (val === 5) {
unwatch();
}
this.message = "a的原值是:" + oldVal + ",a的新值是:" + val;
}
})
</script>

computed與watch的區(qū)別
- computed能完成的功能,watch都可以完成;watch能完成的功能,computed不一定能完成。
- 例如:watch可以進行異步操作(使用setTimeout函數(shù))。
8 模板渲染
8.1 條件渲染
條件渲染分為兩種方式,一種是v-if,另一種是v-show。v-if又分為單路分支、雙路分支和多路分支。只有if后面的值為true時才會有DOM元素,為false時不會有DOM元素
1、v-if方式渲染:在<template>中配合v-if渲染,在使用v-if控制元素的時候,需要將它添加到這個元素上。然而,如果需要切換很多元素時,一個一個添加比較麻煩。這時,可以使用<template></template>將一組元素進行包裹
<div id="app">
<template v-if="yes">
<h2>vue</h2>
</template>
</div>
<script>
var vm = new Vue({
el: "#app",
data: {
yes: true
}
})
</script>
2、v-show方式渲染:用法與v-if大致相同
8.2 列表渲染
列表渲染用v-for指令根據(jù)一組數(shù)據(jù)的選項列表進行渲染。v-for指令需要采用item in items 形式的特殊語法,其中items是源數(shù)據(jù)
<div class="app">
<ul>
<li v-for="item in items">{{item.text}}</li>
</ul>
</div>
<script>
new Vue({
el: '.app',
data: {
items: [
{ text: 'Name'},
{ text: 'Age'},
{ text: 'Like'}
]
}
})
</script>
可以使用v-for迭代對象的屬性
<div class="app">
<ul>
<li v-for="item in obj">{{item}}</li>
</ul>
</div>
<script>
new Vue({
el: '.app',
data: {
obj: {
firstname: '歐陽',
lastname: '靜靜',
age:18
}
}
})
</script>
總結(jié)
以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。
相關(guān)文章
vue利用better-scroll實現(xiàn)輪播圖與頁面滾動詳解
在我們?nèi)粘5捻椖块_發(fā)中,處理滾動和輪播圖是再常見不過的需求了,下面這篇文章主要給大家介紹了關(guān)于vue利用better-scroll實現(xiàn)輪播圖與頁面滾動的相關(guān)資料,文中給出了詳細的示例代碼供大家參考學習,需要的朋友們下面來一起看看吧。2017-10-10
使用vue插件axios傳數(shù)據(jù)的Content-Type及格式問題詳解
這篇文章主要介紹了使用vue插件axios傳數(shù)據(jù)的Content-Type以及格式問題,本文通過實例代碼給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下2022-09-09
詳細講解如何創(chuàng)建, 發(fā)布自己的 Vue UI 組件庫
當我們自己開發(fā)了一個 _UI Component_, 需要在多個項目中使用的時候呢? 我們首先想到的可能是直接復(fù)制一份過去對嗎?我們?yōu)槭裁床话l(fā)布一個 UI 組件庫給自己用呢?下面小編和大家來一起學習下吧2019-05-05
vue3中使用ref和emit來減少props的使用示例詳解
現(xiàn)在在開發(fā)vue3項目的過程中,我們開發(fā)小組漸漸的減少props的使用,轉(zhuǎn)而用ref 和 emit 來代替,這篇文章主要介紹了vue3中使用ref和emit來減少props的使用,需要的朋友可以參考下2022-06-06
Vue-cli assets SubDirectory及PublicPath區(qū)別詳解
這篇文章主要介紹了Vue-cli assets SubDirectory及PublicPath區(qū)別詳解,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下2020-08-08

