简体   繁体   中英

Vue convert functional component to Vue 3

I would like to migrate my Vue 2 functional component to Vue 3. I read their official docs but don't understand it.

I have for example this component:

module.exports = (name, path, ariaLabel) => `<template functional>
  <div
    :class="['main-${name}', props.width ? 'default-width' : undefined]"
  >
  <span  v-if="title">${title}</span>
  <span> hello </span>
  </div>
</template>

<script>
export default {
  name: 'test-${name}',
  props: {
    width: {
      type: [Number, String],
      default: null
    },
    title: {
      type: String,
      required: false
    },
  }
}
</script>
<style src="./style.css"/>
`

I got this far converting to Vue 3:

import { h } from 'vue'

const MyComponent = (props, context) => {
    return h(`div${props.name}`, context.attrs, context.slots)
}

MyComponent.props = {
    width: {
        type: [Number, String],
        default: null
    },
    title: {
        type: String,
        required: false
    },
}

import styles from './style.css';

export default MyComponent;

How do I properly import CSS? How would I add the nested span and the classes?

Styles

External CSS files can be imported into the file, and those styles will automatically be applied to the component:

import './MyComponent.css'

props.name

You're using props.name , which isn't declared, so make sure to add it to props :

MyComponent.props = {
  //...
  name: {
    type: String,
    required: true,
  },
}

h() Arguments

  1. The 2nd argument of h() is an object of attributes, which includes class , so you would pass the multiple class names under the class key.
  2. The 3rd argument of h() can be a string, slots, or an array of child elements, which are also created with h() , so you could nest the <span> s by passing them in an array.
import { h } from 'vue'

const MyComponent = ({ name, width, title }) =>
  h(
    'div',

    // 1
    {
      class: `main-${name} ${width && 'default-width'}`
    },

    // 2
    [
      title && h('span', null, title), // conditional on `title`
      h('span', null, ' hello ')
    ]
  )

demo

JSX

Projects generated with Vue CLI also support JSX out of the box, which might be more straightforward given how close it is to the original HTML. Here's the equivalent of the h() calls above:

const MyComponent = ({ name, width, title }) =>
  <div class={`main-${name} ${width && 'default-width'}`}>
    {title && <span>{title}</span>}
    <span> hello </span>
  </div>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM