vue 學習筆記(二)

最近公司趕項目,一直也沒時間看 vue,以前看下的都快忘得差很少了。哈哈哈,來一塊兒回顧一下vue 學習筆記(一)後,繼續向下看嘛。html

#表單輸入綁定

基礎用法vue

  1. v-model 會忽略全部表單元素的 value、checked、selected 特性的初始值而老是將 Vue 實例的數據做爲數據來源。你應該經過 JavaScript 在組件的 data 選項中聲明初始值。
  2. 對於須要使用輸入法 (如中文、日文、韓文等) 的語言,你會發現 v-model 不會在輸入法組合文字過程當中獲得更新。若是你也想處理這個過程,請使用 input 事件。(手敲一個「中文」,在輸入法中有「zhongwen」的拼音,而且有「中文」等選項能夠選擇,從輸入拼音,到選擇結束,這個過程就叫作 「輸入法組合文字過程」)

譬如:webpack

<span>Multiline message is:</span>
<p style="white-space: pre-line;">{{ message }}</p>
<br>
<textarea v-model="message" placeholder="add multiple lines"></textarea>

在文本區域插值 (<textarea></textarea>) 並不會生效,應用 v-model 來代替。web

順便了解一下 white-space 的屬性值:json

  • pre 按給的文字格式顯示
  • pre-line 合併多個空白符,但可正常換行
  • pre-wrap 保留多個空白符,能夠正常換行
  • no-wrap 不換行
  • inherit 從符元素繼承 white-space 屬性值
  • normal 默認。空白會被瀏覽器忽略

當有多個同類型表單元素時,通常都加上 value。譬如:數組

// 單個複選框,綁定到布爾值
<input type="checkbox" id="checkbox" v-model="checked">
<label for="checkbox">{{ checked }}</label>

// 多個複選框,綁定到同一個數組
<div id='example-3'>
  <input type="checkbox" id="jack" value="Jack" v-model="checkedNames">
  <label for="jack">Jack</label>
  <input type="checkbox" id="john" value="John" v-model="checkedNames">
  <label for="john">John</label>
  <input type="checkbox" id="mike" value="Mike" v-model="checkedNames">
  <label for="mike">Mike</label>
  <br>
  <span>Checked names: {{ checkedNames }}</span>
</div>

技巧說明:瀏覽器

<div id="example-5">
  <select v-model="selected">
    <option disabled value="">請選擇</option>
    <option>A</option>
    <option>B</option>
    <option>C</option>
  </select>
  <span>Selected: {{ selected }}</span>
</div>
new Vue({
  el: '...',
  data: {
    selected: ''
  }
})

若是 v-model 表達式的初始值未能匹配任何選項,<select> 元素將被渲染爲「未選中」狀態。在 iOS 中,這會使用戶沒法選擇第一個選項。由於這樣的狀況下,iOS 不會觸發 change 事件。所以,更推薦像上面這樣提供一個值爲空的禁用選項。ide

值綁定函數

對於單選按鈕,複選框及選擇框的選項,v-model 綁定的值一般是靜態字符串 (對於複選框也能夠是布爾值),但有時咱們可能想把值綁定到 Vue 實例的一個動態屬性上,這時能夠用 v-bind 實現,而且這個屬性的值能夠不是字符串。譬如:post

// 複選
<input
  type="checkbox"
  v-model="toggle"
  true-value="yes"
  false-value="no"
>

// 單選
<input type="radio" v-model="pick" v-bind:value="a">

// 下拉列表
<select v-model="selected">
    <!-- 內聯對象字面量 -->
  <option v-bind:value="{ number: 123 }">123</option>
</select>
// 當選中時
vm.toggle === 'yes'
// 當沒有選中時
vm.toggle === 'no'

// 當選中時
vm.pick === vm.a

// 當選中時
typeof vm.selected // => 'object'
vm.selected.number // => 123

這裏的 true-value 和 false-value 特性並不會影響輸入控件的 value 特性,由於瀏覽器在提交表單時並不會包含未被選中的複選框。若是要確保表單中這兩個值中的一個可以被提交,(好比「yes」或「no」),請換用單選按鈕。

並無理解到 true-value 和 false-value 有什麼用? // todo


修飾符

  1. .lazy 在默認狀況下,v-model 在每次 input 事件觸發後將輸入框的值與數據進行同步。你能夠添加 lazy 修飾符,從而轉變爲使用 change 事件進行同步.(有丟丟沒理解上 // todo)譬如:
<!-- 在「change」時而非「input」時更新 -->
<input v-model.lazy="msg" >
  1. .number 想自動將用戶的輸入值轉爲數值類型,能夠給 v-model 添加 number 修飾符;即便在 type="number" 時,HTML 輸入元素的值也總會返回字符串。
  2. .trim 過濾用戶輸入的首尾空白字符

組件基礎

#組件

由於組件是可複用的 Vue 實例,因此它們與 new Vue 接收相同的選項,例如 data、computed、watch、methods 以及生命週期鉤子等。僅有的例外是像 el 這樣根實例特有的選項。

一個組件的 data 選項必須是一個函數,所以每一個實例能夠維護一份被返回對象的獨立的拷貝。不然,點擊某一個按鈕,會影響其餘實例。

data: function () {
  return {
    count: 0
  }
}

組件註冊分爲 全局註冊 和 局部註冊 兩種。
定義組件名的方式有兩種:kebab-case 和 PascalCase。
譬如:

Vue.component('my-component-name', { /* ... */ })
Vue.component('MyComponentName', { /* ... */ })

當使用 PascalCase (駝峯式命名) 定義一個組件時,你在引用這個自定義元素時兩種命名法均可以使用。也就是說 <my-component-name><MyComponentName> 都是可接受的。注意,儘管如此,直接在 DOM (即非字符串的模板) 中使用時只有 kebab-case 是有效的。

全局註冊,在註冊以後能夠用在任何新建立的 Vue 根實例 (new Vue) 的模板中,在子組件各自內部也均可以相互使用。

局部組件

全局註冊每每是不夠理想的。好比,若是你使用一個像 webpack 這樣的構建系統,全局註冊全部的組件意味着即使你已經再也不使用一個組件了,它仍然會被包含在你最終的構建結果中。這形成了用戶下載的 JavaScript 的無謂的增長。

對於 components 對象中的每一個屬性來講,其屬性名就是自定義元素的名字,其屬性值就是這個組件的選項對象。

局部註冊的組件在其子組件中不可用

// 傳統聲明組件方式
var ComponentA = { /* ... */ }

var ComponentB = {
  components: {
    'component-a': ComponentA
  },
  // ...
}

// 經過 Babel 和 webpack 使用 ES2015 模塊
import ComponentA from './ComponentA.vue'

export default {
  components: {
    ComponentA
  },
  // ...
}

使用 require.context 只全局註冊這些很是通用的基礎組件。

#prop

當你使用 DOM 中的模板時,camelCase (駝峯命名法) 的 prop 名須要使用其等價的 kebab-case (短橫線分隔命名) 命名。可是,重申一次,若是你使用字符串模板,那麼這個限制就不存在了。譬如:

Vue.component('blog-post', {
  // 在 JavaScript 中是 camelCase 的
  props: ['postTitle'],  // 也能夠是 json 對象格式
  template: '<h3>{{ postTitle }}</h3>'
})
<blog-post post-title="hello"></blog-post>

<!-- 動態賦予一個變量的值 -->
<blog-post v-bind:title="post.title"></blog-post>

<!-- 動態賦予一個複雜表達式的值 -->
<blog-post v-bind:title="post.title + ' by ' + post.author.name"></blog-post>

<!-- 即使 `42` 是靜態的,咱們仍然須要 `v-bind` 來告訴 Vue -->
<!-- 這是一個 JavaScript 表達式而不是一個字符串。-->
<blog-post v-bind:likes="42"></blog-post>

<!-- 包含該 prop 沒有值的狀況在內,都意味着 `true`。-->
<blog-post is-published></blog-post>

<!-- 即使 `false` 是靜態的,咱們仍然須要 `v-bind` 來告訴 Vue -->
<!-- 這是一個 JavaScript 表達式而不是一個字符串。-->
<blog-post v-bind:is-published="false"></blog-post>

即使 42 是靜態的,咱們仍然須要 v-bind 來告訴 Vue 這是一個 JavaScript 表達式而不是一個字符串。傳入數組,對象都是同樣的。詳情見官網

全部的 prop 都使得其父子 prop 之間造成了一個單向下行綁定:父級 prop 的更新會向下流動到子組件中,這樣能夠防止子組件意外改變父組件的狀態。不該該在一個子組件內部改變 prop。常見的兩種試圖改變 prop 情形:

  1. 這個 prop 用來傳遞一個初始值;這個子組件接下來但願將其做爲一個本地的 prop 數據來使用。這種狀況下,會定義一個data 屬性來存儲這個 prop 值。
props: ['initialCounter'],
data: function () {
  return {
    counter: this.initialCounter
  }
}
  1. _這個 prop 以一種原始的值傳入且須要進行轉換。_在這種狀況下,最好使用這個 prop 的值來定義一個計算屬性:
props: ['size'],
computed: {
  normalizedSize: function () {
    return this.size.trim().toLowerCase()
  }
}

注意在 JavaScript 中對象和數組是經過引用傳入的,因此對於一個數組或對象類型的 prop 來講,在子組件中改變這個對象或數組自己將會影響到父組件的狀態。

爲了定製 prop 的驗證方式,你能夠爲 props 中的值提供一個帶有驗證需求的對象,而不是一個字符串數組。譬如:

Vue.component('my-component', {
  props: {
    // 基礎的類型檢查 (`null` 匹配任何類型)
    propA: Number,
    // 多個可能的類型
    propB: [String, Number],
    // 必填的字符串
    propC: {
      type: String,
      required: true
    },
    // 帶有默認值的數字
    propD: {
      type: Number,
      default: 100
    },
    // 帶有默認值的對象
    propE: {
      type: Object,
      // 對象或數組且必定會從一個工廠函數返回默認值
      default: function () {
        return { message: 'hello' }
      }
    },
    // 自定義驗證函數
    propF: {
      validator: function (value) {
        // 這個值必須匹配下列字符串中的一個
        return ['success', 'warning', 'danger'].indexOf(value) !== -1
      }
    }
  }
})

注意那些 prop 會在一個組件實例建立以前進行驗證,因此實例的屬性 (如 data、computed 等) 在 default 或 validator 函數中是不可用的。

type 能夠是下列原生構造函數中的一個:

  • String
  • Number
  • Boolean
  • Array
  • Object
  • Date
  • Function
  • Symbol

額外的,type 還能夠是一個自定義的構造函數,而且經過 instanceof 來進行檢查確認。例如,給定下列現成的構造函數:

function Person (firstName, lastName) {
  this.firstName = firstName
  this.lastName = lastName
}

Vue.component('blog-post', {
    props: {
        author: Person
    }
})

來驗證 author prop 的值是不是經過 new Person 建立的。

#自定義事件

事件名不會被用做一個 JavaScript 變量名或屬性名,因此就沒有理由使用 camelCase 或 PascalCase 了。而且 v-on 事件監聽器在 DOM 模板中會被自動轉換爲全小寫 (由於 HTML 是大小寫不敏感的),因此 v-on:myEvent 將會變成 v-on:myevent——致使 myEvent 不可能被監聽到。

一個組件上的 v-model 默認會利用名爲 value 的 prop 和名爲 input 的事件,可是像單選框、複選框等類型的輸入控件可能會將 value 特性用於不一樣的目的。model 選項能夠用來避免這樣的衝突:

Vue.component('base-checkbox', {
  model: {
    prop: 'checked',
    event: 'change'
  },
  props: {
    checked: Boolean
  },
  template: `
    <input
      type="checkbox"
      v-bind:checked="checked"
      v-on:change="$emit('change', $event.target.checked)"
    >
  `
})
<base-checkbox v-model="lovingVue"></base-checkbox>

這裏的 lovingVue 的值將會傳入這個名爲 checked 的 prop。同時當 <base-checkbox> 觸發一個 change 事件並附帶一個新的值的時候,這個 lovingVue 的屬性將會被更新。

PS: 注意你仍然須要在組件的 props 選項裏聲明 checked 這個 prop。



羨慕和追逐強者,是男人生來融入血脈的天性。 一一 俗念親 《每次跳樓,都看見那廝在鋪救生氣墊》

天氣轉涼,請預防感冒!這不是廣告,是忠告。

相關文章
相關標籤/搜索