Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Dynamic content in Vue components #1074

Closed
1 task done
Fohlen opened this issue Mar 14, 2020 · 8 comments · Fixed by #1271
Closed
1 task done

Dynamic content in Vue components #1074

Fohlen opened this issue Mar 14, 2020 · 8 comments · Fixed by #1271
Labels
bug confirmed as a bug vuejs related to Vue.js

Comments

@Fohlen
Copy link

Fohlen commented Mar 14, 2020

Bug Report

In the documentation it says that one can embed Vue instances. I tried building an interactive component for our documentation like so:

# Servers

Thanks to [AngrySnout](https://github.com/AngrySnout/SauerTracker) we have excellent statistics for the game.

<div id="server">
    <ul>
        <li v-for="server in servers" :key="server.description"> {{ server.descriptionStyled }} </li>
    </ul>
</div>

<script>
  const API_URL = "https://tomaten.sauertracker.net/api/servers"

  new Vue({
    el: '#server',
    data: () => ({
        servers: []
    }),
    async mounted {}
        console.log("HEY")
        const response = await fetch(API_URL);
        this.servers = await response.json(); 
    }
  })
</script>

However when loading the page the content quickly flashes before getting "rendered away".
I have no idea what sorcery is going on behind the scenes but my best bet is that it's an unsupported feature.

Steps to reproduce

(see above)

What is current behaviour

(see above)

What is the expected behaviour

The app that is rendered on screen should allow for dynamic content.

Other relevant information

  • Bug does still occur when all/other plugins are disabled?

  • Your OS: OSX 10.15.3 (19D76)

  • Browser version: Version 80.0.3987.132 (Official Build) (64-bit)

  • Docsify version: 4.11.2

  • Docsify plugins: search plugin

@anikethsaha
Copy link
Member

Sorry I am not familiar with vue so cant really help you here !

Feel Free to investigate and submit the fix.

Also, try testing with older version and check in which it broke, it will help in investigation

@Koooooo-7
Copy link
Member

Actually ,It seems some issues about the Vue supports in docsify.
Currently, when u create ur own Vue instance, you will not get the Vue instance in the mounted hook by using this (this directs to the window obj in docsify now).

the Vue instance was covered in this.__EXECUTE_RESULT__.
there is showing how we execute script in docsify.

  // Execute script
  if (
    this.config.executeScript !== false &&
    typeof window.Vue !== 'undefined' &&
    !executeScript()
  ) {
    setTimeout(_ => {
      const vueVM = window.__EXECUTE_RESULT__;
      vueVM && vueVM.$destroy && vueVM.$destroy();
      window.__EXECUTE_RESULT__ = new window.Vue().$mount('#main');
    }, 0);
  } else {
    this.config.executeScript && executeScript();
  }

Although, I tried to set the root data in a hack way, it seems not work.
I haven't found a way to resolve it yet, I hope those informations could be helpful.

@stale
Copy link

stale bot commented May 14, 2020

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.

@stale stale bot added the wontfix label May 14, 2020
@stale stale bot closed this as completed May 21, 2020
@trusktr
Copy link
Member

trusktr commented Jun 21, 2020

stale bot may make it harder to triage issues if they get closed before we see them. Wdyt?

Now that I've realized this, I need to go check all the closed issues.

@trusktr trusktr reopened this Jun 21, 2020
@stale stale bot removed the wontfix label Jun 21, 2020
@trusktr
Copy link
Member

trusktr commented Jun 21, 2020

Regarding the original issue, I think I encountered them. I believe it has to do with double execution of scripts, and I refactored this code in my personal fork. I will make a PR soon...

@trusktr trusktr added the bug confirmed as a bug label Jun 21, 2020
@jhildenbiddle
Copy link
Member

@Fohlen --

This bug is currently being addressed in #1271. The changes in that PR allow your example to work as expected, albeit with a few minor changes:

<div id="server">
  <ul>
    <li v-for="server in servers" :key="server.description">
      <span v-html="server.descriptionStyled"></span>
    </li>
  </ul>
</div>

<script>
  const API_URL = "https://tomaten.sauertracker.net/api/servers"

  new Vue({
    el: '#server',
    data: () => ({
      servers: []
    }),
    async mounted() {
      console.log("HEY")
      const response = await fetch(API_URL);
      this.servers = await response.json();
    }
  });
</script>

@jhildenbiddle jhildenbiddle linked a pull request Jul 5, 2020 that will close this issue
@woshiguabi
Copy link
Contributor

woshiguabi commented Aug 14, 2020

my solution:
set executeScript to false and use a plugin to initial Vue instance

((global, plugin) => {
  global.DocsifyVuePlugin = plugin;
})(window, () => (hook) => {
  let script = null;
  hook.beforeEach(() => {
    if(window.__DOCSIFY_VUE_INSTANCE__ ){
      window.__DOCSIFY_VUE_INSTANCE__.$destroy();
      window.__DOCSIFY_VUE_INSTANCE__ = null;
    }
  });
  hook.afterEach((content, next) => {
    script = null;
    const template = content.replace(/<script>([\s\S]*?)<\/script>/g, ($0, $1) => {
      if(!script) {
        script = $1;
      }
      return '';
    });
    return next(script ? `<div id="docsifyVuePluginInstance">${template}</div>` : content);
  });
  hook.doneEach(() => {
    if(!script) return;
    const vm = window.eval(script);
    script = null;
    if (vm instanceof window.Vue) {
      vm.$mount('#docsifyVuePluginInstance');
      window.__DOCSIFY_VUE_INSTANCE__ = vm;
    }
  })
});
<div>{{msg}}</div>
<script>
new Vue({
  data() {
    return { msg: 'hello' };
  },
});
</script>

@jhildenbiddle
Copy link
Member

@Fohlen --

Fixed in #1271. The example code you provided has a few issues though. Here's update code that will work as is:

# Servers

Thanks to [AngrySnout](https://github.com/AngrySnout/SauerTracker) we have excellent statistics for the game.

<div id="server">
    <ul>
        <li v-for="server in servers" :key="server.description"><span v-html="server.descriptionStyled"></span></li>
    </ul>
</div>

<script>
  const API_URL = "https://tomaten.sauertracker.net/api/servers"

  new Vue({
    el: '#server',
    data: () => ({
        servers: []
    }),
    mounted() {
      console.log("HEY")
      fetch(API_URL)
        .then(response => response.json())
        .then(data => this.servers = data)
        .catch(err => console.log(err));
    }
  })
</script>

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug confirmed as a bug vuejs related to Vue.js
Projects
None yet
Development

Successfully merging a pull request may close this issue.

6 participants