Peshang Hiwa
Peshang Hiwa

Reputation: 154

How to access "this" keyword in <script setup> vue SFC

I am working on a simple scaffold for vite, vue and vuetify with typescript and I wanted to use the script setup version of SFC vue

<script setup lang="ts">

One thing that I can't figure out is how to access "this" keyword properties?

for example in my old vue projects i could write this

this.$vuetify.themes.light.colors.primary

so i had the ability to access $vuetify anywhere in the component, but now in script setup mode "this" keyword is undefined; How to access "this" properties?

Upvotes: 9

Views: 9122

Answers (2)

Kaustubh Bagwe
Kaustubh Bagwe

Reputation: 144

Using provide and inject

For e.g. I am using marcoschulte/vue3-progress package to show a loading bar at the top whenever routing happens.

According to vue3-progress docs, I can use this.$progress inside the script tag, but the this keyword is unavailable inside .

So in this scenario, I had to use provide and inject for props drilling.

In main.js or app.js (in laravel)

require('./bootstrap');

import { createApp } from 'vue'
import App from './views/App.vue'
import store from './store/index'
import router from './router'
import Vue3Progress from 'vue3-progress'

const options = {
    position: "fixed",
    height: "3px",
    color: "#9d5e32",
}

let app = createApp(App)

app.use(store)
    .use(router)
    .use(Vue3Progress, options)
    // $progress is set automatically when I import vue3-progress at top
    .provide('progressBar', app.config.globalProperties.$progress) 
    .mount('#app')

In any SFC

<template>
    <vue3-progress />
    <TopNav />
        <router-view></router-view>
    <Footer />
</template>

<script setup>

    import Header from '../components/admin/Fixed/Header.vue'
    import Footer from '../components/admin/Fixed/Footer.vue'

    import { inject } from 'vue-demi'
    import { useRouter } from 'vue-router'

    let router = useRouter()
    let progressBar = inject('progressBar')

    router.beforeEach((to, from, next) => {

        progressBar.start()
        next()
    })

    router.afterEach((to, from) => {

        progressBar.finish()
    })

</script>

Upvotes: 2

Bruno Francisco
Bruno Francisco

Reputation: 4210

The setup keyword in the script tag is a syntax sugar for:

const myComponent = createComponent({
  setup() {
    const foo = "may-the-force";
    let bar = "be-with-you";

    return {
      foo,
      bar
    }
  }
})

So naturally, in a setup function, you won't need this keyword because now you can just do:

bar = "be-not-with-you";

return {
  foo,
  bar
}

Now, when you initiated your Vuetify framework an instance is going to be kept somewhere. Something like this:

import Vue from "vue";
import { createVuetify } from 'vuetify'

Vue.use(Vuetify);

export const vuetify = createVuetify({ theme: {} });

Now that you have stored your vuetify instance somewhere you can import it just like you would do any other javascript/typescript file:

<script setup lang="ts">
import { vuetify } from "path/to/vuetify/instance";

console.log(vuetify.themes.light.colors.primary);

// You can even set dark mode if you prefer to
vuetify.framework.theme.dark = true;

</script>

Edit

I'm guessing that things are a little bit different in Vue 3. After researching a little bit you can get the current Vue instance by using getCurrentInstance

<script setup>
    import { getCurrentInstance } from 'vue'

    const app = getCurrentInstance()
    // it should be here in this instance the vuetify object with its properties
    console.log(app);
</script>

Upvotes: 6

Related Questions