Vue 3 template ref in composable

1.7k Views Asked by At

I want to switch from Options API to Composition API and use composables in place of mixin. So far I've been using a global mixin with computed property like this:

// globalMixin.js

 computed: {
    myAlert() {
        return this.$refs.myAlertDiv;
    }
 }

Then I used this mixin when creating app:

// MyApp.js

const MyApp = {
   mixins: [globalMixin]
...
}

myAlert became MyApp's computed property and I could use it without declaring directly inside MyApp properties.

Now I want to achieve the same result with composables, let's say I have a component importing a composable:

// App.vue

<script setup>
import { useGlobalComposable} from './globalComposable.js';

const globalComposable = useGlobalComposable();

onMounted(() => {

// should work without declaring myAlert inside App.vue
console.log(globalComposable.myAlert);
})
...
</script>

Is it possible to do? If so, how should I declare myAlert template ref inside composable?

1

There are 1 best solutions below

1
On

Your useGlobalComposable function should return myAlert, like this:

const useGlobalComposable = function() { 
  
   const myAlertDiv = ....

   const myAlert = computed(() => {
        return myAlertDiv;
    });

   return {myAlert}
  }

Then you can declare myAlert in the setup block

 const { myAlert } = useComposable();   
 return { myAlert }

Note, that this.$refs from the mixin will not work directly with the Composition API. If you create a component, then you can use this to access the component properties and methods.

Here is a good article about using refs with Composition API.

Very simple working example of using a composable in setup:

 const { ref, reactive, createApp } = Vue;
 
 const useComposable = function() { 
  const test = ref(1);
  return { test }; 
 }
 
 const App = { 
   setup() {    
      const { test } = useComposable();   
      return { test }
   }
}
 
 const app = createApp(App)
 app.mount('#app')
<div id="app">
  <div>Test: {{ test }}</div>
</div>
<script src="https://unpkg.com/vue@3/dist/vue.global.prod.js"></script>