建立 vue 例項
index.html
檔案:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>My first Vue</title>
<!-- 引入樣式檔案 -->
<link rel="stylesheet" href="styles.css">
<!-- 引入 vue 的包 -->
<script src="https://cdn.jsdelivr.net/npm/vue"></script>
</head>
<body>
<!-- 對應 app.js 檔案中 el:'#vue-app' 的 vue 例項 -->
<div id="vue-app">
<h1>{{ name }}</h1>
</div>
<!-- 引入 js 檔案 -->
<script src="app.js"></script>
</body>
</html>
app.js
檔案:
// 建立 vue 例項
new Vue({
// 與 index.html 檔案中 id="vue-app" 的 div 對應, 包含在這個 vue 例項的資料和方法, 都可以作用於這個 div 中.
el:'#vue-app',
data:{
name:'Rachel'
}
});
總結, 就是在 js 檔案中處理資料以達到在頁面上動態展現資料的效果.
data & methods
Html:
<div id="vue-app">
<p>{{ greet('afternoon') }}</p>
</div>
JS:
new Vue({
el: '#vue-app',
data: {
name: 'Rachel'
},
methods: {
greet: function(time) {
return 'Good ' + time + ' ' + this.name;
}
}
});
輸出: Good afternoon Rachel
Data binding 資料繫結
流程/格式:
在 html 標籤中新增:
v-bind: (標籤的任意屬性)="xxx"在 js 檔案中:
給 xxx 賦值即可.
Html:
<!-- 繫結連結的三種方式 -->
<a v-bind:href="website">LearnKu</a>
<a :href="website">LearnKu</a>
<p v-html="websiteTag"></p>
<!-- 繫結 input 框的值 -->
<input v-bind:value="name" type="text">
JS:
data: {
website: "https://learnku.com",
websiteTag: '<a href="https://learnku.com">LearnKu</a>',
},
Events 事件
<div id="vue-app">
<p>My age is {{ age }}</p>
<!-- 繫結點選事件, 點選時觸發 add 方法, 如果不需要傳參, 事件中的方法可以不寫括號 -->
<button v-on:click="add(1)">Add a year</button>
<!-- 簡寫方式 -->
<button @click="add(2)">Add 2 years</button>
<!-- 繫結雙擊事件 -->
<button v-on:dblclick="add(10)">Add 10 years</button>
<!-- 加上 once, 使點選事件只生效一次 -->
<button @click.once="add(3)">Add 3 years</button>
<!-- 在 a 標籤上繫結點選事件, 可以加上 "prevent" 以阻止跳轉 -->
<a v-on:click.prevent="click" href="https://learnku.com">LearnKu</a>
</div>
new Vue({
el: '#vue-app',
data: {
age: 25
},
methods: {
add:function(inc) {
this.age += inc;
},
click: function() {
alert('You clicked me');
}
}
});
Keyboard Events 鍵盤事件
<!-- 繫結鍵盤點選事件, 按鍵抬起一次, 就執行一次 logName 方法 -->
<input type="text" v-on:keyup="logName">
<!-- 回車時, 執行 logName 方法 -->
<input type="text" v-on:keyup.enter="logName">
<!-- 同時按下 alt 鍵和Enter鍵, 執行 logName 方法 -->
<input type="text" v-on:keyup.alt.enter="logName">
logName: function() {
console.log('You entered your name');
}
Two-way Data Building 資料的雙向傳輸
<!-- 接收使用者輸入的資料 -->
<input type="text" v-model="name">
<!-- 同步輸出使用者輸入的每個字元-->
<span>{{ name }}</span>
<!-- 接收使用者輸入的資料 -->
<input type="text" v-model.lazy="title">
<!--當使用者按 tab 鍵時, 一次性輸出使用者的輸入-->
<span>{{ title }}</span>
data: {
name: '',
title: ''
},
雙向傳輸圖示:
Computed Properties
<p>Age: {{ age }}</p>
<button v-on:click="a++">AddtoA</button>
<p>A: {{ a }}</p>
<p>Age + A = {{ addToA() }}</p>
<button v-on:click="b++">AddtoB</button>
<p>B: {{ b }}</p>
<p>Age + B = {{ addToB() }}</p>
data: {
// 給 a 和 b 均設初始值為 0
a: 0,
b: 0,
age: 25,
},
methods: {
addToA: function() {
// 便於在控制檯檢視方法被觸發的時機
console.log('addToA');
return this.a + this.age;
},
addToB: function() {
// 便於在控制檯檢視方法被觸發的時機
console.log('addToB');
return this.b + this.age;
}
}
按照上面這段程式碼, 單獨點選哪個 button, 兩個 methods 都會被執行, 這有損效能.
改進: 把 methods 中的程式碼挪到 computed 屬性中, 它跟 methods 的作用很像, 區別就是它會檢查方法中的資料是否有改變, 如果沒有改變, 就不會執行, 就是定位更準確點吧.
computed: {
addToA: function() {
console.log('addToA');
return this.a + this.age;
},
addToB: function() {
console.log('addToB');
return this.b + this.age;
}
}
Html 中的程式碼稍作改動, 把呼叫方法的括號去掉, 否則報錯:
<p>Age + A = {{ addToA }}</p>
<p>Age + B = {{ addToB }}</p>
Dynamic CSS 動態樣式
方式一:
<!-- 繫結屬性, 屬性名: 屬性值(true/false), 用 true/false 控制是否新增此屬性 -->
<div v-bind:class="{red:true, blue:false}"></div>
方式二(更加動態的方式):
把屬性 a 的值用變數 available 表示, 在 js 檔案中控制其為 true or false
新增點選事件, 控制 js 檔案中 available 的值, 從而控制 class a 是否生效.
index.html
檔案
<div v-on:click="available = !available" v-bind:class="{a: available}">
<span>Rachel</span>
</div>
app.js
檔案
data: {
available: true,
},
style.css
檔案
span {
background: red;
display: inline-block;
}
.a span {
background: green
}
方式三:
最解耦的方式, 特別適合於一個元素上有很多個類的情況, 不需要在 html 中羅列所有的類, 而只需要在指定一個變數名, 然後在 js 檔案中編輯所有的類就可以了:
<!--當點選的時候改變 js 檔案中 data 裡的值 -->
<button v-on:click="available = !available">Toggle a</button>
<button v-on:click="nearby = !nearby">Toggle b</button>
<div v-bind:class="compClass">
<span>Rachel</span>
</div>
data: {
available: false,
nearby: false
},
computed: {
compClass: function() {
return {
a: this.available,
b: this.nearby
}
}
}
Conditionals 條件判斷
<button v-on:click="error= !error">Toggle Error</button>
<button v-on:click="success= !success">Toggle Success</button>
<!-- 方式一 -->
<!-- 如果 false, 就不顯示 p 標籤 -->
<p v-if="error">Error</p>
<p v-else-if="success">Success</p>
<!-- 方式二 -->
<!-- 如果 false, 會在 p 標籤上加上 style="display: none;" -->
<p v-show="error">Error</p>
<p v-show="success">Success</p>
data: {
error: false,
success: false
}
Loop for 迴圈
<ul>
<li v-for="character in characters">
{{ character }}
</li>
</ul>
<!-- 遍歷含有物件的陣列 -->
<ul>
<li v-for="info in infos">
{{info.name}} - {{ info.age}}
</li>
</ul>
<!-- 遍歷時加索引 -->
<ul>
<li v-for="(info, index) in infos">
{{ index }}. {{info.name}} - {{ info.age}}
</li>
</ul>
<!-- template 標籤不會被渲染 -->
<!-- 遍歷陣列 -->
<template v-for="info in infos">
<!-- 遍歷輸出物件的 key / value -->
<div v-for="(val, key) in info">
<p>{{ key }} - {{ val }}</p>
</div>
</template>
data: {
characters: ['Rachel', 'Ross', 'Emma'],
infos: [
{name: 'Rachel', age: 25},
{name: 'Ross', age: 30},
{name: 'Emma', age: 2}
]
}
Intro to Component
component is a reusable piece of code or template that we can use in different view instance.
<!-- 對應第一個 vue 例項 -->
<div id="vue-app-one">
<!-- 被複用的 template -->
<greeting></greeting>
</div>
<!-- 對應第二個 vue 例項 -->
<div id="vue-app-two">
<!-- 被複用的 template -->
<greeting></greeting>
</div>
// 對於 greeting 標籤, 在此定義一次, 就可以在多個 vue 例項中複用
Vue.component('greeting', {
template: "<p>Hey there, I am {{name}}. <button v-on:click='changeName'>Change</button></p>",
// 在這裡的 data 不是物件, 而是一個函式, 在函式裡返回物件, data 函式有下面兩種寫法, 都可以
// 寫法一
data:function() {
return {
name: 'Rachel'
}
},
// 寫法二
data() {
return {
name: 'Rachel'
}
},
methods: {
changeName: function() {
this.name = 'Mario'
}
}
});
// 第一個 vue 例項
var one = new Vue({
el: '#vue-app-one',
});
// 第二個 vue 例項
var two = new Vue({
el: '#vue-app-two',
});
Refs
通過標籤的 ref 屬性, 可以在 js 檔案中獲取這個標籤的所有資訊.
<!--給 input 標籤加 ref 屬性, 名字是自定義的, 在 js 中取的時候可以定位到這個標籤-->
<input type="text" ref="input">
<button v-on:click="readRefs">Submit</button>
<p>Your fav food is {{ output }}</p>
<!--給 div 標籤加 ref 屬性-->
<div ref="test">Hello</div>
data: {
output: "Your fav food"
},
methods: {
readRefs: function() {
// 獲取 input 標籤的資訊
this.output = this.$refs.input.value;
// 獲取 div 標籤的資訊
alert(this.$refs.test.innerHTML);
}
}
單獨列印 this.$refs
可以看到所有帶 ref 屬性的元素的詳細資訊:
console.log(this.$refs);