數據綁定 / 組件通訊

  • 當前函數運行形成傳遞的數據改變的執行順序:一、執行完當前函數(這個時候調用子組件中的方法拿到的值依然是舊的,由於還未傳遞到子組件中)。 二、傳遞數據到子組件中。三、執行頁面更新
// 父組件
<my-components :commonData='commonData' @changeCommonData='changeCommonData'></my-components>
changeCommonData(data){
    this.commonData = data
}

// my-components子組件中
doSome(){
    this.$emit('changeCommonData',data) // data === 2,這時父組件中的commonData已經更改成2,可是子組件的響應,要等待當前函數執行完後響應
    console.log(this.commonData) // 原始值是1,
}

—————————————————————————————————————————————————————————

組件內

props

  • 使用some-propssomeProps的命名方式,外部均可以經過some-propssomeProps賦值,在內部只能經過this.someProps得到
    • 內部使用駝峯式命名
    • 外部視使用狀況是否使用駝峯式
  • 不能使用this
  • .sync對一個 prop 進行「雙向綁定」。
<text-document v-bind:title.sync="doc.title"></text-document>
// 實際爲
<text-document
  v-bind:title="doc.title"
  v-on:update:title="doc.title = $event" 
></text-document>

...
watch:{
    title(newTitle){
        this.$emit('update:title', newTitle) 
    }
}
...
  • 能夠傳入一個未定義的prop,會自動添加到的根元素上(不必定會添加到根元素上,組件能夠經過設置inheritAttrs來禁止綁定,同時還能夠經過$attrs來獲取綁定到組件上的屬性)。對於絕大多數特性來講,從外部提供給組件的值會替換掉組件內部設置好的值。因此若是傳入 type="text" 就會替換掉 type="date" 並把它破壞!慶幸的是,class 和 style 特性會稍微智能一些,即兩邊的值會被合併起來,從而獲得最終的值
  • 驗證,props 會在一個組件實例建立以前進行驗證,因此實例的屬性 (如 data、computed 等) 在 default(默認值,當是數組或對象時須要函數返回) 或 validator 函數(傳入值校驗)中是不可用的。
props: {
    propA:{
        type: Number,
        default: 100, // 對象或數組默認值必須從一個工廠函數獲取
        required: true, // 必傳
        validator: function (value) { // 自定義驗證函數
            // 這個值必須匹配下列字符串中的一個
            return ['success', 'warning', 'danger'].indexOf(value) !== -1
        }
    }
}
  • type能夠是下列原生構造函數中的一個String、Number、Boolean、Array、Object、Date、Function、Symbol,還能夠是一個自定義的構造函數,而且經過 instanceof 來進行檢查確認。prop 的值是不是經過 new Person 建立的。
function Person (firstName, lastName) {
  this.firstName = firstName
  this.lastName = lastName
}

Vue.component('blog-post', {
  props: {
    author: Person
  }
})
// 類同於
propA: Number

inheritAttrs

  • 能夠傳入一個未定義的prop,會自動添加到的根元素上(不必定會添加到根元素上,組件能夠經過設置inheritAttrs來禁止綁定,同時還能夠經過$attrs來獲取綁定到組件上的屬性)。對於絕大多數特性來講,從外部提供給組件的值會替換掉組件內部設置好的值。因此若是傳入 type="text" 就會替換掉 type="date" 並把它破壞!慶幸的是,class 和 style 特性會稍微智能一些,即兩邊的值會被合併起來,從而獲得最終的值
  • 若是你不但願組件的根元素繼承特性,你能夠設置在組件的選項中設置
Vue.component('my-component', {
  inheritAttrs: false,
  // ...
})

—————————————————————————————————————————————————————————

組件外

v-bind

  • 當在一個自定義組件上使用 class 屬性時,這些類將被添加到該組件的根元素上面。這個元素上已經存在的類不會被覆蓋。
  • 當綁定爲布爾值flase時,該特性不會綁定給元素
  • 當 v-bind:style 使用須要添加瀏覽器引擎前綴的 CSS 屬性時,如 transform,Vue.js 會自動偵測並添加相應的前綴。因此儘可能使用(須要browserslist目標瀏覽器支持嗎?)
  • 從 2.3.0 起你能夠爲 style 綁定中的屬性提供一個包含多個值的數組,這樣寫只會渲染數組中最後一個被瀏覽器支持的值。(須要browserslist目標瀏覽器支持嗎?)
<div :style="{ display: ['-webkit-box', '-ms-flexbox', 'flex'] }"></div>
  • 若是你想要將一個對象的全部屬性都做爲 prop 傳入,你可使用不帶參數的 v-bind (取代 v-bind:prop-name)。可是不容許綁定字面量對象,例如v-bind=」{ title: doc.title }」沒法正常工做
<blog-post v-bind="post"></blog-post>
// 等價於
<blog-post
  v-bind:id="post.id"
  v-bind:title="post.title"
></blog-post>

v-model

  • 在inpu中,可使用修飾符.lazy(使用 change 事件進行輸入數據同步).number(自動將用戶的輸入值轉爲數值類型,原生中即便在 type="number" 時,HTML 輸入元素的值也總會返回字符串).trim(自動過濾用戶輸入的首尾空白字符)
  • 對於須要使用輸入法 (如中文、日文、韓文等) 的語言,你會發現 v-model 不會在輸入法組合文字過程當中獲得更新。若是你也想處理這個過程,請使用 input 事件。當用輸入法時可以捕獲輸入的每一個拼音字母vue

  • 下拉菜單選項的value能夠綁定爲任意內存對象,不必定要是字符串。只要傳入相同鍵值的對象就可以選中下拉項(測試來源於餓了嗎組件)
  • select下拉菜單,單選爲文本,多選爲文本數組(option有value時優先綁定)。若是 v-model 表達式的初始值未能匹配任何選項,<select> 元素將被渲染爲「未選中」狀態。在 iOS 中,這會使用戶沒法選擇第一個選項。由於這樣的狀況下,iOS 不會觸發 change 事件。所以,更推薦提供一個值爲空的禁用選項。
<div id="example-5">
  <select v-model="selected"> // selected 默認爲''
    <option disabled value="">請選擇</option>
    <option>A</option>
    <option>B</option>
    <option>C</option>
  </select>
  <span>Selected: {{ selected }}</span>
</div>
  • 單選按鈕綁定value值
<input type="radio" id="huey" name="drone" value="huey" checked>    // checked初始被選中
  • 複選框能夠單獨設置選中和未選中時的值
<input
  type="checkbox"
  v-model="toggle"
  true-value="yes"
  false-value="no"
>
  • 單個複選框,綁定到布爾值:<input type="checkbox" id="checkbox" v-model="checked">選中時checked爲true,不然爲false。不須要value
  • 多個複選框,綁定到同一個數組:
<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>
</div>

new Vue({
  el: '#example-3',
  data: {
    checkedNames: []    //=>['Jack','John']
  }
})
  • 在組件中使用v-model
// input中
<input v-model="searchText">
// 等價於
<input
  v-bind:value="searchText"
  v-on:input="searchText = $event.target.value"    // 這裏的$event是事件對象
>


// 組件中
// 組件外部使用
<custom-input v-model="searchText"></custom-input>
// 等價於
<custom-input
  v-bind:value="searchText"
  v-on:input="searchText = $event"
></custom-input>

// 組件內部定義
Vue.component('custom-input', {
  props: ['value'],
  template: `
    <input
      v-bind:value="value"
      v-on:input="$emit('input', $event.target.value)" // $event.target指向時間對象,input對象有value屬性
    >
  `
})
  • 一個組件上的 v-model 默認會利用名爲 value 的 prop 和名爲 input 的事件
Vue.component('base-checkbox', {
  model: {
    prop: 'checked',
    event: 'change'
  },

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

—————————————————————————————————————————————————————————

插槽通信

slot和slot-scope

  • 做用域插槽(從子組件傳數據給父組件處理)
// 組件
<ul>
  <li
    v-for="todo in todos"
    v-bind:key="todo.id"
  >
    <!-- 咱們爲每一個 todo 準備了一個插槽,-->
    <!-- 將 `todo` 對象做爲一個插槽的 prop 傳入。-->
    <slot v-bind:todo="todo">
      <!-- 回退的內容 -->
      {{ todo.text }}
    </slot>
  </li>
</ul>

// 使用(獲取組件中傳出的數據)
<todo-list v-bind:todos="todos">
  <!-- 將 `slotProps` 定義爲插槽做用域的名字 -->
  <template slot-scope="slotProps"> // 這裏可使用解構語法{ todo }
    <!-- 爲待辦項自定義一個模板,-->
    <!-- 經過 `slotProps` 定製每一個待辦項。-->
    <span v-if="slotProps.todo.isComplete">✓</span>
    {{ slotProps.todo.text }}
  </template>
</todo-list>
  • 普通slot(非做用域插槽)能夠傳入多個子元素

<template>

  • v-show 不支持 <template> 元素。若是須要很是頻繁地切換,則使用 v-show 較好;

—————————————————————————————————————————————————————————

後代組件通信

provide / inject

  • provide 選項容許咱們指定咱們想要提供給後代組件的數據/方法。當多個子/孫組件須要調用同一個父組件的方法時使用。而後在任何後代組件裏,咱們均可以使用 inject 選項來接收指定的咱們想要添加在這個實例上的屬性(provide 和 inject 綁定並非可響應的。這是刻意爲之的。然而,若是你傳入了一個可監聽的對象,那麼其對象的屬性仍是可響應的。在 Vue 2.2.1以前inject中的值在prop和data以後初始化)
// 父級組件提供 'foo'
var Provider = {
  provide: { // provide 選項應該是一個對象或返回一個對象的函數。
    foo: 'bar'
  },
  // ...
}

// 子組件注入 'foo'
var Child = {
  inject: ['foo'], 
  created () {
    console.log(this.foo) // => "bar"
  }
  // ...
}
// inject 選項應該是數組或對象(該對象的 key 是本地的綁定名,value 是搜索用的 key 或一個包含from和default屬性的對象。(對象的from 屬性是在可用的注入內容中搜索用的 key 、default 屬性是降級狀況下使用的 value))
inject:{
    myFoo1:'foo',
    myFoo:{
        from:'foo',
        default:'boy' // 與 prop 的默認值相似,你須要對非原始值(數組、對象)使用一個工廠方法
    }
}

bus只是一種解決方案並非vue提供的官方示例

  • 局部bus
// 組件1
import Bus from './Bus'

export default {
    data() {
        return {
            .........
            }
      },
  methods: {
        ....
        Bus.$emit('log', 120)
    },

  } 

// 組件2
import Bus from './Bus'

export default {
    data() {
        return {
            .........
            }
      },
    mounted () {
       Bus.$on('log', content => { 
          console.log(content)
        });    
    }    
}
  • 全局bus
import Vue from 'vue'
const Bus = new Vue()

var app= new Vue({
    el:'#app',
   data:{
    Bus
    }  

})
相關文章
相關標籤/搜索