vuejs / jsx-vue2

monorepo for Babel / Vue JSX related packages
https://jsx-vue2-playground.netlify.app/
1.47k stars 96 forks source link

fix: h is not in current instance but in children #278

Closed Sorryhx closed 1 year ago

Sorryhx commented 2 years ago

background: Now our team is readying to migrate from vue2 to vue3. First, we need to migrate jsx form options to setup.

problems:

  1. project throw "unknown custom element: - did you register the component correctly" when using babel-sugar-composition-api-inject-h.
  2. css style has expired if we don't use v-deep what we used in options jsx.
  3. jsx in option's method or data will has above these problems, too.

cause: ’h‘ is lastChildrenInstance().proxy.$createElement when using 'import { h } from '@vue/composition-api', because using vue.mixin realize the 'compostion-api'. so, we need true currentInstanceH to solve the problems.

it won't work with 'babel-sugar-composition-api-inject-h'

<script>
import MyComponent from '../my-component'
export default  {
  components: { MyComponent },
  setup() {
    // because using ‘h’ method for the first time is the last mixin childrenInstance().proxy.$createElement.
    // so we need declare 'const h = getCurrentInstance().proxy.$createElement' in setup block.

    //  throw ''unknown custom element: <my-component> - did you register the component correctly" 
    const renderMyComponent = () => <my-component class="font-20">hello world</my-component>

    // it will work
    const renderMyComponent = () => <MyComponent class="font-20">hello world</my-component>

    // method or data options jsx will occur the same problems.
    // it's so sad to update old code when we using so many jsx and outbreak bug easily. 
  },
  render () {
     // old vue2 code will throw ''unknown custom element: <my-component> - did you register the component correctly" 
     //  after we enable { compositionAPI: true }. 
     // however, it run  correctly if we disable { compositionAPI: true }. 
     //  we can't compatible old jsx's code.
     // there will be easily occur many bugs and works if we force to transform kebab-case component and normal scoped
    //  css to camelCase component and  v-deep css.

     return <my-component  class="font-20"/>
  }
}
</script>
<style scoped>
// it won't work
.font-20 {
  font-size: 20px;
}
// it will work
::v-deep .font-20 {
  font-size: 40px;
} 
</style> 

@sodatea @antfu