鍍金池/ 問(wèn)答/HTML/ vue 父組件如何實(shí)時(shí)監(jiān)聽(tīng)子組件數(shù)據(jù)變化

vue 父組件如何實(shí)時(shí)監(jiān)聽(tīng)子組件數(shù)據(jù)變化

vue 父組件如何實(shí)時(shí)監(jiān)聽(tīng)子組件data數(shù)據(jù)變化 然后進(jìn)行業(yè)務(wù)邏輯處理。

父組件代碼:

<template lang = "pug">

    #debugger

        .debugger-1
            //- 請(qǐng)求
            .debugger_body_request

                .debugger_body_request_host

                    input(autocomplete = "off", placeholder = "服務(wù)器未配置",readonly = "readonly","type" = "text", value = "http://localhost")

                .debugger_body_request_method_url

                    .debugger_body_request_method(@mouseleave = "isShowRequestMethod = false", style = "display: -webkit-inline-box;")

                        button.btn(@click = "isShowRequestMethod = !isShowRequestMethod")

                            strong {{ currentRequestMethod }}

                            i.iconfont.icon-xia1(style = "font-size:13px;")

                        .prohibition_of_replication(v-show = "isShowRequestMethod")

                            ul.xiahua

                                li(v-for = "method in requestMethod", @click = "selectiveRequestMethod(method)") {{ method }}

                        .debugger_body_request_url

                            input(v-model = "requestUrl" type = "text", name = "requestUrl", placeholder = "http://", autocomplete = "off")

                .debugger_body_reset_params.prohibition_of_replication

                    a(href="#") 重置為文檔參數(shù)

                .debugger_body_params

                    .tabcontrol.prohibition_of_replication

                        .abcontrol-1(v-if = "tab")

                            div(v-for="tab, index in tab", @click = "showView(tab.view, index)", :class = "{tab: true, updateStyle: index == viewIndex}") {{ tab.name }}

                                div(v-if = "tab.options", @mouseleave = "isShowParamsFormat = false", style = "display:inline-block")

                                    i.iconfont.icon-xia1(@click.stop = "isShowParamsFormat =!isShowParamsFormat", style = "vertical-align: middle")

                                    ul.xiahua(v-show = "isShowParamsFormat", style = "widthd:82px")

                                        li(v-for = "option,optionIndex in tab.options" @click.stop = "selectiveParamsFormat(option.name, option.view, index)") {{ option.name }}

                    keep-alive
                        component(:is = "view", :type = "type", @cacheParams = "cacheParams")

                .el_button

                    button.request_test(type = "button") 請(qǐng)求測(cè)試

                    div(style = "float: left;width:60%")

                        button.saveArchive(type = "button") 生成文檔

        //- 響應(yīng)
        .debugger_response(style = "width:40%")

            .debugger_response_statusCode

                ul

                    li
                        span Status:

                        span(style = "color:red") 200

                    li

                        span Time: 7ms

                    li
                        span Size: 123kb


</template>


<script>
import formView from './form';
import queryView from './query';
import jsonView from './json';
import xmlView from './xml';
import headerView from './header';

export default {
    components: {
        formView,
        jsonView,
        queryView,
        xmlView,
        headerView,
    },
    data()
    {
        return {
            view: "formView",
            viewIndex: 0,
            type: 'Form',
            //接口地址
            requestUrl: '',
            isShowRequestMethod: false,
            isShowParamsFormat: false,
            requestMethod: [
                'GET',
                'POST',
                'PUT',
                'DELETE',
                'OPTIONS'
            ],
            currentRequestMethod: 'GET',
            tab: [{
                "name": "Form",
                "view": "formView",
                "options": [{
                    "name": "Form",
                    "view": "formView"
                },{
                    "name": "JSON",
                    "view": "jsonView",
                }, {
                    "name": "XML",
                    "view": "xmlView"
                }]

            }, {
                "name": "Query",
                "view": "queryView",

            }, {
                "name": "Header",
                "view": "headerView",
            }],

            params: []
        }
    },
    methods: {
        selectiveRequestMethod(method)
        {
            this.currentRequestMethod = method;

            this.isShowRequestMethod  = !this.isShowRequestMethod;
        },

        /**
         * 二級(jí)選項(xiàng)卡處理
         *
         * @param string name 展示的內(nèi)容
         * @param string view 要顯示的視圖
         * @index intger index 父級(jí)選項(xiàng)卡的索引
         */
        selectiveParamsFormat(name, view, index)
        {
            this.type               = name;

            this.tab[index].name    = name;

            this.tab[index].view    = view;

            this.showView(view, index);

            this.isShowParamsFormat = !this.isShowParamsFormat;

        },
        showView(view, index)
        {
            this.viewIndex       = index;

            this.view            = view;
        },
        cacheParams(data)
        {
            console.log(data);
        }
    }
}
</script>

子組件代碼:

<template lang = "pug">

    #form

        .form_form

            table(v-if = "data")

                tr(v-for = "val, index in data")

                    td(style="width:7%")

                        label

                            input.check.form_input(:checked = "val.is", @click = "data[index].is = !data[index].is", type = "checkbox")
                    td

                        div

                            input.params_key.form_input.input-placeholder(v-model = "val.key", placeholder = "key")

                    td
                        div

                            input.form_input(v-model = "val.value", @keyup.enter = "", placeholder = "value")
                    td

                        i.iconfont.icon-shanchu.debugger_icon(@click = "deleteParams(index)")

        button.form_button(@click = "addParams()", type = "button")

            i.iconfont.icon-iconjia(style="font-weight:400, font-size:15px")

            span 添加參數(shù)

</template>

<script>
export default {
    data()
    {
        return {
            data: [],
            //QUERY_STRING Params
            params: '?'

        }
    },

    updated()
    {
        this.$emit('cacheParams', this.data);
    },

    methods: {
        addParams()
        {
            this.data.push({"key":"", "value":"","is":1});
        },
        deleteParams(index)
        {
            this.data.splice(index, 1);
        },
    }
}
</script>

頁(yè)面:

clipboard.png

下面那個(gè)input框是子組件, 我想實(shí)現(xiàn)的效果是 input框發(fā)生變化實(shí)時(shí)通知給父組件 然后父組件在上面那個(gè)url框進(jìn)行拼接 比如: test.php?id=1&name=3

已嘗試的解決方案:

1、在子組件里聲明updated方法然后拋出事件給父組件 this.$emit('cacheParams', this.data);

這樣每次data發(fā)生變化都會(huì)通知父組件并把改過(guò)的或者新增的data數(shù)據(jù)傳遞給父組件, 
但是這樣會(huì)把全部數(shù)據(jù)給父組件 父組件每次都需要for循環(huán)一遍全部數(shù)據(jù) 很浪費(fèi)性能。

請(qǐng)問(wèn)還有沒(méi)有一些其他的解決方案

回答
編輯回答
終相守

使用.sync語(yǔ)法糖: https://cn.vuejs.org/v2/guide...

2017年9月3日 22:57
編輯回答
維他命

首先。。。麻煩簡(jiǎn)化一下你的代碼。。。八哥看著頭大。
其次,簡(jiǎn)要說(shuō)一下父組件監(jiān)聽(tīng)子組件數(shù)據(jù)的方法(沒(méi)看你的示例,不知道是不是你要的)

// 父組件
<template>
    <child-comp v-model="a"></child-comp>
</template>
export default {
    data() {
        a: ''
    }
}
// 子組件
<template>
    <input @input="handleInput" />
</template>
export default {
    methods: {
        handleInput() {
            this.$emit('input', e.target.value)
        }
    }
}

Vue關(guān)于組件的章節(jié)

其實(shí)這里的v-model也是一個(gè)語(yǔ)法糖,省略了在父組件里監(jiān)聽(tīng)input事件的代碼。
如果你的數(shù)據(jù)項(xiàng)比較多,那就分別發(fā)事件吧。

this.$emit('xx', payload)
2017年9月4日 19:13