vuejs / rfcs

RFCs for substantial changes / feature additions to Vue core
4.87k stars 546 forks source link

The template function supports JS functions #264

Closed ZouHuaYi closed 3 years ago

ZouHuaYi commented 3 years ago

In the template I would like to use the following js function:

{# // Parsing JS syntax is supported here function() { return (hello world) } #}

{# // Parsing JS syntax is supported here function() { return (hello world) }

}

or This function only supports the render function {# h('span', null, 'hello world')

}

Justineo commented 3 years ago

Please DO read the README of this repo.

I saw this coming from a closed issue at https://github.com/vuejs/vue-next/issues/3274. If you really think your proposal deserves adoption into Vue's core, you'd better provide a better RFC document in which we can see more detailed description of your scenarios and discussion on design/drawbacks.

ZouHuaYi commented 3 years ago

Summary

The Template syntax supports JSX, JSX can be parsed inside the template.

Basic example

template syntax

<template>
  <div class="container">
    <span>hello world</span>
    <!-- here jsx -->
    {#
      (h, ctx) => {
        let a = ctx.state + 1
        return h('div', a, [])
      }
    #}
  </div>
</template>

Motivation

When I render complex tables

<template>
 <div class="container">
 <!-- tabel -->
  <ul>
    <li v-for="(item, index) in list">
       <!-- There are complex styles and logic -->
       <h1 v-if="index===1" @click="func">{{state + item.state}}</h1>
       <h2 v-if="index===2">{{state + item.state}}</h2>
       <h3 v-if="index===3">{{state + item.state}}</h3>
       <h4 v-if="index===4">{{state + item.state}}</h4>
       <h5 v-if="index===5">{{state + item.state}}</h5>
       <h6 v-if="index===6">{{state + item.state}}</h6>
    </li>  
  </ul>
 </div>
</template>
<script>
export default {
  // This has been passed through multiple components
  props: {
    func: {
      type: Function,
      default: () => {}
    },
    state: {
      type: Number,
      default: 0
    }
  } 
}
</script>

or

<template>
  <div class="container">
    <span>hello world</span>
    <!-- here jsx -->
    {#
     tempRender
    #}
  </div>
</template>

<script>
export default {
   methods: {
      tempRender (h, ctx) {
        // here return jsx render
        return h('span', 'hello world')
      }
    }
}
</script>

I know that here in H1-H6, the complex logic and style can be encapsulated into a component and then implemented through parameter passing, The props are not controlled after several times, so the props are not easy to maintain in the future

PatrykWalach commented 3 years ago

for

<template>
  <div class="container">
    <span>hello world</span>
    <!-- here jsx -->
    {#
      (h, ctx) => {
        let a = ctx.state + 1
        return h('div', a, [])
      }
    #}
  </div>
</template>

this should work

<template>
  <div class="container">
    <span>hello world</span>
    <!-- here jsx -->
    <component :is="() => {
        let a = state + 1
        return h('div', a, [])
      }"/>
  </div>
</template>

<script>
import { h } from 'vue'

export default {
  created(){
    this.h = h
  },
  state(){
    return {
      state: 1,
    }
  }
}
</script>