【问题标题】:Is there a way, to "emit" a built in event, by hard coding it in Vue instance?有没有办法通过在 Vue 实例中硬编码来“发出”内置事件?
【发布时间】:2019-07-14 15:28:03
【问题描述】:

我想在我的 Vue 项目中将两个组件相互链接。 我为此使用双向绑定,因此我有一个父组件和两个子组件。

概念:

我们在屏幕左侧看到一个旋转木马,在右侧看到一个手风琴。我用 v-for 从一个数据库文件构建了旋转木马和手风琴。

当我点击一些手风琴时,它会下降,我需要来自轮播组件的反应,才能准确滑动到我点击手风琴的位置。

喜欢:

旋转木马:香蕉、苹果、房子

手风琴:香蕉、苹果屋

所以当我点击苹果手风琴按钮时,我需要滑块转到显示苹果的位置,然后反向。

正如我所说,我已经将这两个组件相互绑定了,所以当我单击像 @click="onShowStart(index)" 这样的手风琴按钮之一时,我也会在另一个孩子中获得该索引,并且它通过滑动或点击动态变化,反之亦然。所以索引已经链接并且它是动态的。

我的问题是我不知道如何触发事件,例如 @sliding-start from vue instance in the watch field。所以我在我的组件中观察了“actualPosition”道具,当它发生变化时(例如从 3 到 1),我想启动一个滑动事件到 actualPosition 的新值。

所以我需要类似的东西:

 this.$emit('sliding-start', actualPosition);

我已经解决这个问题好几天了,但我认为我的整个想法都是错误的。但在我相信这一点之前,我先问你。

这是我的父组件代码:

        <div class="row">
            <carousel :actualPosition="actualPosition" class="col bg-dark" @sendTheCarouselPosition="updateAccordion($event)"></carousel>
            <accordion :actualPosition="actualPosition" class="col bg-dark" @sendTheAccordionlPosition="updateCarousel($event)"></accordion>
        </div>

<script>
    export default {

        data() {
            return {
                actualPosition: null,
            }
        },

        methods:{
            updateAccordion: function (updatedAccordion){
                this.actualPosition = updatedAccordion;
            },
            updateCarousel: function(updatedSlider){
                this.actualPosition = updatedSlider
            }
        },
    }
</script>

我的 Accordion 组件:

<template>
    <div role="tablist">
        <b-card no-body class="mb-1" v-for="(item, index) in dataForProject">
            <b-card-header header-tag="header" class="p-1" role="tab">
                <b-button block href="#" v-b-toggle="'accordion-' + index" variant="info" @click="onShowStart(index)" >{{ item.title }}</b-button>
            </b-card-header>
            <b-collapse :id="'accordion-' + index" visible accordion="my-accordion" role="tabpanel">
                <b-card-body>

                    <div>
                        <h1>data from Carousel sibling: {{ actualPosition }}</h1>
                    </div>

                    <b-card-text>{{ item.content }}</b-card-text>
                </b-card-body>
            </b-collapse>
        </b-card>
    </div>
</template>


<script>
    import myDataBase from '../data2'

    export default {

        props:['actualPosition'],

        watch:{
            actualPosition: function () {


            },
        },

        data() {
            return {
                dataForProject: myDataBase,
            }
        },

        methods:{
            onShowStart: function (accordionIndex) {
                this.$emit('sendTheAccordionlPosition', accordionIndex);

            },



        },
    }
</script>

还有我的轮播组件:

<template>
    <div>
        <p class="mt-4 text-white">
            data from Accordion sibling: {{ actualPosition }}
        </p>
        <b-carousel
                id="carousel-1"
                :interval="0"
                controls
                indicators
                background="#ababab"
                img-width="1024"
                img-height="480"
                style="text-shadow: 1px 1px 2px #333;"
                ref="slider"
                @sliding-start="onSlideStart"
                @sliding-end="onSlideEnd"
        >

            <b-carousel-slide v-for="(item, index) in dataForProject" :id="index" >
                <img
                        slot="img"
                        class="d-block img-fluid w-100"
                        width="1024"
                        height="480"
                        :src="item.image_url"
                        alt="image slot"
                >
            </b-carousel-slide>
        </b-carousel>
    </div>
</template>

<script>
    import myDataBase from '../data2'

    export default {
        props:['actualPosition'],

        watch: {
            actualPosition: function () {

            },
        },


        data() {
            return {
                //slide: 0,
                dataForProject: myDataBase,
            }
        },
        methods: {
            onSlideStart(slide) {
                this.$emit('sendTheCarouselPosition', slide);
            },
            onSlideEnd(slide) {

            },

        }
    }
</script>

【问题讨论】:

    标签: vue.js carousel accordion vue-cli bootstrap-vue


    【解决方案1】:

    我可以通过两种方式完成。

    1 - 全球EventBus 我将创建一个 eventBus 并从任何文件在其上注册事件并在任何地方收听 -

    import { EventBus } from '@/eventBus' 
    // simply import it to component which need listen the event
    
    
    //Register Event where you have your methods - like In your COMP_B_TWO                   
     EventBus.$on('changeValue', () => { this.doSomething() })
    
    // Emit event from another component
    EventBus.$emit('changeValue')// Like directly from your COMP_A_TWO
    

    要了解如何创建 eventBus,请遵循此 - Global Event Bus Vue


    2 - 使用 state management - Vuex 点击此链接 - Vuex

    基本上,它将集中存储应用程序中的所有组件。每当您希望更新状态时,您都会更新到存储。并且所有其他使用该状态的组件都会做出相应的反应

    【讨论】:

    • 谢谢,但我已经完成了这部分。数据正在正确地流动。简而言之,我的问题是:我想从函数()调用@sliding-start 事件,因为我希望滑块移动到属性显示的位置。
    【解决方案2】:

    好的,所以我的整个概念都是错误的,我对此也错了。

    我应该对整个事情使用 v 模型。仅此而已。

    我将v-model添加到目标标签中,我的问题就解决了。

    【讨论】:

      猜你喜欢
      • 2017-04-24
      • 2017-01-22
      • 1970-01-01
      • 1970-01-01
      • 2010-10-16
      • 2017-08-05
      • 1970-01-01
      • 2015-08-27
      • 1970-01-01
      相关资源
      最近更新 更多