14

With options API we can use these ways to extend components. Let's say we've 2 components.

Component1.vue

<script>
export default {
  methods: {
    init(message) {
      alert(message)
    }
  }
}
</script>

Component2.vue

<script>
    import Component1 from './Component1'
    
    export default {
      extends: Component1,
      methods: {
        showAlert() {
          // we can access Component1 'init()' method here
          this.init('Hello World!')
        }
      },
      mounted() {
        this.showAlert()
      }
    }
</script>

Now, how to make it work with composition API? I've checked that extends property still available at the documentation but there's no clear usage explanation about that.

https://v3.vuejs.org/api/options-composition.html#extends

Consider the following code with composition API.

Component1.vue

<script>
import { defineComponent, ref } from 'vue'

export default defineComponent({
  setup () {
    const init = (message) => {
      alert(message)
    }
    
    return {
      init
    }
  }
})
</script>

Component2.vue

<script>
import { defineComponent, ref, onMounted } from 'vue'
import Component1 from './Component1.vue'

export default defineComponent({
  extends: Component1,
  setup () {
    const showAlert = () => {
      // How to access 'init()' method here?
    }
    
    onMounted(() => {
      showAlert()
    })
  }
})
</script>

Thank you!

2
  • did you fix it? I think the answer was reuse the function, not reuse the component. I am facing the same problem as you. stackoverflow.com/questions/70866392/… @Muhammad Rizki A. I want to nest the public component into the parent. Commented Jan 27, 2022 at 6:22
  • what's closest to it is the extends option that you can use in defineComponent. See vuejs.org/api/options-composition.html#extends a "base class" component to extend from. Commented Aug 31, 2023 at 8:02

3 Answers 3

5

Composition api enforces the code reusability with composable function which could be used across multiple components, so create a file named useInit.js with following content :

const useInit=()=>{
     const init = (message) => {
      alert(message)
    }
    
    return {
      init
    }
}

export default useInit;

then import it in every component like:

component 1

<script>
import { defineComponent, ref } from 'vue'
import useInit from './useInit'
export default defineComponent({
  setup () {
    const {init} = useInit()
    
    return {
      init
    }
  }
})
</script>

Component 2

<script>
import { defineComponent, ref, onMounted } from 'vue'
import Component1 from './Component1.vue'
import useInit from './useInit'

export default defineComponent({

  setup () {
     const {init} = useInit()
     const showAlert = () => {
       init()
     }
    
    onMounted(() => {
      showAlert()
    })
  }
})
</script>
Sign up to request clarification or add additional context in comments.

7 Comments

Hi, thanks for your help. I think it could be a good way to achieve this. However, I'm still curious about how to accomplish this with extends property. Why it still on the documentation and how to use that with composition API? Please check this documentation link: v3.vuejs.org/api/options-composition.html#extends
In vue 3 you could use options and composition api in the same component, but you shouldn't interchange properties/methods between the options and the setup hook, and since extend is an option (belongs to options api) it doesn't get access to setup hook.
the syntax used in vue 2 is valid in version 3
Okay that's pretty clear and make sense to me. So in other words, there's no 'extends' feature if we choose to use composition API, right?
Yes, extends is used only for option api to make components reusable, for composition api there's a different approach by using composable functions which could be used in different components.
|
3

Late to the party but check this:

https://github.com/vuejs/rfcs/blob/master/active-rfcs/0009-global-api-change.md#global-api-mapping

export default defineComponent({ extends: defineComponent({ ... }) });

Also this https://github.com/pearofducks/mount-vue-component

2 Comments

This seems to be part of LegacyOptions interface, I wonder what's non-legacy option?...
I checked it again and looks like it only inherits the component options. So technically, you can't do this now with Composition API as it suggests composition instead of inheritance.
0

Its really pretty straight forward, here is my code that works great:

BaseComponent.vue

import { defineComponent } from 'vue'
 export default defineComponent({
        methods: {
...
        },
})

ChildComponent.vue

    import { defineComponent } from 'vue'
    import BaseComponent from '@/components/BaseComponent.vue'
     export default defineComponent({
     extends: BaseComponent, 
    
...
    
    })

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.