stefanhoelzl/vue.py

Proper way to integrate a Javascript Vue plugin

adamlwgriffiths opened this issue · 3 comments

I'm not clear how to wrap and integrate a Vue.js plugin from the docs.

I've got the following:

# plugins/socketio.py
from browser import window
from vue import Vue
from vue.decorators.base import VueDecorator, pyjs_bridge

def install(socketio=None):
    SocketIO = window.io
    VueSocketIO = window.VueSocketIO

    socketio = socketio or SocketIO()
    Vue.use(VueSocketIO.new({
        'debug': True,
        'connection': socketio,
    }))

class Sockets(VueDecorator):
    __key__ = "sockets"

    def __init__(self, fn):
        self.fn = fn
        self.__id__ = fn.__name__
        self.__value__ = pyjs_bridge(fn, inject_vue_instance=True)

def sockets(fn):
    return Sockets(fn)
# app.py
from vue import VueComponent
from . import plugins

class App(VueComponent):
    template = '''
        <div class="container">
            <router-view></router-view>
        </div>
    '''

plugins.socketio.install()

App("#app")

I'm not sure if I should use VuePlugin or some other method.

Along with this, VueSocketIO can receive a dict of options, I'm not sure how this would be passed in?

As described in the documentation native Vue Plugins work out of the box with vuepy.

try this example app.py

from browser import window
from vue import Vue, VueComponent

Vue.use(window.VueSocketIO.new({
    'debug': True,
    'connection': window.io.new(),
}))

class App(VueComponent):
    template = '''
        <div class="container" />
    '''

App("#app")

along with this vuepy.yml (to use the required javascript libraries, see also the documentation)

scripts:
  - https://unpkg.com/vue-socket.io@3.0.10/dist/vue-socketio.js
  - https://unpkg.com/socket.io-client@4.4.1/dist/socket.io.js

and deploy with flask as described here

vue-cli deploy flask

On a related note, I can't see any tests for VuePlugin, and despite the code and documentation matching the official Vue.js documentation, it doesn't seem to work.

Ie, when using the following:

from vue import VuePlugin

class StaticPlugin(VuePlugin):
    @staticmethod
    def install(options=None, kwargs=None):
        options = options.to_dict() if options else {}
        kwargs = kwargs.to_dict() if kwargs else {}
        print(f'StaticPlugin.install({options}, {kwargs})')

Vue.use(StaticPlugin, {'options': True})

class ObjectPlugin(VuePlugin):
    def install(self, options=None, kwargs=None):
        options = options.to_dict() if options else {}
        kwargs = kwargs.to_dict() if kwargs else {}
        print(f'ObjectPlugin.install({options}, {kwargs})')

Vue.use(ObjectPlugin, {'options': True})

I get the following output:

ObjectPlugin.install({'options': True}, {})

Ie, the @staticmethod version isn't run.

Thank you for reporting this.
Indeed tests for the VuePlugin are missing, I will need to dig into it an check what's wrong there.