9

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?

4
  • Note: Vue.js questions are highly version specific and should always be tagged with [vuejs2] or [vuejs3] in addition to this tag. Commented Aug 27, 2021 at 21:37
  • It's Vue 3, i thought the SETUP word would make it clear that it is vue 3 Commented Aug 27, 2021 at 21:39
  • OK, so you are using Vuetify 3 Alpha, right ? Commented Aug 27, 2021 at 21:42
  • Yes i am using Vueify3 with the new modular createVuetify mode Commented Aug 27, 2021 at 22:19

2 Answers 2

6

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>
Sign up to request clarification or add additional context in comments.

6 Comments

I have had imported vuetify in to my component the way you explained it, but it doesn't have the properties that the previous version $vuetify had, it only have one property called install which is a function that accepts a oneof type <App>
export default createVuetify({ components, directives, theme: { themes: { light: { colors: { primary: "#41b883", background: "#35495e", error: "#41b883", info: "#41b883", secondary: "#41b883", success: "#41b883", surface: "#41b883", warning: "#3d405b", }, dark: false, variables: {}, }, }, }, });
Updated the answer. Please, see that I'm doing export const vuetify = createVuetify(). You import into your component the variable vuetify and not the vuetify framework itself.
Please take a look at screenshots to see it for yourself, i have exported the createVuetify() as you said and yet i am getting only one property as a result of that function, drive.google.com/drive/folders/…
getCurrentInstance is considered a private API, use with caution stackoverflow.com/q/72209080
|
2

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>

1 Comment

this should be the accepted answer, for multiple reasons: 1. getCurrentInstance is not documented and should not be used to replace this in Composition API. 2. Vue docs recommend to make plugins accessible (for example) with provide/inject. 3. In the main.js file you already have access to the app instance, where you can find app.config.globalProperties, which is the recommended place by Vue docs for plugin/library maintainers to install their plugins.

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.