JuniorTour / vue-template-babel-compiler

Enable Optional Chaining(?.), Nullish Coalescing(??) and many new ES syntax for Vue.js SFC based on Babel
https://www.npmjs.com/package/vue-template-babel-compiler
118 stars 9 forks source link

[Resolved Question] functional component usage #10

Open vip30 opened 2 years ago

vip30 commented 2 years ago

Description

Filename: Functional.vue

<template functional>
<div>
    {{ props.msg }}
</div>
</template>

<script lang="ts">
import Vue from 'vue';

export default Vue.extend({
  name: 'Functional',
  props: {
    msg: String,
  },
});
</script>

Current behavior

Throw error message

vue.runtime.esm.js?2b0e:619 [Vue warn]: Error in render: "TypeError: Cannot read properties of undefined (reading '$createElement')"

found in

---> <App> at src/App.vue
       <Root>
warn @ vue.runtime.esm.js?2b0e:619
vue.runtime.esm.js?2b0e:1897 TypeError: Cannot read properties of undefined (reading '$createElement')
    at render (Functional.vue?09b6:3)
    at options.render (index.js?6435:83)
    at createFunctionalComponent (vue.runtime.esm.js?2b0e:3077)
    at createComponent (vue.runtime.esm.js?2b0e:3250)
    at _createElement (vue.runtime.esm.js?2b0e:3443)
    at createElement (vue.runtime.esm.js?2b0e:3374)
    at vm._c (vue.runtime.esm.js?2b0e:3512)
    at Proxy.render (App.vue?17b1:20)
    at VueComponent.Vue._render (vue.runtime.esm.js?2b0e:3569)
    at VueComponent.updateComponent (vue.runtime.esm.js?2b0e:4081)

Expected behavior

Can be used

vip30 commented 2 years ago

Found that if change filename to Functional.functional.vue, it works

JuniorTour commented 2 years ago

Found that if change filename to Functional.functional.vue, it works

Yes, we have to rename functional component .vue file to contain .functional mark.

So that this lib can detect functional component.

You can customize the mark by functionalComponentFileIdentifier option :

// where you config to use vue-template-babel-compiler, eg: vue.config.js
            .tap(options => {
                options.functionalComponentFileIdentifier = 'whateverYouWantToMarkFunctionalComponentFile'
                options.compiler = require('vue-template-babel-compiler')
                return options
            })

Sorry for the inconvenience, I will update Doc to address. Thank you for your feedback~

Mrzhangqc commented 2 years ago

Have the same problem

JuniorTour commented 2 years ago

Have the same problem

@Mrzhangqc We have to rename functional component .vue file to contain .functional mark.

If you have any good idea, welcome for Pull Request.


We should be able to know if a .vue file is or not functional component.

But we can NOT get this from options: image

I implement this logic in: https://github.com/JuniorTour/vue-template-babel-compiler/blob/09211ec7ca40b500eb15ea2d2b5233cc74e739cb/src/templateCompiler.js#L33-L34

jakedowns commented 2 years ago

if this isn't in the documentation / readme, it might be good to add it there

oh nvm, found the doc here https://github.com/JuniorTour/vue-template-babel-compiler/blob/main/doc/Usage.md#1-Functional-Component-Usage

thanks for a great package, and for posting this question / answer- helped me out. thought i'd have to revert my optional chaining. glad i can keep it by just renaming files to .functional

odd that you can't introspect into the component definition at all to find the .functional=true flag

maybe it's different in vue 2 vs. vue 3?

JuniorTour commented 2 years ago

@jakedowns Thanks for your support!

As far as I know, Vue 3 also use filename mark to identify web component:

... end your component file name with .ce.vue: https://vuejs.org/guide/extras/web-components.html#building-custom-elements-with-vue

So currently, I think add mark to file name is an acceptable solution.

But if anyone has any idea, welcome for discussion!