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

Vue (vuejs) examples? (ANY VUE EXPERT WILLING TO HELP?) #287

Closed
Tset-Noitamotua opened this issue Feb 10, 2017 · 20 comments
Closed

Vue (vuejs) examples? (ANY VUE EXPERT WILLING TO HELP?) #287

Tset-Noitamotua opened this issue Feb 10, 2017 · 20 comments

Comments

@Tset-Noitamotua
Copy link

Do you plan to provide some Vue examples?

@JdeH JdeH assigned JdeH and unassigned JdeH Feb 10, 2017
@JdeH
Copy link
Collaborator

JdeH commented Feb 10, 2017

Most examples of the use of frameworks are contributed by users.
If anyone contributes a good example, probably we'll include it in the distro.

KR
Jacques

@JdeH JdeH closed this as completed Mar 6, 2017
@icarito
Copy link

icarito commented Feb 21, 2018

I'm trying but I'm running into an issue - I've created an object by instantiating a class and passing this object to Vue, I'm getting an infinite look (recursion limit) I think it's looping over __metaclass__.

How to aproach this issue? Thanks!

@JdeH
Copy link
Collaborator

JdeH commented Feb 21, 2018

Could you show me some code in order to be able to help you?

@icarito
Copy link

icarito commented Feb 21, 2018

Sure! I'm writing a module for Nuxtjs which will allow to write Nuxt apps with Python / Transcrypt.
But I've currently only been able to produce the required object with Javascripthon.

Please check out:

https://github.com/nuxt-community/python-module/blob/transcrypt_example/example/pages/transcrypt.vue

It is a single file component with Transcrypt syntax. Since Vue is rather functional, Python may not be the best match for producing the required objects (docs at https://vuejs.org/v2/guide/ )

@icarito
Copy link

icarito commented Feb 21, 2018

Here's also the relevant Nuxt docs. Nuxt is a framework which uses the filesystem as routes to serve .vue files, single file components.
For better documentation of the issue here's the clean code achieved with Javascripthon:

<script lang="py">
from ..components.PythonLogo import __default__ as PythonLogo
from ..components.NuxtLogo import __default__ as NuxtLogo
class Component:
    def __init__(self):
      self['components'] = { 'NuxtLogo': NuxtLogo, 'PythonLogo': PythonLogo }
      self['data'] = lambda: {
        'name': 'Nuxt.js + Python',
        'description': 'Build Nuxt.js applications using Python!'
      }
      self['methods'] = {
        'increment': self.increment,
        'decrement': self.decrement
      }
    def increment(self):
      self['$store'].commit('increment')
    def decrement(self):
      self['$store'].commit('decrement')
__default__= Component()
</script>

While with Transcrypt I'm using this and getting errors:

<script lang="py?compiler=transcrypt">
__pragma__('jsiter')
PythonLogo = require ('@/components/PythonLogo')['default']
NuxtLogo = require ('@/components/NuxtLogo')['default']
def increment(self):
  console.log(self)
  this['$store'].commit('increment')
def decrement(self):
  console.log(this)
  this['$store'].commit('decrement')
c = {}  # __: jsiter
c['components'] = { 'NuxtLogo': NuxtLogo, 'PythonLogo': PythonLogo }
c['data'] = lambda: {
    'name': 'Nuxt.js + Python',
    'description': 'Build Nuxt.js applications using Python!'
    }
c['methods'] = {
    'increment': increment,
    'decrement': decrement
    }
module.exports = c
</script>

Getting:


client.js?name=client&reload=true&timeout=30000&path=/__webpack_hmr:87 [HMR] connected
vue-meta.js:502 Uncaught RangeError: Maximum call stack size exceeded
    at eval (vue-meta.js:502)
    at Array.reduce (<anonymous>)
    at escape (vue-meta.js:502)
    at eval (vue-meta.js:517)
    at Array.reduce (<anonymous>)
    at escape (vue-meta.js:502)
    at eval (vue-meta.js:517)
    at Array.reduce (<anonymous>)
    at escape (vue-meta.js:502)
    at eval (vue-meta.js:517)
    at Array.reduce (<anonymous>)
    at escape (vue-meta.js:502)
    at eval (vue-meta.js:517)
    at Array.reduce (<anonymous>)
    at escape (vue-meta.js:502)
    at eval (vue-meta.js:517)
    at Array.reduce (<anonymous>)
    at escape (vue-meta.js:502)
    at eval (vue-meta.js:517)
    at Array.reduce (<anonymous>)
    at escape (vue-meta.js:502)
    at eval (vue-meta.js:517)
    at Array.reduce (<anonymous>)
    at escape (vue-meta.js:502)
    at eval (vue-meta.js:517)
    at Array.reduce (<anonymous>)
    at escape (vue-meta.js:502)
    at eval (vue-meta.js:517)
    at Array.reduce (<anonymous>)
    at escape (vue-meta.js:502)
    at eval (vue-meta.js:517)
    at Array.reduce (<anonymous>)
    at escape (vue-meta.js:502)
    at eval (vue-meta.js:517)
    at Array.reduce (<anonymous>)
    at escape (vue-meta.js:502)
    at eval (vue-meta.js:517)
    at Array.reduce (<anonymous>)
    at escape (vue-meta.js:502)
    at eval (vue-meta.js:517)
    at Array.reduce (<anonymous>)
    at escape (vue-meta.js:502)
    at eval (vue-meta.js:517)
    at Array.reduce (<anonymous>)
    at escape (vue-meta.js:502)
    at eval (vue-meta.js:517)
    at Array.reduce (<anonymous>)
    at escape (vue-meta.js:502)
    at eval (vue-meta.js:517)
    at Array.reduce (<anonymous>)
    at escape (vue-meta.js:502)
    at eval (vue-meta.js:517)
    at Array.reduce (<anonymous>)
    at escape (vue-meta.js:502)
    at eval (vue-meta.js:517)
    at Array.reduce (<anonymous>)
    at escape (vue-meta.js:502)
    at eval (vue-meta.js:517)
    at Array.reduce (<anonymous>)
    at escape (vue-meta.js:502)
    at eval (vue-meta.js:517)
    at Array.reduce (<anonymous>)
    at escape (vue-meta.js:502)
    at eval (vue-meta.js:517)
    at Array.reduce (<anonymous>)
    at escape (vue-meta.js:502)
    at eval (vue-meta.js:517)
    at Array.reduce (<anonymous>)
    at escape (vue-meta.js:502)
    at eval (vue-meta.js:517)
    at Array.reduce (<anonymous>)
    at escape (vue-meta.js:502)
    at eval (vue-meta.js:517)
    at Array.reduce (<anonymous>)
    at escape (vue-meta.js:502)
    at eval (vue-meta.js:517)
    at Array.reduce (<anonymous>)
    at escape (vue-meta.js:502)
    at eval (vue-meta.js:517)
    at Array.reduce (<anonymous>)
    at escape (vue-meta.js:502)
    at eval (vue-meta.js:517)
    at Array.reduce (<anonymous>)
    at escape (vue-meta.js:502)
    at eval (vue-meta.js:517)
    at Array.reduce (<anonymous>)
    at escape (vue-meta.js:502)
    at eval (vue-meta.js:517)
    at Array.reduce (<anonymous>)
    at escape (vue-meta.js:502)
    at eval (vue-meta.js:517)
    at Array.reduce (<anonymous>)
    at escape (vue-meta.js:502)
...

@JdeH
Copy link
Collaborator

JdeH commented Feb 21, 2018

I must say I've currently no idea what's going on and why.
This is because I don't know anything about Vue.

But the code in the Javascripthon example looks a lot more Pythonic than the Transcrypt code. Why is that? Can't you use a class there as well? And why are the two jsiter pragma's necessary. They are meant for very uncommon cases.

The error report indeeds signals infinite recursion. But what is vue-meta.js? Is it generated from the Transcrypt code? Do you perhaps need components, as described in:

http://www.transcrypt.org/docs/html/special_facilities.html#transcrypt-s-unit-mechanism-and-creating-native-javascript-component-frameworks ?

Sorry for all these utterly uninformed questions, but I have no concept of how this is supposed to work, so I try to explore the playfield...

@JdeH JdeH reopened this Feb 21, 2018
@JdeH JdeH changed the title Vue (vuejs) examples? Vue (vuejs) examples? (ANY VUE EXPERT WILLING TO HELP?) Feb 21, 2018
@icarito
Copy link

icarito commented Feb 22, 2018

Jaques,
Here's what we are actually trying to accomplish.
It is an object that will hold functional behaviour of the web component at hand.
I've found it's tricky to produce this object with Python syntax. Any idea for it would be cool.
Also I've found Transcrypt works with Nuxt only in SPA mode, server side rendering doesn't work as something in Transcrypt wants to access the window object.
If you check out the https://github.com/nuxt-community/python-module/tree/transcrypt_example (transcrypt_example branch), i've just added this javascript example.
When you run with npm run dev you'll get routes / with pj, /transcrypt with transcrypt and /javascript with this example.

<script>
import PythonLogo from '~/components/PythonLogo'
import NuxtLogo from '~/components/NuxtLogo'


export default {
  components : { 'NuxtLogo': NuxtLogo, 'PythonLogo': PythonLogo },
  data: function () {
    return {
      'name': 'Nuxt.js + Python',
      'description': 'Build Nuxt.js applications using Python!'
      }
  },
  methods: {
    increment: function() {
      this['$store'].commit('increment')
    },
    decrement: function() {
      this['$store'].commit('decrement')
    }
  }
}
</script>

@icarito
Copy link

icarito commented Feb 22, 2018

It's necessary to launch the example with nuxt --spa example/ in order to try SPA mode or it will fail.

@JdeH
Copy link
Collaborator

JdeH commented Feb 22, 2018

I 've tried to install the example but unfortunately the installation fails on my Windows 10 machine.

But already one hint:
To keep Transcrypt from referencing the global Window object, take a look at the -p .none switch,
that's also used when compiling server side applications for node.js.

@JdeH
Copy link
Collaborator

JdeH commented Feb 22, 2018

Tranlated from your JavaScript example a sugggestion would be (currently no idea if it really works):

<script lang="py?compiler=transcrypt">

__pragma__ ('js', '{}', '''
    import PythonLogo from '~/components/PythonLogo';
    import NuxtLogo from '~/components/NuxtLogo';
''')

class MyClass:
    def __init__ (self):
        self.components = {'NuxtLogo': NuxtLogo, 'PythonLogo': PythonLogo}

    def data (self):
        return {
            'name': 'Nuxt.js + Python',
            'description': 'Build Nuxt.js applications using Python!'
        }
        
    def increment (self):
        self ['$store'].commit('increment')
        
    def decrement (self):
        self ['$store'].commit('decrement')

__pragma ('js', '', ''')      
    export default {MyClass ()};
''')

</script>

To make the whole thing lean when multiple components are used on a page, probably you need to use Transcrypt units. This avoids duplicating the runtime and other common code.

As mentioned earlier, units (components) are described at:

http://www.transcrypt.org/docs/html/special_facilities.html#transcrypt-s-unit-mechanism-and-creating-native-javascript-component-frameworks

Sorry my help isn't more concrete, but I currently lack the Vue knowledge for that.

@mmjee
Copy link

mmjee commented Feb 24, 2018

@icarito I had previously used Vue, Browserify with Transcrypt, it worked, but I didn't use webpack, so it seems you just need a plain old JS object, Python can implement functions, you don't need classes, Vue is rather functional.

@pyenthu
Copy link

pyenthu commented Sep 6, 2018

Dear All I am not a vue expert but have been hacking my way through this problem last few days.
I have also come to the same conclusion that vue needs functions not classes.
However we still need to encapsulate this within a class to not pollute the global name space.
This is a small excerpt from the work I am doing. I was able to compile a component and make it work quite well.

`#This is the python file
pragma('alias', 'jq', '$')
pragma('alias', 'this_items', 'this.items')
pragma('kwargs')
pragma('alias', 'print', 'console.log')

from .template import comp_template

class my_comp():
props = ['api']

@staticmethod
def data():
    return {'showSearch': False,
            'items': [],
            'selectedItems': [], 'filter': '', 'count': 0,
            'fields': ['first_name', 'last_name', 'age', 'img', 'add_me']}

@staticmethod
def created():
    this.init()

@staticmethod
def showSearchBox():
    this.showSearch = not this.showSearch

@staticmethod
def addMe(data):
    this.selectedItems.push(data)

@staticmethod
def init():
    this.loadData()

@staticmethod
def loadData():
    _this = this

    def process_request(response):
        if response.data is not None:
            _this.js_items = response.data
        else:
            alert('RESPONSE BODY IS NONOE')

    axios.js_get(this.api).then(process_request)

@staticmethod
def comp_defs():
    class_handle = my_comp
    methods = {'showSearchBox': class_handle.showSearchBox,
               'addMe': class_handle.addMe,
               'init': class_handle.init,
               'loadData': class_handle.loadData}

    return {'data': class_handle.data,
            'props': class_handle.props,
            'template': comp_template,
            'created': class_handle.created,
            'methods': methods}

Vue.component('vrs-search', my_comp.comp_defs())
`
I also wrote a small compilation script to incorporate an html based template for view to be incorporated into the component. This allows you to build the template in a good html ide.
A bit hacky but works like a charm for me. Key thing is to be able to use "this" key word whilst maintaining some semblance of OOP tenets of python. Not using python instances at all.
Hope to exchange more ideas soon.

`import argparse
from subprocess import call
from pathlib import Path

if name == 'main':
parser = argparse.ArgumentParser()
parser.add_argument("file", help="Python File")
parser.add_argument("--template", "-t", help="template file")

args = parser.parse_args()

# Get the template
html = Path(args.template).read_text()
html = html.replace('\n', '\\\n').replace('\r', '\\\n')
template_py_file = open('template.py', 'w')
tpl_py = ''.join(['comp_template=', '\'', html, '\''])
print(tpl_py, file=template_py_file)
template_py_file.close()

# Define the methods
call('transcrypt -b -n %s' % (args.file))

`

@manatlan
Copy link

manatlan commented Oct 1, 2018

I'm working on the same kind of thing.
My tests with transcrypt weren't goods.

But currently, I reach to use components like that :

<template>
    <div>
        {{name}} {{cpt}}
        <button @click="inc()">++</button>
    </div>
</template>
<script lang="python">

class Component:
    def __init__(self, name):  # <- name is a props
        self.cpt=0

    def inc(self):
        self.cpt+=1

</script>
<style scoped>
    :scope {background:#EEE}
</style>

Currently, I've got the lifecyles, watchers, computed, props features ...
I've not released it yet, but it will be in my vbuild thing
Will release soon

@manatlan
Copy link

manatlan commented Oct 4, 2018

BTW, I've just released ... my vision of "python component" in a vue/sfc file, thru vbuild (python lib to render "*.vue" -> html/script/style, without a nodejs stack).

All is here : https://github.com/manatlan/vbuild
The py component part : https://github.com/manatlan/vbuild/blob/master/doc/PyComponent.md

It's pretty usable (I use it in production)

@JdeH
Copy link
Collaborator

JdeH commented Oct 5, 2018

@manatlan
What would you need in Transcrypt (enhancements, fixes) to make vbuild work with Transcrypt?

@manatlan
Copy link

manatlan commented Oct 6, 2018

I've made tests with the 3 main currents transpilers (transcrypt, javascrypthon and pscript). I want to keep vbuild py2/py3 compliant (I use it mainly on appengine/py27 (but will go with py37 soon))
transcrypt seems to be a command line only. I needed to do hacks to call it from python code. And AFAIK, it's not py2 & py3 compatible. Javascrypthon is py3 only, but callable easily with python. pscript works with py2 & py3 ootb, and is simple, and callable from python (but miss decorators support ... but reach to bypass this limitation by using conventions names, which is less verbose too (good point)).

btw, python components doesn't need all py std lib ... and pscript seems to do the minimal which fit the needs. (and will support decorators soon)

@icarito
Copy link

icarito commented Oct 14, 2018

Hi @manatlan thanks for pointing me to wuy and vbuild, and PScript, hadn't seen it!
What I like most about Javascripthon is source maps :-D

@manatlan
Copy link

manatlan commented Oct 21, 2018

your welcome...

btw, i've just released a vbuild demo, so you can EASILY test python/pscript rendering of python components, in a vuejs context ! (the demo is, himself, a vuejs python component)

@Andrei-Pozolotin
Copy link

related:
#665

@JennaSys
Copy link
Collaborator

JennaSys commented Jul 7, 2024

Closing as answered

@JennaSys JennaSys closed this as completed Jul 7, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

8 participants