Vue父子組件通訊的三兩事(prop、emit)

組件是Vue核心功能之一,合理的組件化,能夠減小咱們代碼的冗餘,提升項目的可維護性。下面,我將由淺入深的講Vue的組件
在講以前,首先咱們先了解一下組件的命名。
HTML是對特徵名不敏感的語言,他會將全部的字符所有轉換成小寫。咱們命名了一個組件的名稱爲 nameTest ,而後再其餘組件裏面引用 <nameTest> </nameTest> ,那麼咱們將找不到這個組件,由於這個組件一已經將名字轉換爲nametesthtml

props : 父組件子組件 傳參

基本使用

Parent.vuevue

<template>
<div>
    parent:下面是個人子組件
    <childSon :userName='name'></childSon>
</div>
</template>
<script>
import childSon from './Childs'
export default {
    name:'Parent',
    components:{
        childSon
    },
    data(){
        return{ 
            name:'啊哈'
        }
    }
}
</script>

Childs.vue數組

<template>
<div>
    child:這是父組件給我傳的數據——{{userName}}
</div>
</template>
<script>
export default {
    name:'Childs',
    props:['userName'],
    data(){
        return{

        }
    }
}
</script>

props1

咱們在 Parent.vue 組件裏面引用子組件 Childs.vue 而後傳入 userName 參數給子組件,Childs 在props裏面接收父組件傳傳來的數據。ide

上面的例子咱們傳入的是一個字符串,其實,props能夠傳入StringNumberObjectBoolenArray等數據類型。那麼咱們在接受參數的時候就會有一個問題,咱們怎麼知道接收的應該是字符串'12'仍是數字12呢?
因此 Vue有一個 Prop驗證 的功能。組件化

Prop 驗證

子組件在接受數據的時候,能夠指定接收具體類型的數據、是否不能爲空,是否有默認值等。 ui

Parent.vuethis

<template>
<div>
    parent:下面是個人子組件
    <childSon :name='name' :firstName='firstName' :age='18' ></childSon>
</div>
</template>
<script>
import childSon from './Childs'
export default {
    name:'Parent',
    components:{
        childSon
    },
    data(){
        return{ 
            name:'大衛',
            firstName:'大華'
        }
    }
}
</script>

Child.vuespa

<template>
<div>
     child:這是父組件給我傳的數據——name:{{name}}——firstName:{{firstName}}——lastName:{{lastName}}——age:{{age}}
</template>
<script>
export default {
    name:'Childs',
    props:{
        name: String,
        firstName: {
            type: String,//規定值的類型
            required: true //必須傳值,不然報錯
        },
        lastName: {
            type: String,
            default: 'lastNameDefault' //若是不傳值,則爲default的值
        },
        age: {
            type: [String,Number], //類型能夠是多種
            validator: function(value) { //自定義驗證

                let num = parseInt(value)
                if (num > 0 && num <100) {
                    return true;
                } else {
                    return false;
                }
            }
        }
    },
    data(){
        return{

        }
    }
}
</script>

運行結果以下圖:
prop驗證3d

若是咱們將條件改變的時候,name 傳入一個數組,firstName 不傳值,age 傳入一個不能轉換爲數字的值。雙向綁定

<childSon :name=[11]  age='ss' ></childSon>

運行結果以下圖:
驗證1
驗證2
驗證3
驗證4
根據咱們的驗證規則,name 必須爲一個String 類型,因此控制檯報錯:但願獲得一個String,獲得了一個數組;firstName 爲一個必填的值,可是咱們沒有傳值,因此報錯;age要爲一個能夠轉換成數字的值,可是咱們穿了"ss",會通過咱們自定義的驗證,而後拋錯。

Prop傳入對象

若是咱們要將一個 對象 的全部屬性所有傳給子組件,咱們不須要將屬性一個個的做爲Prop傳遞,只須要將整個對象傳遞過去就能夠。

Parent.vue

template>
<div>
    parent:下面是個人子組件
    <childSon v-bind='obj' ></childSon>
</div>
</template>
<script>
import childSon from './Childs'
export default {
    name:'Parent',
    components:{
        childSon
    },
    data(){
        return{ 
            obj: {
                name: 'lily',
                age: '16'
            }
        }
    }
}
</script>

Childs.vue

<template>
<div>
    child:這是父組件給我傳的數據——name:{{name}}——age:{{age}}
</div>
</template>
<script>
export default {    
    name:'Childs',
    props:{
        name: String,
        age: {
            type: [String,Number], //類型能夠是多種
            validator: function(value) { //自定義驗證

                let num = parseInt(value)
                if (num > 0 && num <100) {
                    return true;
                } else {
                    return false;
                }
            }
        }
    }
}
</script>

運行結果以下圖:
object
咱們傳入一個 obj 對象,而後在子組件裏面能夠拿到對象的全部屬性。

Prop的單向數據傳遞

直接做爲一個本地變量

Parent.vue

<template>
<div>
    parent:<input type='text' v-model="content">下面是個人子組件 
    <childSon :content='content' ></childSon>
</div>
</template>
<script>
import childSon from './Childs'
export default {
    name:'Parent',
    components:{
        childSon
    },
   data() {
    return {
      content:'er'
    };
  },
}
</script>

Childs.vue

<template>
<div>
    child:這是父組件給我傳的數據——{{con}}
</div>
</template>
<script>
export default {    
    name:'Childs',
    props:['content'],
    data(){
        return{
           con:this.content
        }
    }
}
</script>

運行結果以下圖:
prop

emit :子組件父組件 傳遞數據

基本使用

子組件父組件傳遞數據,不能像上面同樣實時的傳遞數據,必須經過 事件 觸發。咱們經過 $emit 方法來向父子間傳遞數據,第一個參數爲事件的 名稱 ,第二個爲傳遞的 數據 ,是一個可選的參數。父組件必須監聽一樣的事件名稱才能監聽到咱們的這個事件,事件拋出的值必須經過 $event或者經過一個方法來訪問。

**Parent.vue

<template>
<div>
    parent:這是個人子組件傳給個人值:{{num}}
    <childSon :content='content' @getNum='getMsg'></childSon>
</div>
</template>
<script>
import childSon from './Childs'
export default {
    name:'Parent',
    components:{
        childSon
    },
   data() {
    return {
      content:'er',
      num:''
    }
  },
  methods:  {
      getMsg(num){
          this.num = num;
      }
  }
}
</script

Childs.vue

<template>
<div>
    child:這是父組件給我傳的數據——{{content}} <br />
    <button @click="sendMsgtoParent">點擊我能夠向父子間傳遞參數哦</button>
</div>
</template>
<script>
export default {    
    name:'Childs',
    props:['content'],
    data(){
        return{
            num: 0
        }
    },
    methods: {
        sendMsgtoParent(){
            this.$emit('getNum',this.num ++ );
        }
    }
}
</script>

運行結果以下圖:
emit基礎用法
子組件定義了一個num變量,而後點擊按鈕觸發method,經過 $emit向父組件發送事件的名稱(getNum)和一個參數(this.num),而後 父組件 監聽事件getNum,而後將傳遞值賦值給父組件的一個屬性上,這樣就能夠是實現子組件點擊一次按鈕,就向父組件發送一次數據。更多實例能夠參考官網

組件間的數據雙向綁定

咱們知道咱們可使用v-model來實現數據的雙向綁定。可是若是這個數據是跨組件的話,咱們要怎樣實現綁定嗎?

首先咱們先要明白v-model的原理。v-model實際上是分爲兩個方面,一方面數據層的改變引發視圖層的變化,咱們可使用v-bind來實現,另外一方面視圖層的變化引發數據層的變化咱們能夠監聽事件來實現。因此咱們想要雙向綁定一個數據,只須要這兩步操做。具體實現參考官網

彈框嵌套表格組件化使用

(待續...)

相關文章
相關標籤/搜索