Vue組件參數傳遞問題


Vue組件參數傳遞問題

組件中的data為什么是函數?

組件中的數據是保存在哪里呢?頂層的Vue實例中嗎?並不是的,組件無法訪問Vue實例中的data。即使可以訪問,如果所有組件的數據都在頂級Vue實例中,那么Vue中的data會十分的臃腫。組件中的數據應該由自己管理。

組件是一個單獨功能模塊的封裝,這個模塊有屬於自己的HTML模板,也應該有屬於自己的數據data,不過這個data是一個函數。這是為什么呢?

這是為了保證組件復用時,屬性之間的隔離。利用方法都會重新開辟內存空間的機制。當創建多個相同組件實例時,不同組件實例之間的data必須保證不被共享

父子組件通訊之props(父->子)

需求1:在頁面中,父組件請求得到的數據需要在子組件中展示。

需求2:子組件很多,每次創建都要向后他發送數據,在父組件中進行請求,將數據傳遞給子組件展示。

Vue中提供了props用於父組件向子組件中傳遞數據

在子組件中,使用props聲明需要從父級接收到的數據

props的值有兩種方式:

  • 方式一:字符串數組,數組中的字符串就是傳遞時的屬性名稱。
  • 方式二:對象,對象可以設置傳遞時的類型,也可以設置默認值等。

數組形式的傳遞

1、在父組件中創建數據

  data() {
    return {
      userId: "rayfoo",
      name:'rayfoo',
      hobby: ['抽煙','喝酒','燙頭']
    };
  }

2、在子組件中創建props

props: ['name','hobby']

3、在子組件中使用屬性

<h2 v-text="name"></h2>

4、在父組件中導入並使用子組件

import News from "./views/home/news";


  components: {
    News
  }

    <News :name="name" />

對象形式的傳遞

對象參數的傳遞需要指定對象類數據類型、[默認值]、[是否必傳]等參數

支持的類型類型

  • String
  • Number
  • Boolean
  • Object
  • Data
  • Function
  • Symbol
props:{
        title:{
            //數據類型 參數可以指定多個[String,Number,...]
            type: String,
            //默認值,在沒有引入傳遞參數時渲染
            default: 'Message',
            //是否為必傳參數
            required: false
        },
   		 hobby:{
            type: Array,
            default: function(){
                return ['抽煙','喝酒']
            }
        }
    }

需要注意的時,當類型如果是Object或者Array,默認值必須是一個函數。

子組件向父組件傳遞數據

子組件中配置事件發送:

template:

<button @click="giveAdvice">我是一個小按鈕</button>

methods:

methods: {
        giveAdvice: function(){
            this.$emit('give-advice',this.title);
        }
    }

父組件中監聽

template:

<News :name="name" @give-advice="showAdvice" />

methods:

showAdvice: function (advice) {
      alert(advice)
    }

需要注意的是,事件如果傳遞的是駝峰式,需要使用下划線形式發射。具體的操作可以參考官方API

https://cn.vuejs.org/v2/api/#vm-emit

參數同步問題

如果父子間傳遞的參數需要實時的進行雙向綁定,該如何做?

如果修改了props中的值,父組件中的內容不會修改。Vue不推薦在子組件中直接修改props的值。

如果需要修改props中的值,可以在子組件中創建一個data或者computed副本

使用@input事件實現雙向綁定

子組件代碼:

1、在子組件中聲明props,由父組件傳遞。

2、創建props的副本,當props的副本

3、使用v-model綁定props副本的值

4、監聽控件的@input,當值發生改變,修改參數值,並且將值彈回父組件

<template>
    <div name='chidren'>
        <h1 v-text="title"></h1>
        <p v-text="info"></p>
        <input type="text" v-model="dparam" @input="valChange">
        <button @click="giao">發射屬性到父組件</button>
    </div>
</template>

<script>
export default {
    name: 'chidren',
    props: {
        title: String,
        info: String
    },
    data(){
        return{
            param: 'GIAO',
            dparam: this.title
        }
    },
    methods:{
        giao: function(){
            this.$emit('giao',this.param);
        },
        valChange: function(event){
            let newVal = event.target.value;
            this.param = newVal;
            this.$emit('title-change',newVal);
        }
    }/*,
    watch:{
        dparam(oldVal,newVal){
            this.param = newVal;
            this.$emit('title-change',newVal);
        }
    }*/
}
</script>

<style>

</style>

父組件代碼

父組件中可以直接使用v-model來修改子組件中屬性

<template>
    <div name="parent">
        <h1 v-text="title"></h1>
        <input type="text" v-model="title">
        <Childred @giao="giao" @title-change="titleChange" :title="title" :info="info"></Childred>
    </div>
</template>

<script>
import Childred from './Chidren';
export default {
    name: 'parent',
    data(){
        return {
            title: 'rayfoo',
            info: '真帥'
        }
    },
    methods:{
        giao: function(param){
            alert(param);
        },
        titleChange:function(newVal){
            this.title = newVal;
        }
    },
    components:{
        Childred
    }
}
</script>

<style>

</style>

如果數據類型不是String,可能要牽涉一些類型轉換問題。

使用watch進行子父組件雙向綁定

略。。。

父組件中取得子組件的對象

$children-不常用

上面的案例中我們已經成功的在父組件中取得子組件的屬性,也可以從子組件中拿到父組件的屬性,下面介紹一個更加簡單的操作形式-從父組件中拿到子組件對象。

在父組件中,可以使用:this.\(children[index].屬性名、this.\)children[index].方法名來獲取子組件內的屬性和方法,但是在開發過程中一般不會使用這樣的形式,因為其依賴下標,有很多的不確定性。

btnClick: function(){
            console.log(this.$children[0].param);
            this.$children[0].showInfo();
        }

$refs-常用

可以在引用子組件的位置給子組件指定一個ref屬性,例如ref='aaa'

此時,this.\(refs.aaa就是子組件對象,就可以在父組件中使用this.\)refs.aaa來訪問子組件啦~

btnClick: function(){
            console.log(this.$refs.child.param);
        }

子組件中訪問父組件對象

$parent不常用

在子組件中可以直接使用$parent來訪問父組件中的內容,但是在子組件中頻繁父組件中的內容,會使得組件的耦合度非常的高,所以開發過程中不常用。

        btnClick: function(){
            console.log(this.$parent.title);
        }

$root

使用$root可以獲取根組件中的內容

btnClick: function(){
            console.log(this.$root.title);
        }


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM