0

I am currently playing with Clippy.js, a js implementation of the old school Microsoft Agent. The problem occurs as I want to render the agent inside the App.vue component in my VueJS project. Though, i can't seem to figure out how to bind the agent to App.vue component, or any of its children.

The agent is loaded as follows:

<script>
import 'clippyjs';
methods: {
clippy() {
      clippy.load('Clippy', (agent) => {
        agent.show();
        agent.animate();
      });
    }
}
</script>

The code is from a method in my Header.app component, which is a child component of App.vue

LINK TO DIRECTORY : https://github.com/pi0/clippyjs

Ry-
  • 218,210
  • 55
  • 464
  • 476
kib
  • 77
  • 5
  • Not sure what you mean for `I want to render the agent inside the App.vue component in my VueJS project.` the Clippy js control the render for its agent, Vue can't control `clippy.js` where to put its agents. From the demo in the official site, `clippy.js` always put its agents as direct children of `body`. – Sphinx Aug 19 '20 at 16:29
  • @Sphinx is there a work around where you can bind the dom element to a specific div or something, possibly with css code ? thx for helpful answers – kib Aug 20 '20 at 10:51

1 Answers1

0

Below is one simple demo to integrate clippy.

The key point is fetch the agent instance inside the callback of clippy.load, then execute the actions you need by invoke the related APIs agent instance provides.

Clippy.js will add extra Dom elements under <body>, so we'd better to clear them up if necessary (like: component destroyed).

Anyway, the implementation of Clippy.js is based on real Dom through JQuery, Vue is based on Virtual Node. It makes the things a little complicate if uses Clippy.js in Vue project.

Vue.component('v-clippy',{
    template:`
        <div>
            <button v-show="!this.agent" @click="loadClippy()">Load Clippy</button>
            <button v-show="this.agent" @click="show()">Show</button>
            <button v-show="this.agent" @click="hide()">Hide</button>
            <button v-show="this.agent" @click="play()">Play</button>
            <button v-show="this.agent" @click="animate()">Animate</button>
            <button v-show="this.agent" @click="destroy()">Destroy</button>
        </div>
    `,
    props: {
      name: {
        type: String,
        default: 'Links'
      }
    },
    data () {
      return {
        agent: null
      }
    },
    mounted: function () {
      this.loadClippy()
    },
    methods: {
      loadClippy: function () {
        clippy.load(this.name, (agent) => {
          this.agent = agent
        })
      },
      show: function () {
        this.agent && this.agent.show()
      },
      hide: function () {
        this.agent && this.agent.hide()
      },
      play: function () {
        this.agent && this.agent.play('Searching')
      },
      animate: function () {
        this.agent.animate()
      },
      destroy: function () {
        this.agent._el.remove() // this.agent._el is the JQuery object binds to the Dom of Agent
        this.agent = null
      }
    }
})

new Vue ({
  el:'#app'
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.16/vue.js"></script>
<link rel="stylesheet" type="text/css" href="https://gitcdn.xyz/repo/pi0/clippyjs/master/assets/clippy.css">
<script src="https://unpkg.com/jquery@3.2.1"></script>
<script src="https://unpkg.com/clippyjs@latest"></script>

<div id="app">
    <div>
        <h3>Test Clippy</h3>
        <div>
            <v-clippy></v-clippy>
            <v-clippy name="Merlin"></v-clippy>
        </div>
    </div>
</div>
Sphinx
  • 10,519
  • 2
  • 27
  • 45
  • thx for useful answer, i kind of figured out a work around to get the wanted outcome with adding some css values to the DOM element rendered with jquery. – kib Aug 21 '20 at 09:56