Writing a Vue.js App in Python

Introduction

Transcrypt makes it possible to write JavaScript code using Python syntax. It can compile a significant subset of Python into fully functional JavaScript, and it got me thinking about what I could do with this newfound superpower.

How about building a Vue.js app using Python instead of JavaScript?

Installation

To get started, let's install transcrypt using pip:

# This example uses Transcrypt 3.6
pip install "transcrypt<3.7"

(If you aren't already, you should use virtualenv or pipenv to manage your Python dependencies per-project.)

N.B.: Keep an eye on what Python version you're using. Transcrypt supports Python 3.6, but as of the time of writing it doesn't yet support Python 3.7.

The Template

Here's a simple HTML template for our app, which consists of a message and a button that displays how many times it's been clicked:

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <title>Vue from Python</title>
    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
  </head>
  <body>
    <div id="app">
      <p>{{ message }}</p>
      <button @click="onClick">Clicked {{ count }} times</button>
    </div>
    <script src="__javascript__/app.js"></script>
  </body>
</html>

The template contains a script tag with Vue.js, and the app has three pieces of reactivity:

  1. The {{ message }} variable
  2. The @click="onClick" handler, which calls the click method
  3. The {{ count }} variable

The last piece of the puzzle is the app.js file, located in a somewhat strange-looking __javascript__ directory. We'll soon come back to that.

The Not-JavaScript

Take a look at this Python file, app.py:

# app.py
def on_click():
    this.count += 1


initial_data = {
    'message': 'Hello Vue (from Python)!',
    'count': 0,
}

methods = {
    'onClick': on_click
}

app = __new__(Vue(dict(
    el='#app',
    data=initial_data,
    methods=methods,
)))

If you're familiar with Vue.js, it might look familiar if a bit uncanny. If you're familiar with Python, it might also look a bit strange. Nevertheless, that Python code compiles to a working Vue.js application.

Let's take a look at some parts that warrant further explanation.

What's this?

In the on_click function on line 4, there's a seemingly rogue this. The this is the JavaScript this keyword, and it will work as expected in JavaScript. It looks odd in a Python file and it feels a little dirty using a variable that hasn't been imported. Think of it as cleaner JavaScript instead of dirtier Python.

That's __new__

The equivalent of new Vue() in Transcrypt is __new__(Vue()). There are other ways to create JavaScript objects in Transcrypt, too. With a bit of abstraction, creating the Vue component can look even more Pythonic:

def VueClass(config):
    return __new__(Vue(config))


app = VueClass({...})

JS -> Py

To compile this Python file to usable JavaScript, pass the filename as an argument to the transcrypt command:

$ transcrypt -b -m app.py

Transcrypt (TM) Python to JavaScript Small Sane Subset Transpiler Version 3.6.101
Copyright (C) Geatec Engineering. License: Apache 2.0

Saving target code in: /home/john/Code/python-vue/__javascript__/app.js

Ready

The first couple arguments are:

The transcrypt command outputs its version information and where it's saving the compiled JavaScript. There's that __javascript__ directory again. transcrypt processes the supplied files, converts them to JavaScript, moves them to the __javascript__ directory, and updates their extensions to .js.

Now that we've got a JS version of our Vue.js app, we can run it in the browser.

The Result

Feast your eyes on this:

Vue.js app screenshot
Vue.js app screenshot

We've got a working Vue.js app and we didn't even write any JS.

Conclusion

Writing JavaScript code using Python syntax is like writing CoffeeScript but with less JavaScript. I think it's pretty nifty, and I barely scratched the surface of what Transcrypt can do.

Whether you're looking to write form validation functions once and use them in a website's front- and backends, or whether you're just trying to get more Python in your web development workflow, Transcrypt is well worth a try. It supports a number of Python libraries, like datetime and numpy. It can compile your Python code to ES5, ES6, or Node.js. Transcrypt supports third-party JS libraries, too, like in the little Vue.js app above—or should I call it a Vue.py app?