02-Vue基礎學習
關鍵字:
指令、過濾器、修飾符
向元素中插入值 (02.基礎v-xxx的學習.html)
- {{ msg }} 插值表示式
- v-cloak
- v-text
- v-html
- v-bind 繫結屬性機制,簡寫
:
。 - v-on 事件繫結機制,簡寫
@
,語法:v-on:不帶on的事件='註冊的函式'
,舉例:v-on:mouseover="showFn"
。 - 例項中的 this
- 跑馬燈小練習
v-model 和 雙向資料繫結 (03.v-model指令的學習.html)
v-model 是唯一一個可以實現雙向資料繫結的指令
通常在表單控制元件中使用input(radio、text、address、email...)、select、checkbox、textarea
複習了
eval()
能夠把字串儘量轉成js能夠執行的程式碼,容易被注入病毒,正式開發中儘量少用。
Vue 中如何使用樣式(04.Vue中的樣式-class.html)
-
使用 class 樣式
- 陣列
<h1 :class="['red', 'thin']">這是個邪惡的h1</h1>
- 陣列中使用三元表示式
<h1 :class="['red', 'thin', isactive ? 'active' : '']">這是個邪惡的h1</h1>
- 陣列中巢狀物件
<h1 :class="['red', 'thin', {'active': isactive}]">這是個邪惡的h1</h1>
- 直接使用物件
<h1 :class="{red: true, thin: true, italic: true, active: isactive}">這是個邪惡的h1</h1>
- 陣列
-
使用內聯樣式
- 直接在元素上通過
:style
的形式,書寫樣式物件
<h1 :class="{color: 'red', 'font-size': '40px'}">這是個善良的h1</h1>
- 經樣式物件,定義到
data
中,並直接應用到:style
中
- 在data上定義樣式
data: { styleObj1: { 'color': 'red', 'font-weight': 200 }, }
- 在元素中國,通過屬性繫結的樣式,將樣式物件應用到元素中:
<h1 :style="styleObj1">這是個善良的h1</h1>
- 多個樣式物件的使用
- 在data上定義樣式
data: { styleObj1: { 'color': 'red', 'font-weight': 200 }, styleObj2: { 'font-style': 'italic', 'letter-spacing': '0.5em' } }
- 在元素中國,通過屬性繫結的樣式,將樣式物件應用到元素中:
<h1 :style="[styleObj1, styleObj2]">這是個善良的h1</h1>
- 直接在元素上通過
v-for 和 key 屬性 (05.v-for.html)
- 迭代陣列:
<ul> <li v-for="item in list">{{item}}</li> </ul>
<ul> <li v-for="(item, index) in list">索引:{{index}}-->值:{{item}}</li> </ul>
<ul> <li v-for="(item, index) in data" :key='item.id'>id:{{item.id}}-->name:{{item.name}}</li> </ul>
- 迭代物件中的屬性:
<p v-for="(val, key, index) in user">值:{{val}} --> 鍵:{{key}} --> 索引:{{index}}</p>
- 迭代數字:
<!-- 注意:如果使用 v-for 迭代數字的話,前面的 count 是從1開始的 --> <p v-for="count in 10">這是第{{ count }}次迴圈</p>
2.2.0+ 的版本里,擋在元件中使用v-for時,key現在是必須的。
當 Vue.js 用 v-for 正在更新已渲染的元素列表時,它預設使用就地複用策略。如果資料項的順序被改變,
Vue將不是移動DOM元素來匹配資料項的順序,而是簡單複用此處每個元素,並且確保它在特定索引下顯示已被渲染過的每一個元素。
為了給Vue一個提示,以便它能跟蹤每一個節點的身份,從而重用和重新排序現有元素,你需要為每項提供一個唯一的 key 屬性。
v-if 和 v-show 指令(06.v-if和v-show.html)(16-元件切換.html)
-
v-if:
- 每次都會重新刪除或建立元素
- 有較高的切換效能消耗,如果元素涉及到頻繁的切換,最好不要使用 v-if,推薦使用 v-show 。
-
v-show:
- 每次更新不會重新進行DOM的刪除和建立操作,只是切換了元素的 display: none 樣式
- 有較高的初始渲染效能消耗,如果元素可能永遠也不會被顯示出來,給使用者看到,則推薦使用 v-if 。
-
v-else (注意:必須跟在v-if或者v-if-else的後面,不然失效)
- 如果if條件不成立顯示當前的元素
-
v-else-if 要緊跟 v-if
品牌列表的案例(07.品牌列表的案例.html)
過濾器(07.品牌列表的案例.html)
概念:Vue.js 允許你自定義過濾器,可以用作一些常見的文字格式化,過濾器可以用在兩個地方:mustache 插值和 v-bind 表示式。過濾器應該被新增在 JavaScript 表示式的尾部,由“管道”符指示
- 過濾器的語法:
Vue.filter('過濾器的名稱', function () {})
。 - 過濾器中的 function,第一個引數,已經被規定死了,永遠都是 過濾器 管道符前面傳過來的資料。
- 全域性過濾器
Vue.filter()
要寫在new Vue()
建立Vue例項之前。 - 私有過濾器
filters
。 - 過濾器呼叫的時候,採用的是就近原則,如果私有過濾器和全域性過濾器名稱一致了,優先呼叫私有過濾器。
全域性過濾器、私有過濾器(07.品牌列表的案例.html)
- HTML元素
<td>{{ item.ctime | dataFormat('yyyy-mm-dd') }}</td>
- 全域性過濾器
Vue.filter()
Vue.filter("dataFormat", function (ctime, pattern = "yyyy-mm-dd hh:mm:ss") {
const dt = new Date(ctime);
const year = dt.getFullYear();
const month = dt.getMonth() + 1;
const day = dt.getDate();
const houer = dt.getHours();
const minute = dt.getMinutes();
const second = dt.getSeconds();
let ds = "";
if (pattern && pattern.toLowerCase() === "yyyy-mm-dd") {
ds = `${year}-${month}-${day}`;
} else {
ds = `${year}-${month}-${day} ${houer}:${minute}:${second}`;
};
return ds;
});
- 私有
filters
定義方式:
const vm = new Vue({
el: "#app",
data: {...},
methods: {...},
filters: {
dataFormat: function (ctime, pattern = "yyyy-mm-dd hh:mm:ss") {
const dt = new Date(ctime);
const year = dt.getFullYear();
const month = dt.getMonth() + 1;
const day = dt.getDate();
const houer = dt.getHours();
const minute = dt.getMinutes();
const second = dt.getSeconds();
let ds = "";
if (pattern && pattern.toLowerCase() === "yyyy-mm-dd") {
ds = `${year}-${month}-${day}`;
} else {
ds = `${year}-${month}-${day} ${houer}:${minute}:${second}`;
};
return ds;
}
}
});
使用 ES6 字串新方法
String.prototype.padStart(maxLenght, fillString="")
或者String.prototype.padEnd(maxLenght, fillString="")
來填充字串
例子:
"1".padStart(2, 0) // "01"
事件修飾符(07.品牌列表的案例.html)
.stop => event.stopPropagation() // 阻止冒泡
.prevent => 呼叫 event.preventDefault() // 阻止預設行為
舉例:
阻止 的預設跳轉事件 @click.prevent="function"
html <a href="" @click.prevent="del(item)">刪除</a> <!-- 也可以設定 href="javascript:;" 防止 a 標籤跳轉頁面 --> <!-- <a href="javascript:;" @click="del(item)">刪除</a> -->
按鍵修飾符、自定義按鍵修飾符(07.品牌列表的案例.html)
- Vue 提供的按鍵修飾符:
- enter / 13
- tab
- delete (捕獲“刪除”和“退格”)
- esc
- space
- up
- dowm
- left
- right
語法:
- 監聽所有案件的抬起事件:
@keyup="fun"
, - 監聽某個案件的抬起事件
@keyup.按鍵修飾符="fun"
或者@keyup.鍵盤碼="fun"
。
舉例:
<input type="text" v-model="name" @keyup.enter="add" />
<input type="text" v-model="name" @keyup.13="add" />
- 自定義全域性按鍵修飾符:
<input type="text" v-model="name" @keyup.f2="add" />
// 113 是 F2 的鍵盤碼。
Vue.config.keyCodes.f2 = 113;
自定義全域性指令(07.品牌列表的案例.html)
注意:Vue中的所有指令,在呼叫的時候,都是以 v- 開頭的。
通過 Vue.directive();
來定義全域性指令。
其中 引數1:指令的名稱。注意:在定義的時候,指令的名稱前面,不需要加v-
字首,但是在呼叫的時候,必須在指令名稱前加上v-
字首來進行呼叫
引數2:是一個物件,這個物件身上,有一些指令相關的鉤子函式,這些鉤子函式可以在特定的階段,執行相關操作。
語法以及使用舉例:
// 全域性過濾器,所有的例項都共享
// 過濾器的語法: `Vue.filter('過濾器的名稱', function () {})`
// 過濾器中的 function,第一個引數,已經被規定死了,永遠都是 過濾器 管道符前面傳過來的資料
// 過濾器 `Vue.filter()` 要寫在 `new Vue()` 建立Vue例項之前
Vue.filter("dataFormat", function (ctime, pattern = "yyyy-mm-dd hh:mm:ss") {
const dt = new Date(ctime);
const year = dt.getFullYear();
const month = dt.getMonth() + 1;
const day = dt.getDate();
const houer = dt.getHours();
const minute = dt.getMinutes();
const second = dt.getSeconds();
let ds = "";
if (pattern && pattern.toLowerCase() === "yyyy-mm-dd") {
ds = `${year}-${month}-${day}`;
} else {
ds = `${year}-${month}-${day} ${houer}:${minute}:${second}`;
};
return ds;
});
使用:
<div>
{{item.ctime | dataFormat()}}
</div>
註冊區域性指令(07.品牌列表的案例.html)
舉例:input 文字框自動獲取焦點
const vm = new Vue({
el: "#app",
data: {
keyword: "",
...
},
methods: { // 自定義私有方法
...
},
filters: { // 自定義一個私有的過濾器
...
},
directives: { // 註冊區域性指令(自定義私有指令)
focus: {
// 指令的定義
inserted: function (el) {
el.focus()
}
}
}
});
<input type="text" v-model="keyword" v-focus></input>
鉤子函式
一個指令定義物件可以提供如下幾個鉤子函式 (均為可選):
- bind:只調用一次,指令第一次繫結到元素時呼叫。在這裡可以進行一次性的初始化設定。
- inserted:被繫結元素插入父節點時呼叫 (僅保證父節點存在,但不一定已被插入文件中)。
- update:所在元件的 VNode 更新時呼叫,但是可能發生在其子 VNode 更新之前。指令的值可能發生了改變,也可能沒有。但是你可以通過比較更新前後的值來忽略不必要的模板更新 (詳細的鉤子函式引數見下)。
- componentUpdated:指令所在元件的 VNode 及其子 VNode 全部更新後呼叫。
- unbind:只調用一次,指令與元素解綁時呼叫。
接下來我們來看一下鉤子函式的引數 (即 el、binding、vnode 和 oldVnode)。
鉤子函式引數
指令鉤子函式會被依次傳入以下引數:
- el:指令所繫結的元素,可以用來直接操作 DOM。
- binding:一個物件,包含以下 property:
- name:指令名,不包括 v- 字首。
- value:指令的繫結值,例如:v-my-directive="1 + 1" 中,繫結值為 2。
- oldValue:指令繫結的前一個值,僅在 update 和 componentUpdated 鉤子中可用。無論值是否改變都可用。
- expression:字串形式的指令表示式。例如 v-my-directive="1 + 1" 中,表示式為 "1 + 1"。
- arg:傳給指令的引數,可選。例如 v-my-directive:foo 中,引數為 "foo"。
- modifiers:一個包含修飾符的物件。例如:v-my-directive.foo.bar 中,修飾符物件為 { foo: true, bar: true }。
- vnode:Vue 編譯生成的虛擬節點。移步 VNode API 來了解更多詳情。
- oldVnode:上一個虛擬節點,僅在 update 和 componentUpdated 鉤子中可用。
除了 el 之外,其它引數都應該是隻讀的,切勿進行修改。如果需要在鉤子之間共享資料,建議通過元素的 dataset 來進行。
指令函式的簡寫形式
directives: { // 註冊區域性指令
// focus: { // 指令的定義,完整寫法
// inserted: function (el) {
// el.focus()
// }
// },
'fontSize': function(el){ // 註冊指令 **簡寫** ,會同時註冊到 `bind` 和 `updata` 鉤子函式中去
const value = parseInt(binding.value) + "px";
el.style.fontSize = value;
}
}