Vue表單和元件

weixin_34037977發表於2018-03-06

一、表單

  v-model 指令在表單控制元件元素上建立雙向資料繫結,v-model 會根據控制元件型別自動選取正確的方法來更新元素。

<input v-model="message" placeholder="編輯我……">
<p>訊息是: {{ message }}</p>

1、核取方塊

  核取方塊如果是一個為邏輯值,如果是多個則繫結到同一個陣列:

<div id="app">
  <p>單個核取方塊:</p>
  <input type="checkbox" id="checkbox" v-model="checked">
  <label for="checkbox">{{ checked }}</label>
    
  <p>多個核取方塊:</p>
  <input type="checkbox" id="runoob" value="Runoob" v-model="checkedNames">
  <label for="runoob">Runoob</label>
  <input type="checkbox" id="google" value="Google" v-model="checkedNames">
  <label for="google">Google</label>
  <input type="checkbox" id="taobao" value="Taobao" v-model="checkedNames">
  <label for="taobao">taobao</label>
  <br>
  <span>選擇的值為: {{ checkedNames }}</span>
</div>
 
<script>
new Vue({
  el: '#app',
  data: {
    checked : false,
    checkedNames: []
  }
})
</script>

2、單選按鈕

  單選按鈕的雙向資料繫結,就是選擇的按鈕的value

3、select 列表

  下拉選單的雙向資料繫結,就是選擇的選項的value

4、修飾符

(1).lazy

  在預設情況下, v-model 在 input 事件中同步輸入框的值與資料,但你可以新增一個修飾符 lazy ,從而轉變為在 change 事件中同步:

//在 "change" 而不是 "input" 事件中更新
<input v-model.lazy="msg" >

(2).number

  如果想自動將使用者的輸入值轉為 Number 型別(如果原值的轉換結果為 NaN 則返回原值),可以新增一個修飾符 number 給 v-model 來處理輸入值:

<input v-model.number="age" type="number">
//這通常很有用,因為在 type="number" 時 HTML 中輸入的值也總是會返回字串型別

(3).trim

  如果要自動過濾使用者輸入的首尾空格,可以新增 trim 修飾符到 v-model 上過濾輸入:

<input v-model.trim="msg">

  例項,全選與取消全選:

<script src="https://cdn.bootcss.com/vue/2.2.2/vue.min.js"></script>
<div id="app">
    <p>全選:</p>
    <input type="checkbox" id="checkbox" v-model="checked" @click="changeAllChecked()">
    <label for="checkbox">
        {{checked}}
    </label>
    <p>多個核取方塊:</p>
    <input type="checkbox" id="runoob" value="Runoob" v-model="checkedNames">
    <label for="runoob">
        Runoob
    </label>
    <input type="checkbox" id="google" value="Google" v-model="checkedNames">
    <label for="google">
        Google
    </label>
    <input type="checkbox" id="taobao" value="Taobao" v-model="checkedNames">
    <label for="taobao">
        taobao
    </label>
    <br>
    <span>
        選擇的值為:{{checkedNames}}
    </span>
</div>

new Vue({
    el: '#app',
    data: {
        checked: false,
        checkedNames: [],
        checkedArr: ["Runoob", "Taobao", "Google"]
    },
    methods: {
        changeAllChecked: function() {
            if (this.checked) {
                this.checkedNames = this.checkedArr
            } else {
                this.checkedNames = []
            }
        }
    },
    watch: {
        "checkedNames": function() {
            if (this.checkedNames.length == this.checkedArr.length) {
                this.checked = true
            } else {
                this.checked = false
            }
        }
    }
})

二、元件

  元件(Component)是 Vue.js 最強大的功能之一。元件可以擴充套件 HTML 元素,封裝可重用的程式碼。元件系統讓我們可以用獨立可複用的小元件來構建大型應用,幾乎任意型別的應用的介面都可以抽象為一個元件樹。

  註冊一個全域性元件語法格式如下:

Vue.component(tagName, options)

  tagName 為元件名,options 為配置選項。註冊後,我們可以使用以下方式來呼叫元件:

<tagName></tagName>

1、全域性元件

  所有例項都能用全域性元件。

//註冊一個簡單的全域性元件 runoob,並使用它:
<div id="app">
    <runoob></runoob>
</div>
 
<script>
// 註冊
Vue.component('runoob', {
  template: '<h1>自定義元件!</h1>'
})
// 建立根例項
new Vue({
  el: '#app'
})
</script>

2、區域性元件

  我們也可以在例項選項中註冊區域性元件,這樣元件只能在這個例項中使用:

//註冊一個簡單的區域性元件 runoob,並使用它:
<div id="app">
    <runoob></runoob>
</div>
 
<script>
var Child = {
  template: '<h1>自定義元件!</h1>'
}
 
// 建立根例項
new Vue({
  el: '#app',
  components: {
    // <runoob> 將只在父模板可用
    'runoob': Child
  }
})
</script>

3、Prop

  prop 是父元件用來傳遞資料的一個自定義屬性。

  父元件的資料需要通過 props 把資料傳給子元件,子元件需要顯式地用 props 選項宣告 "prop"

<div id="app">
    <child message="hello!"></child>
</div>
 
<script>
// 註冊
Vue.component('child', {
  // 宣告 props
  props: ['message'],
  // 同樣也可以在 vm 例項中像 "this.message" 這樣使用
  template: '<span>{{ message }}</span>'
})
// 建立根例項
new Vue({
  el: '#app'
})
</script>

4、動態 Prop

  類似於用 v-bind 繫結 HTML 特性到一個表示式,也可以用 v-bind 動態繫結 props 的值到父元件的資料中。每當父元件的資料變化時,該變化也會傳導給子元件

<div id="app">
    <div>
      <input v-model="parentMsg">
      <br>
      <child v-bind:message="parentMsg"></child>
    </div>
</div>
 
<script>
// 註冊
Vue.component('child', {
  // 宣告 props
  props: ['message'],
  // 同樣也可以在 vm 例項中像 "this.message" 這樣使用
  template: '<span>{{ message }}</span>'
})
// 建立根例項
new Vue({
  el: '#app',
  data: {
    parentMsg: '父元件內容'
  }
})
</script>

  將 v-bind 指令將 todo 傳到每一個重複的元件中:

<div id="app">
    <ol>
    <todo-item v-for="item in sites" v-bind:todo="item"></todo-item>
    </ol>
</div>
 
<script>
Vue.component('todo-item', {
  props: ['todo'],
  template: '<li>{{ todo.text }}</li>'
})
new Vue({
  el: '#app',
  data: {
    sites: [
      { text: 'Runoob' },
      { text: 'Google' },
      { text: 'Taobao' }
    ]
  }
})
</script>

  注意:prop 是單向繫結的:當父元件的屬性變化時,將傳導給子元件,但是不會反過來。

5、Prop 驗證

  元件可以為 props 指定驗證要求。prop 是一個物件而不是字串陣列時,它包含驗證要求:

Vue.component('example', {
  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 value > 10
      }
    }
  }
})

  type 可以是下面原生構造器:String、Number、Boolean、Function、Object、Array;

  type 也可以是一個自定義構造器,使用 instanceof 檢測。

6、自定義事件

  父元件是使用 props 傳遞資料給子元件,但如果子元件要把資料傳遞回去,就需要使用自定義事件!我們可以使用 v-on 繫結自定義事件,每個 Vue 例項都實現了事件介面(Events interface),即:

  (1)使用 $on(eventName) 監聽事件

  (2)使用 $emit(eventName) 觸發事件

  另外,父元件可以在使用子元件的地方直接用 v-on 來監聽子元件觸發的事件

  以下例項中子元件已經和它外部完全解耦了。它所做的只是觸發一個父元件關心的內部事件。

<div id="app">
    <div id="counter-event-example">
      <p>{{ total }}</p>
      <button-counter v-on:increment="incrementTotal"></button-counter>
      <button-counter v-on:increment="incrementTotal"></button-counter>
    </div>
</div>
 
<script>
Vue.component('button-counter', {
  template: '<button v-on:click="incrementHandler">{{ counter }}</button>',
  data: function () {
    return {
      counter: 0
    }
  },
  methods: {
    incrementHandler: function () {
      this.counter += 1
      this.$emit('increment')//觸發事件,父元件用v-on:increment監聽子元件觸發的事件
    }
  },
})
new Vue({
  el: '#counter-event-example',
  data: {
    total: 0
  },
  methods: {
    incrementTotal: function () {
      this.total += 1
    }
  }
})
</script>

  如果你想在某個元件的根元素上監聽一個原生事件。可以使用 .native 修飾 v-on 。例如:

<my-component v-on:click.native="doTheThing"></my-component>

 

相關文章