父子之間組件傳值及評論案例

父子之間組件傳值

父組件向子組件傳值

父組件向子組件傳data中的值

在這裏插入圖片描述
首先,我們知道子組件默認是無法訪問父組件中的data上的數據和methods中的方法,其次,如果我們想要子組件取到父組件中data中的msg值,該怎麼辦呢?
先區分父組件中的data和子組件中data
子組件中的data數據,並不是通過父組件傳遞過來的,而是子組件自身私有的,比如:子組件通過ajax請求回來的數據,都可以放在data身上,注意:子組件的data必須是個方法,有返回值

var vm = new Vue({
    el:'#app',
    data:{
        msg: '123 啊-父組件中的數據'
    },
    methods:{},
    components: {
        com1: {
            data(){ 
                return {
                    title: '123',
                    content: 'qqq'
                }
            },
            template: '<h1>這是子組件 --- {{ parentmsg }}</h1>',
        }
    }
});

父組件向子組件傳值:
通過屬性綁定(v-bind)的方式,把需要傳遞給子組件的數據,以屬性綁定的形式,傳遞到子組件內部,供子組件使用;然後在子組件中的props數組中定義從父組件傳遞過來的屬性。
注意:子組件中的data上的數據,是可讀可寫的,props中的數據都是隻讀的,是無法重新賦值的

<body>
    <div id="app">
        <com1 v-bind:parentmsg="msg"></com1>
    </div>
    <script>
        var vm = new Vue({
            el:'#app',
            data:{
                msg: '123 啊-父組件中的數據'
            },
            methods:{},
            components: {
                com1: {
                    data(){  
                        return {
                            title: '123',
                            content: 'qqq'
                        }
                    },
                    template: '<h1>這是子組件 --- {{ parentmsg }}</h1>',
                    props: ['parentmsg'],  
                }
            }
        });
    </script>
</body>

父組件向子組件傳遞方法

父組件向子組件傳遞方法,使用的是事件綁定機制:v-on (<com2 v-on:func=“show”>)
當我們自定義了一個事件屬性之後,子組件就能通過某些方式(this.$emit(‘func’,this.sonmsg),看父組件的方法是否有參數),來調用傳遞進去的這個方法

<body>
    <div id="app">
        <com2 v-on:func="show"></com2>
    </div>

    <template id="tmp1">
        <div>
            <h1>這是子組件</h1>
            <input type="button" value="這是子組件中的按鈕- 點擊它,觸發父組件傳遞過來的func方法" @click="myclick">
        </div>
    </template>

    <script>
        var com2 = {
            template : '#tmp1',
            data(){
                return {
                    sonmsg: {name:'小頭兒子', age:6}
                }
            },
            methods: {
                myclick(){
                    //當點擊子組件按鈕時,如何拿到父組件傳遞過來的func方法,並調用這個方法
                    // emit英文意思:觸發,調用意思
                    this.$emit('func',this.sonmsg)
                }
            }
        }

        var vm = new Vue({
            el:'#app',
            data:{
                datamsgFormSon: null
            },
            methods:{
                show(data){
                    // console.log(data)
                    this.datamsgFormSon = data
                }
            },
            components: {
                com2
            }
        });
    </script>
</body>

實例:評論列表

分析:發表評論的業務邏輯
1.評論數據存到哪裏去? 存放到本地localStorage中localStorage.setItem(‘cmts’,’’)
2.先組織一個最新的評論數據對象
3.想辦法,把第二步得到的評論對象,保存到localStorage中
3.1 localStorage只支持存放字符串數據,要先序列化成一個對象,調用JSON.stringify
3.2 在保存最新的評論數據之前,要先從localStorage獲取到之前的評論數據(string),轉換爲一個數組對象, 然後把最新的評論push到這個數組
3.3 如果獲取到的localStorage中的評論字符串,爲空不存在,則可以返回一個‘[]’讓JSON.parse去轉換
3.4 把最新的評論列表數組,再次調用JSON.stringify轉化爲數組字符串,然後調用localStorage.setItem()
知識點:在點擊發表評論時,希望能夠自動刷新列表從localStorage中獲得最新列表。而該方法爲localComments(),是父組件的方法,子組件是如何調用父組件的方法的。
知識點:JSON.parse() 從一個字符串解析出JSON對象;JSON.stringify()從一個對象中解析出字符串。
知識點:localStorage爲本地存儲,只存儲字符串類型的對象,如果想要轉成JSON對象類型就需要用到上一個知識點。

<body>
    <div id="app">
        <cmt-box @func="localComments"></cmt-box>
        
        <ul class="list-group">
            <li class="list-group-item" v-for="item in list" :key="item.id">
                <span class="badge">評論人:{{ item.user }}</span>
                {{ item.content }}
            </li>
        </ul>
        

    </div>

    <template id="tmp1">
        <div>
            <div class="form-group">
                <label>評論人:</label>
                <input type="text" class="form-control" v-model='user'>
            </div>
            <div class="form-group">
                <label>評論內容:</label>
                <textarea class="form-control" v-model='content'></textarea>
            </div>
            <div class="form-group">
                <input type="button" value="發表評論" class="btn btn-primary" @click="postComment">
            </div>
        </div>

    </template>

    <script>
        var commentBox = {
            data(){
                return {
                    user: '',
                    content: ''
                }
            },
            template: '#tmp1',
            methods: {
                postComment(){            
                    var comment = {id: Date.now(), user: this.user, content: this.content}                  
                    // 從localStorage中獲取所有的評論
                    var list = JSON.parse(localStorage.getItem('cmts') || '[]')
                    list.unshift(comment)
                    // 重新保存最新的評論數據
                    localStorage.setItem('cmts',JSON.stringify(list))
                    this.user = this.content = ''
                    this.$emit('func')
                    
                }
            }
        }

        var vm = new Vue({
            el:'#app',
            data:{
                list:[
                    {id: Date.now(), user:'李白', content:'天生我材必有用'},
                    {id: Date.now(), user:'江小白', content:'勸君更進一杯酒'},
                    {id: Date.now(), user:'小馬', content:'我姓馬,風吹草低見牛羊的馬'}
                ]
            },
            created(){
                this.localComments()
            },
            methods:{
                localComments(){  // 從本地localStorage中加載評論列表
                    var list = JSON.parse(localStorage.getItem('cmts') || '[]')
                    this.list = list
                }
            },
            components:{
                'cmt-box': commentBox
            }
        });
    </script>
</body>

子組件向父組件傳值

使用this.$refs來獲取元素和組件。
首先,瞭解ref的功能,通過ref就能不操作DOM元素獲取到h3的值,可以從控制檯看到有$refs對象,給h3加上ref=myh3,就能看到$refs中有對象,鍵爲myh3,值爲DOM元素,在方法中,通過this.$refs.myh3.innerText就可以獲取到該元素

<body>
    <div id="app">
        <input type="button" value="獲取元素" @click="getElement">
        <h3 ref="myh3">哈哈哈,今天天氣太好了!!!</h3>
    </div>
    <script>
        var vm = new Vue({
            el:'#app',
            data:{},
            methods:{
                getElement(){
                    console.log(this.$refs.myh3.innerText)
                }
            },
        });
    </script>
</body>

在父組件中通過** this.$refs.mylogin.show()**就可調用子組件的show方法,此時控制檯的$refs中的mylogin對應的值就是子組件

<body>
    <div id="app">
        <input type="button" value="獲取元素" @click="getElement">
        <h3 ref="myh3">哈哈哈,今天天氣太好了!!!</h3>
    <hr>
    <login ref="mylogin"></login>
    </div>
    <script>
        var login={
            template: '<h1>登錄組件</h1>',
            data(){
                return {
                    msg: 'son msg'
                }
            },
            methods: {
                show(){
                    console.log('調用了子組件的方法')
                }
            }
        }
        var vm = new Vue({
            el:'#app',
            data:{},
            methods:{
                getElement(){
                    this.$refs.mylogin.show()
                }
            },
            components:{
                login
            }
        });
    </script>
</body>
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章