你們好,這裏是「 從零開始學 Web 系列教程 」,並在下列地址同步更新......javascript
- github:https://github.com/Daotin/Web
- 微信公衆號:Web前端之巔
- 博客園:http://www.cnblogs.com/lvonve/
- CSDN:https://blog.csdn.net/lvonve/
在這裏我會從 Web 前端零基礎開始,一步步學習 Web 相關的知識點,期間也會分享一些好玩的項目。如今就讓咱們一塊兒進入 Web 前端學習的冒險之旅吧!html
以下圖,前端
一、實現輸入id和name後,點擊add按鈕,添加到table中;vue
二、點擊數據的del,能夠刪除這條數據。java
代碼:git
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Document</title> <script src="./lib/vue-2.4.0.js"></script> <style> * { padding: 0; margin: 0; position: relative; } /* 實現任意無寬高盒子居中顯示 */ #app { position: absolute; left: 50%; top: 100px; transform: translateX(-50%); } .box { width: 500px; height: 40px; background-color: #ccc; display: inline-block; text-align: center; line-height: 40px; border: 1px solid #aaa; box-sizing: border-box; border-bottom: none; } .tb { width: 500px; text-align: center; border-collapse: collapse; border-color: #ccc; } </style> </head> <body> <div id="app"> <div class="box"> <label for="id"> ID: <input type="text" id="id" v-model="id"> </label> <label for="name"> name: <input type="text" id="name" v-model="name"> </label> <input type="button" value="add" @click="addClick"> </div> <table border="1" cellspacing="0" class="tb"> <tr v-for="item in list"> <td>{{item.id}}</td> <td>{{item.name}}</td> <td>{{item.ctime}}</td> <td> <!-- 綁定的事件是能夠傳參數的,這裏傳入須要刪除的對象id --> <a href="javascript:;" @click.prevent="delClick(item.id)">del</a> </td> </tr> </table> </div> <script> var vm = new Vue({ el: "#app", data: { id: "", name: "", list: [{ id: 1, name: 'tony', ctime: new Date() }, { id: 2, name: 'stark', ctime: new Date() } ] }, methods: { addClick() { // 1.獲取表單數據 // 2.組織出一個對象 // 3.將對象添加到data中(不須要從新渲染頁面) let item = { id: this.id, name: this.name, ctime: new Date() }; if ((this.id != "") && (this.name != "")) { this.list.push(item); } // 4.最後將表單清空 this.id = this.name = ""; }, delClick(id) { // 1.根據id找到索引(循環查找) // 2.調用數組的 splice方法刪除 this.list.filter((item, index) => { if (item.id == id) { this.list.splice(index, 1); return true; } }); } } }); </script> </body> </html>
注意:github
一、事件名後面能夠加括號(
@click="addClick"
等價於@click="addClick()
,這樣寫的話,就能夠傳參。)express
在Query中輸入字符串,若是name項中包括Query中的字符串,則顯示。數組
分析:微信
若是要知足條件才顯示相關行,那麼 <tr v-for="item in list">
中的list就是一個可變的。這裏咱們使用一個函數,函數裏面進行判斷是否包含Query中的字符串,而後將包含的拷貝到新數組中,填充到list的位置:
<tr v-for="item in search(keywords)">
methods: { addClick() { //... }, delClick(id) { //... }, // 添加的用於判斷的函數 search(keywords) { // 定義新數組保存符合條件的項 let newList = []; this.list.forEach((item, index) => { // 包含則返回true if (item.name.includes(keywords)) { newList.push(item); } }); return newList; } }
所有源碼:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>Document</title> <script src="./lib/vue-2.4.0.js"></script> <style> * { padding: 0; margin: 0; position: relative; } /* 實現任意無寬高盒子居中 */ #app { position: absolute; left: 50%; top: 100px; transform: translateX(-50%); } .box { width: 800px; height: 40px; background-color: #ccc; display: inline-block; text-align: center; line-height: 40px; border: 1px solid #aaa; box-sizing: border-box; border-bottom: none; } .box>input[type="button"] { width: 60px; background-color: #aaa; border: 0; border: 1px solid #aaa; } .tb { width: 800px; text-align: center; border-collapse: collapse; border-color: #ccc; } </style> </head> <body> <div id="app"> <div class="box"> <label for="id"> ID: <input type="text" id="id" v-model="id"> </label> <label for="name"> name: <input type="text" id="name" v-model="name"> </label> <input type="button" value="add" @click="addClick"> <label for="sel"> Query: <input type="text" id="sel" v-model="keywords"> </label> </div> <table border="1" cellspacing="0" class="tb"> <!-- 有查詢的話,這裏就不該該固定死,而是根據keywords動態生成新的數組 --> <!-- <tr v-for="item in list"></tr> --> <tr v-for="item in search(keywords)"> <td>{{item.id}}</td> <td>{{item.name}}</td> <td>{{item.ctime | ctimeFormat}}</td> <td> <!-- 綁定的事件是能夠傳參數的,這裏傳入須要刪除的對象id --> <a href="javascript:;" @click.prevent="delClick(item.id)">del</a> </td> </tr> </table> </div> <script> // ctime 過濾器 Vue.filter('ctimeFormat', (data) => { let time = new Date(data); let year = time.getFullYear(); let month = (time.getMonth() + 1).toString().padStart(2, '0'); let day = (time.getDate()).toString().padStart(2, '0'); let hour = (time.getHours()).toString().padStart(2, '0'); let minute = (time.getMinutes()).toString().padStart(2, '0'); let second = (time.getSeconds()).toString().padStart(2, '0'); return `${year}-${month}-${day} ${hour}:${minute}:${second}`; }); var vm = new Vue({ el: "#app", data: { id: "", name: "", keywords: "", list: [{ id: 1, name: 'tony', ctime: new Date() }, { id: 2, name: 'stark', ctime: new Date() } ] }, methods: { addClick() { // 1.獲取表單數據 // 2.組織處一個對象 // 3.將對象添加到data中(不須要從新渲染頁面) let item = { id: this.id, name: this.name, ctime: new Date() }; if ((this.id != "") && (this.name != "")) { this.list.push(item); } // 4.最後將表單清空 this.id = this.name = ""; }, delClick(id) { // 1.根據id找到索引(循環查找) // 2.調用數組的 splice方法刪除 this.list.filter((item, index) => { if (item.id == id) { this.list.splice(index, 1); return true; } }); }, search(keywords) { // 定義新數組保存符合條件的項 let newList = []; this.list.forEach((item, index) => { // 包含則返回true if (item.name.includes(keywords)) { newList.push(item); } }); return newList; } } }); </script> </body> </html>
vue 容許自定義過濾器,可被用做一些常見的文本格式化。
過濾器只能用在兩個地方:插值表達式和 v-bind
表達式 。
基本用法:
<body> <div id="box"> <p>{{msg | msgFormat}}</p> </div> <script> // 使用Vue.filter來定義一個過濾器: // 第一個參數:過濾器函數名稱 // 第二個參數:過濾器函數體 // 過濾器的參數就是管道符的前面待處理的字符串。 Vue.filter('msgFormat', (data) => { return data.replace("vue", "Daotin"); }); var vm = new Vue({ el: " #box ", data: { msg: "hello vue" }, methods: {} }); </script> </body>
一、使用 Vue.filter(); 來定義一個過濾器。
二、第一個參數:過濾器函數名稱;第二個參數:過濾器函數體
三、過濾器的參數就是管道符的前面待處理的字符串。
插值表達式裏的過濾器函數能夠帶參數:
相應的,在 Vue.filter('msgFormat', (data, arg1,arg2,...) 中msgFormat 的參數從第二位開始放置。
能夠帶多個參數。
<body> <div id="box"> <p>{{msg | msgFormat('is a boy', 'and good')}}</p> </div> <script> // 使用Vue.filter來定義一個過濾器: // 第一個參數:過濾器函數名稱 // 第二個參數:過濾器函數體 // 過濾器的參數就是管道符的前面待處理的字符串。 Vue.filter('msgFormat', (data, arg1, arg2) => { return data.replace("vue", "Daotin " + arg1 + arg2); }); var vm = new Vue({ el: " #box ", data: { msg: "hello vue" }, methods: {} }); </script> </body>
使用全局過濾器格式化品牌管理案例的 ctime:
<td>{{item.ctime | ctimeFormat}}</td> ... // ctime 過濾器 Vue.filter('ctimeFormat', (data) => { let time = new Date(data); let year = time.getFullYear(); let month = time.getMonth() + 1; let day = time.getDate(); let hour = time.getHours(); let minute = time.getMinutes(); return `${year}-${month}-${day} ${hour}:${minute}`; });
全局過濾器就是若是有多個vm實例的話,全部的VM實例均可以使用。
全局過濾器書寫在 script直接標籤下。
而私有過濾器書寫在VM對象中:
注意:過濾器的調用原則是就近原則,即先調用私有過濾器再調用全局過濾器。
padStart和padEnd
// ctime 過濾器 Vue.filter('ctimeFormat', (data) => { let time = new Date(data); let year = time.getFullYear(); let month = (time.getMonth() + 1).toString().padStart(2, '0'); let day = (time.getDate()).toString().padStart(2, '0'); let hour = (time.getHours()).toString().padStart(2, '0'); let minute = (time.getMinutes()).toString().padStart(2, '0'); let second = (time.getSeconds()).toString().padStart(2, '0'); return `${year}-${month}-${day} ${hour}:${minute}:${second}`; });
使用ES6中的字符串新方法
String.prototype.padStart(maxLength, fillString='')
或String.prototype.padEnd(maxLength, fillString='')
來填充字符串;padStart:從開頭填充
padEnd:從結尾填充
maxLength:填充後最大的長度
fillString:須要填充的字符串(fillString='',不填則以空字符填充)
咱們如今有個需求就是輸入ID和name後不點擊add按鈕,而是按下回車鍵也須要添加到列表中。
咱們能夠在name輸入框中加入按鍵擡起事件,而且指定是enter鍵擡起時才觸發。
<label for="name"> name: <input type="text" id="name" v-model="name" @keyup.enter="addClick">
.enter
: 就是按鍵修飾符。
系統提供的按鍵修飾符有:
.enter
.tab
.delete
(捕獲「刪除」和「退格」鍵).esc
.space
.up
.down
.left
.right
若是咱們想自定義其餘的按鍵怎麼辦呢?
經過Vue.config.keyCodes.f2 = 113;
;能夠將f2做爲按鍵修飾符添加到系統按鍵修飾符中。
具體每一個按鍵的值是多少?下面是常見的按鍵的碼。
keyCode 8 = BackSpace BackSpace keyCode 9 = Tab Tab keyCode 12 = Clear keyCode 13 = Enter keyCode 16 = Shift_L keyCode 17 = Control_L keyCode 18 = Alt_L keyCode 19 = Pause keyCode 20 = Caps_Lock keyCode 27 = Escape Escape keyCode 32 = space keyCode 33 = Prior keyCode 34 = Next keyCode 35 = End keyCode 36 = Home keyCode 37 = Left keyCode 38 = Up keyCode 39 = Right keyCode 40 = Down keyCode 41 = Select keyCode 42 = Print keyCode 43 = Execute keyCode 45 = Insert keyCode 46 = Delete keyCode 47 = Help keyCode 48 = 0 equal braceright keyCode 49 = 1 exclam onesuperior keyCode 50 = 2 quotedbl twosuperior keyCode 51 = 3 section threesuperior keyCode 52 = 4 dollar keyCode 53 = 5 percent keyCode 54 = 6 ampersand keyCode 55 = 7 slash braceleft keyCode 56 = 8 parenleft bracketleft keyCode 57 = 9 parenright bracketright keyCode 65 = a A keyCode 66 = b B keyCode 67 = c C keyCode 68 = d D keyCode 69 = e E EuroSign keyCode 70 = f F keyCode 71 = g G keyCode 72 = h H keyCode 73 = i I keyCode 74 = j J keyCode 75 = k K keyCode 76 = l L keyCode 77 = m M mu keyCode 78 = n N keyCode 79 = o O keyCode 80 = p P keyCode 81 = q Q at keyCode 82 = r R keyCode 83 = s S keyCode 84 = t T keyCode 85 = u U keyCode 86 = v V keyCode 87 = w W keyCode 88 = x X keyCode 89 = y Y keyCode 90 = z Z keyCode 96 = KP_0 KP_0 keyCode 97 = KP_1 KP_1 keyCode 98 = KP_2 KP_2 keyCode 99 = KP_3 KP_3 keyCode 100 = KP_4 KP_4 keyCode 101 = KP_5 KP_5 keyCode 102 = KP_6 KP_6 keyCode 103 = KP_7 KP_7 keyCode 104 = KP_8 KP_8 keyCode 105 = KP_9 KP_9 keyCode 106 = KP_Multiply KP_Multiply keyCode 107 = KP_Add KP_Add keyCode 108 = KP_Separator KP_Separator keyCode 109 = KP_Subtract KP_Subtract keyCode 110 = KP_Decimal KP_Decimal keyCode 111 = KP_Divide KP_Divide keyCode 112 = F1 keyCode 113 = F2 keyCode 114 = F3 keyCode 115 = F4 keyCode 116 = F5 keyCode 117 = F6 keyCode 118 = F7 keyCode 119 = F8 keyCode 120 = F9 keyCode 121 = F10 keyCode 122 = F11 keyCode 123 = F12 keyCode 124 = F13 keyCode 125 = F14 keyCode 126 = F15 keyCode 127 = F16 keyCode 128 = F17 keyCode 129 = F18 keyCode 130 = F19 keyCode 131 = F20 keyCode 132 = F21 keyCode 133 = F22 keyCode 134 = F23 keyCode 135 = F24
示例:
<input type="text" id="name" v-model="name" @keyup.f2="addClick"> //... <script> Vue.config.keyCodes.f2 = 113; </script>
除了核心功能默認內置的指令 (v-model
等),Vue 也容許註冊自定義指令。自定義指令是以 v-
開頭的指令。
好比咱們想讓品牌管理案例中,在剛進入頁面的時候,就獲取 Query輸入框的焦點,可是vue並無提供這樣的指令。
以前咱們能夠經過獲取DOM元素,而後使用 DOM元素.focus();
方法來獲取焦點。可是在vue裏面不推薦獲取DOM元素的方式。這時咱們可使用自定義指令的方式來達到獲取焦點。
好比:咱們想定義一個v-focus
的指令來獲取焦點。
<label for="sel"> Query: <input type="text" id="sel" v-model="keywords" v-focus> </label> <script> // 自定義全局指令 v-focus,爲綁定的元素自動獲取焦點: Vue.directive('focus', { inserted: function (el) { // inserted 表示被綁定元素插入父節點時調用 el.focus(); } }); </script>
一、定義自定義指令的時候,不須要加
v-
,使用的時候須要加。二、注意: 在每一個 函數中,第一個參數,永遠是
el
,表示 被綁定了指令的那個元素,這個 el 參數,是一個原生的JS對象。三、和JS行爲有關的操做,最好在
inserted
中去執行
inserted 是鉤子函數,相似的鉤子函數還有幾個,可是應用場景不一樣:
inserted
:被綁定元素插入DOM元素時調用一次(從內存渲染到頁面時若是綁定了 inserted 就執行)。bind
:只調用一次,指令第一次綁定到元素時調用。在這裏能夠進行一次性的初始化設置(在代碼加載到內存中的時候,若是綁定了bind就執行,好比樣式style的設定,使用bind綁定)。update
:所在組件的 VNode 更新時調用,可是可能發生在其子 VNode 更新以前。指令的值可能發生了改變,也可能沒有。總結:通常:
一、與JS行爲相關的操做在inserted中執行;
二、與樣式相關的在bind中執行。
指令鉤子函數會被傳入如下參數:
el
:指令所綁定的元素,能夠用來直接操做 DOM 。binding
:一個對象,包含如下屬性:
name
:指令名,不包括 v-
前綴。value
:指令的綁定值,例如:v-my-directive="1 + 1"
中,綁定值爲 2
。expression
:字符串形式的指令表達式。例如 v-my-directive="1 + 1"
中,表達式爲 "1 + 1"
。咱們能夠爲自定義指令賦值,好比咱們想給Query文本框的字體顏色賦值:
<label for="sel"> Query: <input type="text" id="sel" v-model="keywords" v-focus v-color="'red'"> </label>
之因此使用
v-color="'red'"
,而不是v-color="red"
,是由於若是是red字符串的話,就當作變量在vue的data中查找,而這裏要表達的是字符串red。
自定義v-color指令:
Vue.directive("color", { bind(el, binding) { el.style.color = binding.value; } });
binding:這個名稱能夠隨意。
自定義私有指令就是在vm實例中加入 directives
屬性,它是一個對象,其中屬性爲自定義指令的名稱(不加 v-),值也是一個對象,對象裏面是鉤子函數列表。
var vm = new Vue({ el: "#app", data: { //... }, methods: { //... }, directives: { "color": { bind(el, binding) { el.style.color = binding.value; } } } });
咱們以前都是在自定義指令名稱的後面跟上一個對象,裏面寫上 bind,inserted,update的鉤子函數列表。
如今簡寫的話,就不須要跟上一個對象了:
directives: { "color": (el, binding) => { el.style.color = binding.value; } }
自定義名稱後能夠直接跟上一個匿名函數,這個匿名函數就至關於bind和update的鉤子函數集合。因此,若是你只須要在bind或者update中進行元素的設置的話,就能夠用這種簡寫的方式,固然若是是inserted的話,仍是要寫回對象的方式。