Subscribe on changes!

use vue template in js directly

avatar
Oct 7th 2020

What problem does this feature solve?

similar to JSX

  1. Write more than one component in a file ;
  2. Use variables directly in the current scope ;
  3. Retain the hoist, block, patchProps, and so on;

What does the proposed API look like?

before compile

import { reactive } from "vue";

export default {
  name: "App",
  setup() {
    let state = reactive({ 
      title: 'jsv-compiler',
      count: 0 
    });

    function handleClick() {
      state.count  ;
    }

    // Write more than one component in a file. The Title here is a component.
    let Title = <template><h1>hello {{state.title}}</h1></template>
    
    // Use variables directly in the current scope, such as state.count
    return (
      <template>
        <Title />
        <div>{{ state.count }}</div>
        <button v-on:Click="handleClick">click add 1</button>
      </template>
      )
  },
};

after compile

import * as Vue from 'vue';
import { reactive } from "vue";

export default {
  name: "App",
  setup() {
    let state = reactive({
      title: 'jsv-compiler',
      count: 0
    });

    function handleClick() {
      state.count  ;
    }

    // Write more than one component in a file. The Title here is a component.
    let Title = (() => {
      const { toDisplayString: _toDisplayString, createVNode: _createVNode, openBlock: _openBlock, createBlock: _createBlock } = Vue

      return function render(_ctx, _cache) {
        return (_openBlock(), _createBlock("h1", null, "hello "   _toDisplayString(
          (() => {
            try {
              return state
            } catch {
              return _ctx.state
            }
          })().title), 1 /* TEXT */))
      }
    })()


    // Use variables directly in the current scope, such as state.count
    return (
      (() => {
        const { resolveComponent: _resolveComponent, createVNode: _createVNode, toDisplayString: _toDisplayString, Fragment: _Fragment, openBlock: _openBlock, createBlock: _createBlock } = Vue

        return function render(_ctx, _cache) {
          const _component_Title = (() => {
            try {
              return Title;
            } catch {
              return _resolveComponent("Title");
            }
          })()

          return (_openBlock(), _createBlock(_Fragment, null, [
            _createVNode(_component_Title),
            _createVNode("div", null, _toDisplayString(
              (() => {
                try {
                  return state
                } catch {
                  return _ctx.state
                }
              })().count), 1 /* TEXT */),
            _createVNode("button", {
              onClick: _cache[1] || (_cache[1] = (...args) => (
                (() => {
                  try {
                    return handleClick(...args)
                  } catch {
                    return _ctx.handleClick(...args)
                  }
                })()))
            }, "click add 1")
          ], 64 /* STABLE_FRAGMENT */))
        }
      })()

    )
  },
};

I've written an online compiler demo: https://ruige24601.github.io/jsv-compiler/playground

avatar
Oct 7th 2020

We already support JSX. We will no invent a new kind of JSX for Vue and thus introduce a third template syntax.