alex-oleshkevich / vue-introjs

intro.js bindings for Vue.
MIT License
301 stars 53 forks source link

Nested Components #43

Closed bakztfuture closed 5 years ago

bakztfuture commented 5 years ago

Has anyone been able to get the plugin to load steps on nested components or components which dynamically render? I have only been able to get the tour to run on parent component steps.

Not sure where I'm going wrong.

alex-oleshkevich commented 5 years ago

Try to change waitTimeout property https://github.com/alex-oleshkevich/vue-introjs#autostart

Or start tour manually when you think all components are ready.

bakztfuture commented 5 years ago

Thanks @alex-oleshkevich !

As you had suggested, I ended up making the following changes to make it work:

  1. waitTimeout in my main.js (as per the docs)
  2. I ended up programmatically creating my tour entirely. I've included a rough out line of how I did it below:
    watch: {
    myVar: { 
        handler: function(){
            /* only start the tour once the actual elements have finished dynamically loading in the DOM */
            /* otherwise, introJS does not have any elements to actually bind to, or gets the positions wrong */
            this.$nextTick(() => {    
                /* dynamically load my steps */
                this.$intro().addSteps(
                    [
                        {
                            intro: "Step 1",
                            element: this.$refs.step_1,
                            position: "right",
                            disableInteraction: true // don't let the user click inside of the highlighted element
                        },
                        {
                            intro: "Step 2",
                            element: this.$refs.step_2,
                            position: "left",
                            disableInteraction: true
                        },
                        {
                            intro: "Step 3",
                            element: this.$refs.step_3_parent.$refs.step3_child_element,
                            position: "right",
                            disableInteraction: true
                        }
                    ]
                )
                .setOptions({
                    exitOnOverlayClick: false, // don't let the user click "out" of the tour to exit
                    overlayOpacity: 0.5 // changed to 0.5 felt it was too dark by default
                })
                .start() // start the tour
                .oncomplete(function () { // callback tour completion
                    console.log("done");
                })
                .onexit(function () {
                    console.log("exited"); // callback tour exit
                });
            });
        },
        deep: true,
        immediate: false // don't load the tour right away
    }
  3. note, in the example above, I am using vue's $refs attributes to identify elements when creating a new step (ie. element: this.$refs.step_1) This means that in my template code, there is a corresponding ref="step_1" attribute I've included for the div/element. I also had to include a ref attribute inside nested components too which allows introjs access to it for purposes of the tour.

Hope my example is useful to someone in the future. Best,

Update June 25, 2019: Code was behaving unexpectedly, especially on Safari. It would show the tour multiple times (even on a different view), it wouldn't even have the elements on the page to bind to. I would strongly recommend switching to the new outline I've shared in issue #44