1. 程式人生 > 其它 >02-Vue基礎學習

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 樣式

    1. 陣列
      <h1 :class="['red', 'thin']">這是個邪惡的h1</h1>
    2. 陣列中使用三元表示式
      <h1 :class="['red', 'thin', isactive ? 'active' : '']">這是個邪惡的h1</h1>
    3. 陣列中巢狀物件
      <h1 :class="['red', 'thin', {'active': isactive}]">這是個邪惡的h1</h1>
    4. 直接使用物件
      <h1 :class="{red: true, thin: true, italic: true, active: isactive}">這是個邪惡的h1</h1>
  • 使用內聯樣式

    1. 直接在元素上通過:style的形式,書寫樣式物件
      <h1 :class="{color: 'red', 'font-size': '40px'}">這是個善良的h1</h1>
    2. 經樣式物件,定義到data中,並直接應用到:style
    • 在data上定義樣式
      data: {
        styleObj1: { 'color': 'red', 'font-weight': 200 },
      }
    
    • 在元素中國,通過屬性繫結的樣式,將樣式物件應用到元素中:
      <h1 :style="styleObj1">這是個善良的h1</h1>
    
    1. 多個樣式物件的使用
    • 在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)
  1. HTML元素
<td>{{ item.ctime | dataFormat('yyyy-mm-dd') }}</td>
  1. 全域性過濾器 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;
  });
  1. 私有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)

  1. 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" />
  1. 自定義全域性按鍵修飾符:
<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;
    }
  }