0

I am making a chatbot in vue.js and I need your help. I created 2 Vue components:

  • ChatLoader.vue - first components that render a button to open actual webchat window

  • Webchat.vue - the async component that only loads when I
    Click on a button to open the chat window.

So what my ChatLoader.vue is doing is setting parameter chatInitialized = true on button click. Then the chat window is opened.

In my Webchat.vue I have a close button which on click only hides the chat window (not removed from DOM) by setting showWindow = false;

Now when the chat window is hidden I again see the button to open the chat (which was there all the time only not visible because overlapped by chatwindow) but when I click on the button now I want to set showWindow = true in Webchat.vue component instead of the previous behavior, so the webchat window is shown again.

ChatLoading.vue:

    <template>
    <div>
        <span class="open-chat" v-on:click="showChat">
            <i class="icon ficon-live-chat"></i>
            Virtual assistant
        </span>
        <Webchat v-if="chatInitialized"></Webchat>
    </div>
</template>

<script>
    import ChatLoading from "./ChatLoading.vue";

    const Webchat = () => ({
        component: import('./Webchat.vue'),
        loading: ChatLoading
    });

    export default {
        data() {
            return {
                chatInitialized: false
            }
        },
        components: {
            Webchat
        },
        methods: {
            showChat() {
                this.chatInitialized = true;
            }
        }
    }
</script>

Webchat.vue:

<template>
    <div class="chat-window" v-show="showWindow">
        <button type="button" class="cancel icon ficon-close" v-on:click="minimize"></button>
        <WebchatPlugin
        >
        </<WebchatPlugin>
    </div>
</template>

<script>
    import <WebchatPlugin{
        createDirectLine,
        createStore
    } from "botframework-webchat/lib/index";
    import {DirectLine} from "botframework-directlinejs";

    export default {
        data() {
            return {
                showWindow : true
            }
        },
        components: <WebchatPlugin
        methods: {
            minimize() {
                this.showWindow = false
            }
        },
</script>

How can I accomplish that? Thank you

1 Answer 1

1

If you want to toggle the child component's (<Webchat>) state showWindow from a consuming parent component, then you will have to create a method in the child component that can be invoked by the parent element.

First of all, in your Webchat component, create a new method, say maximize, that will change this.showWindow to true:

methods: {
    minimize() {
        this.showWindow = false;
    },
    maximize() {
        this.showWindow = true;
    }
},

Then, in your parent component, you can then:

  1. Create a reference to your Webchat component
  2. Use this.$ref to access the component and its inner methods, and call the maximize() method you've just created:

Example:

<template>
    <div>
        <span class="open-chat" v-on:click="showChat">
            <i class="icon ficon-live-chat"></i>
            Virtual assistant
        </span>

        <!-- Use `ref` attribute to create a reference to component -->
        <Webchat ref="webchat" v-if="chatInitialized"></Webchat>
    </div>
</template>

<script>
    import ChatLoading from "./ChatLoading.vue";

    const Webchat = () => ({
        component: import('./Webchat.vue'),
        loading: ChatLoading
    });

    export default {
        data() {
            return {
                chatInitialized: false
            }
        },
        components: {
            Webchat
        },
        methods: {
            showChat() {
                this.chatInitialized = true;

                // Access Webchat component's inner method
                // Do this inside `this.$nextTick` to ensure it is accessible
                this.$nextTick(() => {
                    this.$refs.webchat.maximize();
                });
            }
        }
    }
</script>
Sign up to request clarification or add additional context in comments.

3 Comments

You beat me to it - however I think you may have an issue - you are calling maximize() when the child component may not yet have been created. You might need to do this conditionally only if the chat is already initialised.
@EuanSmith True that, let me update my answer. Probably makes sense to wrap it inside this.$nextTick()
@Terry thanks, that solved my issue! Didn't know about $refs property in vue.js yet.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.