stefanhoelzl / vue.py

Pythonic Vue.js
https://stefanhoelzl.github.io/vue.py/
MIT License
310 stars 20 forks source link

Proper way to integrate a Javascript Vue plugin #26

Open adamlwgriffiths opened 3 years ago

adamlwgriffiths commented 3 years ago

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?

stefanhoelzl commented 2 years ago

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
adamlwgriffiths commented 2 years ago

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.

stefanhoelzl commented 2 years ago

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.