Vue詳解
- 一、什麼是Vue?
- 二、與JavaScript的差別
- 三、建立一個Vue程式
- 四、介紹
-
- 聲明式渲染
- Vue的生命周期
- 五、指令
-
- v-text
- v-html
- v-show
- v-if
- v-else
- v-else-if
- v-for
- v-on
- v-bind
- v-model
- v-slot
- v-pre
- v-cloak
- v-once
- 六、計算屬性
- 七、監聽屬性
- 八 、條件判斷
- 九、循環周遊
- 十、表單
-
- 輸入框
- 複選框
- 單選按鈕
- select 清單
一、什麼是Vue?
Vue (讀音 /vjuː/,類似于 view) 是一套用于建構使用者界面的漸進式JavaScript架構。與其它大型架構不同的是,Vue 被設計為可以自底向上逐層應用。Vue 的核心庫隻關注視圖層,不僅易于上手,還便于與第三方庫或既有項目整合。另一方面,當與現代化的工具鍊以及各種支援類庫結合使用時,Vue 也完全能夠為複雜的單頁應用(SPA)提供驅動。
二、與JavaScript的差別
原生js的做法(程式設計範式:指令式程式設計)
1.建立div元素,設定id屬性
2.定義一個變量message
3.将message放在div中顯示
4.修改資料
5.将修改的資料再次替換到div中
vue做法(聲明式程式設計)将資料交給vue管理
<div id="app">
{{ message }}
</div>
let app = new Vue({//let(變量)/const(常量)
el: '#app',//用于挂載要管理的資料
data: {//定義資料
message: 'Hello Vue!'
}
})
三、建立一個Vue程式
- 建立一個.html檔案
- 通過以下方式引入Vue
<!-- 開發環境版本,包含了有幫助的指令行警告 -->
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
或者
<!-- 生産環境版本,優化了尺寸和速度 -->
<script src="https://cdn.jsdelivr.net/npm/vue"></script>
四、介紹
聲明式渲染
Vue.js 的核心是一個允許采用簡潔的模闆文法來聲明式地将資料渲染進 DOM 的系統:
<div id="app">
{{ message }}
</div>
var app = new Vue({
el: '#app',
data: {
message: 'Hello Vue!'
}
})
我們已經成功建立了一個 Vue 應用!看起來這跟渲染一個字元串模闆非常類似,但是 Vue 在背後做了大量工作。現在資料和 DOM 已經被建立了關聯,所有東西都是響應式的。
打開你的浏覽器的 JavaScript 控制台 (就在這個頁面打開),并修改 app.message 的值,你将看到上例相應地更新。
注意:我們不再和 HTML 直接互動了。一個 Vue 應用會将其挂載到一個 DOM 元素上 (對于這個例子是 #app) 然後對其進行完全控制。那個 HTML 是我們的入口,但其餘都會發生在新建立的 Vue 執行個體内部。
Vue的生命周期
五、指令
指令 (Directives) 是帶有 v- 字首的特殊 attribute。指令 attribute 的值預期是單個 JavaScript 表達式 (v-for 是例外情況)。指令的職責是,當表達式的值改變時,将其産生的連帶影響,響應式地作用于 DOM。
v-text
- 預期:string
- 詳細:更新元素的 textContent。如果要更新部分的 textContent,需要使用 {{ Mustache }} 插值。
- 示例:
<span v-text="msg"></span>
<!-- 和下面的一樣 -->
<span>{{msg}}</span>
v-html
- 預期:string
- 詳細:更新元素的 innerHTML。注意:内容按普通 HTML 插入 - 不會作為 Vue 模闆進行編譯。如果試圖使用 v-html 組合模闆,可以重新考慮是否通過使用元件來替代。
- 示例:
v-show
- 預期:any
-
詳細:根據表達式之真假值,切換元素的 display CSS property。
當條件變化時該指令觸發過渡效果。
v-if
- 預期:any
-
詳細:根據表達式的值的 truthiness 來有條件地渲染元素。在切換時元素及它的資料綁定 / 元件被銷毀并重建。如果元素是 ,将提出它的内容作為條件塊。
當條件變化時該指令觸發過渡效果。
當和 v-if 一起使用時,v-for 的優先級比 v-if 更高。
v-else
- 不需要表達式
- 限制:前一兄弟元素必須有 v-if 或 v-else-if。
- 用法:為 v-if 或者 v-else-if 添加“else 塊”。
<div v-if="Math.random() > 0.5">
Now you see me
</div>
<div v-else>
Now you don't
</div>
v-else-if
2.1.0 新增
- 類型:any
- 限制:前一兄弟元素必須有 v-if 或 v-else-if。
- 用法:表示 v-if 的“else if 塊”。可以鍊式調用。
<div v-if="type === 'A'">
A
</div>
<div v-else-if="type === 'B'">
B
</div>
<div v-else-if="type === 'C'">
C
</div>
<div v-else>
Not A/B/C
</div>
v-for
- 預期:Array | Object | number | string | Iterable (2.6 新增)
- 用法:基于源資料多次渲染元素或模闆塊。此指令之值,必須使用特定文法 alias in expression,為目前周遊的元素提供别名:
<div v-for="item in items">
{{ item.text }}
</div>
另外也可以為數組索引指定别名 (或者用于對象的鍵):
<div v-for="(item, index) in items"></div>
<div v-for="(val, key) in object"></div>
<div v-for="(val, name, index) in object"></div>
v-for 的預設行為會嘗試原地修改元素而不是移動它們。要強制其重新排序元素,你需要用特殊 attribute key 來提供一個排序提示:
<div v-for="item in items" :key="item.id">
{{ item.text }}
</div>
從 2.6 起,v-for 也可以在實作了可疊代協定的值上使用,包括原生的 Map 和 Set。不過應該注意的是 Vue 2.x 目前并不支援可響應的 Map 和 Set 值,是以無法自動探測變更。
v-on
- 縮寫:@
- 預期:Function | Inline Statement | Object
- 參數:event
- 修飾符:
stop - 調用 event.stopPropagation()。 .prevent - 調用 event.preventDefault()。 .capture - 添加事件偵聽器時使用 capture 模式。 .self - 隻當事件是從偵聽器綁定的元素本身觸發時才觸發回調。 .{keyCode | keyAlias} - 隻當事件是從特定鍵觸發時才觸發回調。 .native - 監聽元件根元素的原生事件。 .once - 隻觸發一次回調。 .left - (2.2.0) 隻當點選滑鼠左鍵時觸發。 .right - (2.2.0) 隻當點選滑鼠右鍵時觸發。 .middle - (2.2.0) 隻當點選滑鼠中鍵時觸發。 .passive
- (2.3.0) 以 { passive: true } 模式添加偵聽器
- 用法:
綁定事件監聽器。事件類型由參數指定。表達式可以是一個方法的名字或一個内聯語句,如果沒有修飾符也可以省略。
用在普通元素上時,隻能監聽原生 DOM 事件。用在自定義元素元件上時,也可以監聽子元件觸發的自定義事件。
在監聽原生 DOM 事件時,方法以事件為唯一的參數。如果使用内聯語句,語句可以通路一個 $event property:v-on:click=“handle(‘ok’, $event)”。
從 2.4.0 開始,v-on 同樣支援不帶參數綁定一個事件/監聽器鍵值對的對象。注意當使用對象文法時,是不支援任何修飾器的。
- 示例:
<!-- 方法處理器 -->
<button v-on:click="doThis"></button>
<!-- 動态事件 (2.6.0+) -->
<button v-on:[event]="doThis"></button>
<!-- 内聯語句 -->
<button v-on:click="doThat('hello', $event)"></button>
<!-- 縮寫 -->
<button @click="doThis"></button>
<!-- 動态事件縮寫 (2.6.0+) -->
<button @[event]="doThis"></button>
<!-- 停止冒泡 -->
<button @click.stop="doThis"></button>
<!-- 阻止預設行為 -->
<button @click.prevent="doThis"></button>
<!-- 阻止預設行為,沒有表達式 -->
<form @submit.prevent></form>
<!-- 串聯修飾符 -->
<button @click.stop.prevent="doThis"></button>
<!-- 鍵修飾符,鍵别名 -->
<input @keyup.enter="onEnter">
<!-- 鍵修飾符,鍵代碼 -->
<input @keyup.13="onEnter">
<!-- 點選回調隻會觸發一次 -->
<button v-on:click.once="doThis"></button>
<!-- 對象文法 (2.4.0+) -->
<button v-on="{ mousedown: doThis, mouseup: doThat }"></button>
在子元件上監聽自定義事件 (當子元件觸發“my-event”時将調用事件處理器):
<my-component @my-event="handleThis"></my-component>
<!-- 内聯語句 -->
<my-component @my-event="handleThis(123, $event)"></my-component>
<!-- 元件中的原生事件 -->
<my-component @click.native="onClick"></my-component>
v-bind
- 縮寫::
- 預期:any (with argument) | Object (without argument)
- 參數:attrOrProp (optional)
- 修飾符:
.prop - 作為一個 DOM property 綁定而不是作為 attribute 綁定。(差别在哪裡?)
.camel - (2.1.0+) 将 kebab-case attribute 名轉換為 camelCase。(從 2.1.0 開始支援)
.sync (2.3.0+) 文法糖,會擴充成一個更新父元件綁定值的 v-on 偵聽器。
-
用法:動态地綁定一個或多個 attribute,或一個元件 prop 到表達式。
在綁定 class 或 style attribute 時,支援其它類型的值,如數組或對象。可以通過下面的教程連結檢視詳情。
在綁定 prop 時,prop 必須在子元件中聲明。可以用修飾符指定不同的綁定類型。
沒有參數時,可以綁定到一個包含鍵值對的對象。注意此時 class 和 style 綁定不支援數組和對象。
- 示例:
<!-- 綁定一個 attribute -->
<img v-bind:src="imageSrc">
<!-- 動态 attribute 名 (2.6.0+) -->
<button v-bind:[key]="value"></button>
<!-- 縮寫 -->
<img :src="imageSrc">
<!-- 動态 attribute 名縮寫 (2.6.0+) -->
<button :[key]="value"></button>
<!-- 内聯字元串拼接 -->
<img :src="'/path/to/images/' + fileName">
<!-- class 綁定 -->
<div :class="{ red: isRed }"></div>
<div :class="[classA, classB]"></div>
<div :class="[classA, { classB: isB, classC: isC }]">
<!-- style 綁定 -->
<div :style="{ fontSize: size + 'px' }"></div>
<div :style="[styleObjectA, styleObjectB]"></div>
<!-- 綁定一個全是 attribute 的對象 -->
<div v-bind="{ id: someProp, 'other-attr': otherProp }"></div>
<!-- 通過 prop 修飾符綁定 DOM attribute -->
<div v-bind:text-content.prop="text"></div>
<!-- prop 綁定。“prop”必須在 my-component 中聲明。-->
<my-component :prop="someThing"></my-component>
<!-- 通過 $props 将父元件的 props 一起傳給子元件 -->
<child-component v-bind="$props"></child-component>
<!-- XLink -->
<svg><a :xlink:special="foo"></a></svg>
.camel 修飾符允許在使用 DOM 模闆時将 v-bind property 名稱駝峰化,例如 SVG 的 viewBox property:
在使用字元串模闆或通過 vue-loader/vueify 編譯時,無需使用 .camel。
v-model
- 預期:随表單控件類型不同而不同。
- 限制:
<input>
<select>
<textarea>
components
-
修飾符:
.lazy - 取代 input 監聽 change 事件
.number - 輸入字元串轉為有效的數字
.trim - 輸入首尾空格過濾
- 用法:在表單控件或者元件上建立雙向綁定。細節請看下面的教程連結。
v-slot
- 縮寫:#
- 預期:可放置在函數參數位置的 JavaScript 表達式 (在支援的環境下可使用解構)。可選,即隻需要在為插槽傳入 prop 的時候使用。
- 參數:插槽名 (可選,預設值是 default)
- 限用于
<template>
元件 (對于一個單獨的帶 prop 的預設插槽)
-
用法:
提供具名插槽或需要接收 prop 的插槽。
- 示例:
<!-- 具名插槽 -->
<base-layout>
<template v-slot:header>
Header content
</template>
Default slot content
<template v-slot:footer>
Footer content
</template>
</base-layout>
<!-- 接收 prop 的具名插槽 -->
<infinite-scroll>
<template v-slot:item="slotProps">
<div class="item">
{{ slotProps.item.text }}
</div>
</template>
</infinite-scroll>
<!-- 接收 prop 的預設插槽,使用了解構 -->
<mouse-position v-slot="{ x, y }">
Mouse position: {{ x }}, {{ y }}
</mouse-position>
v-pre
- 不需要表達式
- 用法:跳過這個元素和它的子元素的編譯過程。可以用來顯示原始 Mustache 标簽。跳過大量沒有指令的節點會加快編譯。
- 示例:
v-cloak
- 不需要表達式
- 用法:這個指令保持在元素上直到關聯執行個體結束編譯。和 CSS 規則如 [v-cloak] { display: none } 一起用時,這個指令可以隐藏未編譯的 Mustache 标簽直到執行個體準備完畢。
- 示例:
[v-cloak] {
display: none;
}
<div v-cloak>
{{ message }}
</div>
不會顯示,直到編譯結束。
v-once
- 不需要表達式
- 詳細:隻渲染元素群組件一次。随後的重新渲染,元素/元件及其所有的子節點将被視為靜态内容并跳過。這可以用于優化更新性能。
<!-- 單個元素 -->
<span v-once>This will never change: {{msg}}</span>
<!-- 有子元素 -->
<div v-once>
<h1>comment</h1>
<p>{{msg}}</p>
</div>
<!-- 元件 -->
<my-component v-once :comment="msg"></my-component>
<!-- `v-for` 指令-->
<ul>
<li v-for="i in list" v-once>{{i}}</li>
</ul>
六、計算屬性
模闆内的表達式非常便利,但是設計它們的初衷是用于簡單運算的。在模闆中放入太多的邏輯會讓模闆過重且難以維護。例如:
<div id="example">
{{ message.split('').reverse().join('') }}
</div>
在這個地方,模闆不再是簡單的聲明式邏輯。你必須看一段時間才能意識到,這裡是想要顯示變量 message 的翻轉字元串。當你想要在模闆中的多處包含此翻轉字元串時,就會更加難以處理。
是以,對于任何複雜邏輯,你都應當使用計算屬性。
七、監聽屬性
Vue.js 監聽屬性 watch,我們可以通過 watch 來響應資料的變化。
以下執行個體進行千米與米之間的換算:
<div id = "computed_props">
千米 : <input type = "text" v-model = "kilometers">
米 : <input type = "text" v-model = "meters">
</div>
<p id="info"></p>
<script type = "text/javascript">
var vm = new Vue({
el: '#computed_props',
data: {
kilometers : 0,
meters:0
},
methods: {
},
computed :{
},
watch : {
kilometers:function(val) {
this.kilometers = val;
this.meters = this.kilometers * 1000
},
meters : function (val) {
this.kilometers = val/ 1000;
this.meters = val;
}
}
});
// $watch 是一個執行個體方法
vm.$watch('kilometers', function (newValue, oldValue) {
// 這個回調将在 vm.kilometers 改變後調用
document.getElementById ("info").innerHTML = "修改前值為: " + oldValue + ",修改後值為: " + newValue;
})
</script>
上述代碼中我們建立了兩個輸入框,data 屬性中, kilometers 和 meters 初始值都為 0。watch 對象建立了 data 對象的兩個監控方法: kilometers 和 meters。
當我們再輸入框輸入資料時,watch 會實時監聽資料變化并改變自身的值。
八 、條件判斷
v-if
條件判斷使用 v-if 指令:
<!-- 在元素 和 template 中使用 v-if 指令: -->
<div id="app">
<p v-if="seen">現在你看到我了</p>
<template v-if="ok">
<h1>Algorithm</h1>
<p>學的不僅是技術,更是夢想!</p>
<p>哈哈哈!!!</p>
</template>
</div>
<script>
new Vue({
el: '#app',
data: {
seen: true,
ok: true
}
})
</script>
這裡, v-if 指令将根據表達式 seen 的值(true 或 false )來決定是否插入 p 元素。
v-else
可以用 v-else 指令給 v-if 添加一個 “else” 塊:
<!-- 随機生成一個數字,判斷是否大于0.5,然後輸出對應資訊: -->
<div id="app">
<div v-if="Math.random() > 0.5">
Sorry
</div>
<div v-else>
Not sorry
</div>
</div>
<script>
new Vue({
el: '#app'
})
</script>
v-else-if
v-else-if用作 v-if 的 else-if 塊。可以鍊式的多次使用:
<!-- 判斷 type 變量的值: -->
<div id="app">
<div v-if="type === 'A'">
A
</div>
<div v-else-if="type === 'B'">
B
</div>
<div v-else-if="type === 'C'">
C
</div>
<div v-else>
Not A/B/C
</div>
</div>
<script>
new Vue({
el: '#app',
data: {
type: 'C'
}
})
</script>
v-else 、v-else-if 必須跟在 v-if 或者 v-else-if之後。
v-show
可以使用 v-show 指令來根據條件展示元素:
九、循環周遊
循環使用 v-for 指令。
v-for 指令需要以 site in sites 形式的特殊文法, sites 是源資料數組并且 site 是數組元素疊代的别名。
v-for 可以綁定資料到數組來渲染一個清單:
<div id="app">
<ol>
<li v-for="site in sites">
{{ site.name }}
</li>
</ol>
</div>
<script>
new Vue({
el: '#app',
data: {
sites: [
{ name: 'csdn' },
{ name: 'Google' },
{ name: 'Taobao' }
]
}
})
</script>
模闆中使用 v-for:
<ul>
<template v-for="site in sites">
<li>{{ site.name }}</li>
<li>--------------</li>
</template>
</ul>
v-for 疊代對象
v-for 可以通過一個對象的屬性來疊代資料:
<div id="app">
<ul>
<li v-for="value in object">
{{ value }}
</li>
</ul>
</div>
<script>
new Vue({
el: '#app',
data: {
object: {
name: 'Algorithm',
url: 'http://www.baidu.com',
slogan: '學的不僅是技術,更是夢想!'
}
}
})
</script>
你也可以提供第二個的參數為鍵名:
<div id="app">
<ul>
<li v-for="(value, key) in object">
{{ key }} : {{ value }}
</li>
</ul>
</div>
第三個參數為索引:
<div id="app">
<ul>
<li v-for="(value, key, index) in object">
{{ index }}. {{ key }} : {{ value }}
</li>
</ul>
</div>
v-for 疊代整數
<div id="app">
<ul>
<li v-for="n in 10">
{{ n }}
</li>
</ul>
</div>
十、表單
v-model 指令在表單控件元素上建立雙向資料綁定。
輸入框
<div id="app">
<p>input 元素:</p>
<input v-model="message" placeholder="編輯我……">
<p>消息是: {{ message }}</p>
<p>textarea 元素:</p>
<p style="white-space: pre">{{ message2 }}</p>
<textarea v-model="message2" placeholder="多行文本輸入……"></textarea>
</div>
<script>
new Vue({
el: '#app',
data: {
message: 'CSDN',
message2: 'https://blog.csdn.net/'
}
})
</script>
複選框
<div id="app">
<p>單個複選框:</p>
<input type="checkbox" id="checkbox" v-model="checked">
<label for="checkbox">{{ checked }}</label>
<p>多個複選框:</p>
<input type="checkbox" id="CSDN" value="Runoob" v-model="checkedNames">
<label for="Algorithm">Algorithm</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>
new Vue({
el: '#app',
data: {
checked : false,
checkedNames: []
}
})
</script>
單選按鈕
<div id="app">
<input type="radio" id="CSDN" value="CSDN" v-model="picked">
<label for="Algorithm">Algorithm</label>
<br>
<input type="radio" id="google" value="Google" v-model="picked">
<label for="google">Google</label>
<br>
<span>選中值為: {{ picked }}</span>
</div>
<script>
new Vue({
el: '#app',
data: {
picked : 'CSDN'
}
})
</script>
select 清單
<div id="app">
<select v-model="selected" name="fruit">
<option value="">選擇一個網站</option>
<option value="https://blog.csdn.net/">CSDN</option>
<option value="www.google.com">Google</option>
</select>
<div id="output">
選擇的網站是: {{selected}}
</div>
</div>
<script>
new Vue({
el: '#app',
data: {
selected: ''
}
})
</script>