Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
187 views
in Technique[技术] by (71.8m points)

vue.js - Using same .vue component twice in same parent component - how to differentiate

I want to use the same component twice from a parent component; all that was stopping me was the use of an ID for a dropdown in the subcomponents! So I currently have duplicated the subcomponent.

My parent component:

<template>

    <div id="compare-page">

        <div class="row">

            <div class="col-md-12">

                <div class="row campaign-overview">

                    <div class="col-md-4">
                        <h2>{{ campaign.name }}</h2>
                        <strong>Published</strong>
                        <strong>Starts: {{ campaign.start_date }} - Ends: {{ campaign.end_date }}</strong>
                    </div>

                    <div class="col-md-4 text-right">
                        <select name="daterange" id="" @change="onChangeDaterange($event)">
                            <option v-for="(daterange, index) in dateranges" v-bind:key="daterange.index" :value="index" :data-start="daterange.start" :data-end="daterange.end" :selected="daterange.optionSelected == 1">{{ index }}</option>
                        </select>
                    </div>

                </div>

            </div>
            
        </div>

        <div class="row">

            <div class="col-md-6">

                <left-device ref="leftDevice"></left-device>

            </div>

            <div class="col-md-6">

                <right-device ref="rightDevice"></right-device>

            </div>

        </div>

    </div>

</template>


<script>

    import left from './compared_device_component_left.vue';
    import right from './compared_device_component_right.vue';

    export default {

        components: {
            'left-device': left,
            'right-device': right,
        },
        mounted() {

            this.fetchCampaignData().then(result => {

            });

        },
        data() {
            return {
                campaign_id: this.$route.params.campaign_id,
                campaign: [],
                dateranges: [],
                leftDevice: '',
                rightDevice: ''
            }
        },
        methods: {

            fetchCampaignData() {
                return this.$http.get('/api/portal/campaign/' + this.campaign_id + '/campaign?' + this.axiosParams)
                .then(function(data){
                    return data.json();
                }).then(function(data){
                    this.campaign = data.campaign;
                    this.dateranges = data.dateranges;
                });
            },

            onChangeDaterange(event) {

                this.$router.push('?range=' + event.target.value);

                this.$refs.leftDevice.onChangeDaterange(event);
                this.$refs.rightDevice.onChangeDaterange(event);

            },

        },

        computed: {
            axiosParams() {
                const params = new URLSearchParams();
                if(this.$route.query.range) params.append('range', this.$route.query.range);
                return params;
            }
        },

    }
    
</script>


<style lang="scss">

</style>

One of my subcomponents

<template>

    <div>

        <div class="row device-overview">

            <div class="col-md-4">
                <select name="devices" id="deviceLeft" @change="onChangeDevice($event)">
                    <option v-for="(device, index) in devices" v-bind:key="device.index" :value="index" :data-device_id="device.device_id" :data-address="device.address" :selected="device.optionSelected == 1">{{ device.device_id }} | {{ device.address }}</option>
                </select>
            </div>

        </div>

        <div class="row totals">

            <div class="col-md-4 card">
                <div class="card-body">
                    <h5 class="card-title">Total Interactions</h5>
                    <p class="card-text">{{ total_interactions }}</p>
                </div>
            </div>

            <div class="col-md-4 card">
                <div class="card-body">
                    <h5 class="card-title">Average Interactions Per Day</h5>
                    <p class="card-text">{{ average_daily_interactions }}</p>
                </div>
            </div>

            <div class="col-md-4 card">
                <div class="card-body">
                    <h5 class="card-title">Total Average Dwell Time</h5>
                    <p class="card-text">{{ average_dwell_time }}s</p>
                </div>
            </div>

        </div>
        
        <div class="row interactions">

            <div class="col-md-12">
                <h5>Total Interactions Per Product</h5>
                <table class="table table-condensed table-hover">
                    <tbody>
                        <tr>
                            <td class="">Tag</td>
                            <td class="">Mapped Product</td>
                            <td class="">Lifts</td>
                        </tr>
                        <tr v-for="interaction in table_product_interactions">
                            <td class="">{{ interaction.tag }}</td>
                            <td class="">{{ interaction.mapping }}</td>
                            <td>{{ interaction.tag_count }}</td>
                        </tr>
                    </tbody>
                </table>
            </div>

            <div class="col-md-12">
                <h5>Total Interactions Per Day</h5>
                <div class="chart" ref="chartdaily"></div>
            </div>

        </div>

        <div class="row interactions">

            <div class="col-md-8">
                <h5>Total Interactions Per Hour</h5>
                <div class="chart" ref="charthourly"></div>
            </div>

        </div>

    </div>

</template>


<script>

    import * as am4core from "@amcharts/amcharts4/core";
    import * as am4charts from "@amcharts/amcharts4/charts";
    import am4themes_animated from "@amcharts/amcharts4/themes/animated";

    am4core.useTheme(am4themes_animated);

    export default {

        mounted() {

            this.fetchData(null).then(result => {
                this.chartTotalPerDay();
                this.chartTotalPerHour();
            });

        },

        data() {
            return {
                campaign_id: this.$route.params.campaign_id,
                campaign: [],
                dateranges: [],
                device: [],
                devices: [],
                total_interactions: '',
                average_daily_interactions: '',
                average_dwell_time: '',
                interaction_type: '',
                chart_daily_interactions: [],
                chart_hourly_interactions: [],
                table_product_interactions: []
            }
        },

        methods: {

            fetchData(deviceID) {

                // Use JS to get by ID!
                var device = document.getElementById("deviceLeft");

                // ... call to API
            },

            chartTotalPerDay() {
                // ...
            },

            chartTotalPerHour() {
                // ...
            },

            onChangeDaterange(event) {

                // Use JS to get by ID!
                var device = document.getElementById("deviceLeft");

                // st cookie
                document.cookie = "deviceLeft="+device.value;

                this.fetchData(device.value).then(result => {

                    this.chartTotalPerDay();
                    this.chartTotalPerHour();
                    
                });

            },

            onChangeDevice(event) {

                // st cookie
                document.cookie = "deviceLeft="+event.target.value;

                this.fetchData(event.target.value).then(result => {

                    this.chartTotalPerDay();
                    this.chartTotalPerHour();
                    
                });

            }

        },

        created() {

        },

        computed: {
            axiosParams() {
                const params = new URLSearchParams();
                if(this.$route.query.range) params.append('range', this.$route.query.range);
                return params;
            }
        },

        filters: {

        },
        
        directives: {

        },

    }
</script>


<style lang="scss">

    .interactions {
        h5 {
            text-align: center;
        }
    }

    .chart {
        min-height: 550px;
    }

</style>

I am currently using

var device = document.getElementById("deviceLeft");

...in my duplicated left/right subcomponents (this is 'left' and I also have 'right').

Should I use a 'ref' for my devices dropdown, so that each instance of the subcomponent is looking at the devices dropdown relative to that instance? Currently if I merge these into one the devices dropdown ID is the same for both instances and therefore I get incorrect ID in one of the instances!

Any helpful pointers would be much appreciated.

Thanks, K...

question from:https://stackoverflow.com/questions/65842646/using-same-vue-component-twice-in-same-parent-component-how-to-differentiate

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)
Waitting for answers

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...