在 Vue.js 3 setup() 中访问 this.$root
Access this.$root in Vue.js 3 setup()
在 Vue 2 中,您可以在 created
挂钩中访问 this.$root
。在 Vue 3 中,所有会进入 created
钩子的东西现在都进入了 setup()
.
在 setup()
中我们无法访问 this
,那么,我们如何访问根实例上的任何内容?
说,我在根实例上设置了一个 属性:
const app = createApp(App).mount('#app');
app.$appName = 'Vue3';
我可以使用 this.$root.$appName
从 mounted()
访问 this
,我如何在 setup()
中执行此操作?
更新
我可以访问它,如果我 import
它:
import app from '@/main';
...
setup() {
console.log(app.$appName) // Vue3
但是,如果我必须对每个文件都这样做,这会很麻烦。
更新 2
另一种解决方法是在 App.vue
中使用 provide()
,然后在任何其他组件中使用 inject()
:
setup() {
provide('$appName', 'Vue3')
setup() {
inject('$appName') // Vue3
看来你需要provide / inject。在你的 App.vue
:
import { provide } from 'vue';
export default {
setup() {
provide('appName', 'vue3')
}
}
或provide
它与你的app
:
const app = createApp(App);
app.mount('#app');
app.provide('appName', 'Vue3');
然后在您要访问此变量的任何子组件中,inject
它:
import { inject } from 'vue'
export default {
setup() {
const appName = inject('appName');
}
}
你可以在 vue 3 中定义 global property :
app.config.globalProperties.appName= 'vue3'
使用 setup
(组合 api),您可以使用 getcurrentinstance 访问 属性:
import { getCurrentInstance } from 'vue'
...
setup() {
const app= getCurrentInstance()
console.log(app.appContext.config.globalProperties.appName)
由于您仍然可以使用选项 api,您可以简单地执行以下操作:
mounted(){
console.log(this.appName)
}
对于想知道如何在 setup()
中访问 this
的任何人,一种方法是将 this
设置为 created()
挂钩中的记忆变量并使用 nextTick()
访问它:
const app = createApp(App);
app.config.globalProperties.$appName = 'Hello!';
<script>
import { nextTick } from 'vue';
let self;
export default {
name: 'HelloWorld',
setup() {
nextTick(() => console.log(self.$appName)); // 'Hello!'
},
created() {
self = this;
},
};
</script>
在我看来是更好的做法,但是,这只是另一种方式。
如果您只想将任何模板中的 {{ appName }}
替换为 'Vue 3'
(字符串),而无需导入任何内容,最干净的方法是使用 config.globalProperties,如其他答案建议:
const app = createApp(App).mount('#app');
app.config.globalProperties.appName = 'Vue 3'
但是,您应该尽量不要过度使用这个模式。它违背了推动 Composition 发展的可重用性和模块化原则 API.
你应该避免污染的主要原因 globalProperties
是因为它在 Vue3 应用程序中充当污染场,所以许多插件开发者可能决定使用它来提供他们的插件实例。 (显然,没有人会命名插件 appName
,因此您 运行 在这种特殊情况下没有风险)。
推荐的全球化替代方法是导出 useStuff()
函数。
在你的情况下:
export function useAppName () { return 'Vue 3' }
// or even:
export const useAppName = () => 'Vue 3'
在任何组件中:
import { useAppName } from '@/path/to/function'
setup () {
const appName = useAppName()
return {
appName // make it available in template and hooks
}
}
优点:
- 它使用组合 API 命名约定
- 当共享比原语更复杂的东西时(可以是一个模块、一组函数、一项服务等...)所有类型 是开箱即用的推断。这在
setup()
函数中特别有用。
- 您只在需要公开的地方公开和确定
stuff
的范围,而不是在应用的每个组件中公开。另一个优点是:如果你只在 setup()
函数中需要它,你不必将它暴露给模板或钩子。
使用随机(但真实)插件的示例:
创建插件文件(即:/plugins/gsap.ts
):
import gsap from 'gsap'
import ScrollToPlugin from 'gsap/ScrollToPlugin'
// configure the plugin globally
gsap.registerPlugin(ScrollToPlugin)
export function useGsap () {
return gsap
}
在任何组件中:
import { defineComponent } from 'vue'
import { useGsap } from '@/plugins/gsap'
export defineComponent({
setup () {
const gsap = useGsap()
// gsap here is typed correctly (if the plugin has typings)
// no need for casting
return {
gsap // optionally provide it to hooks and template
} // if needed outside setup()
}
})
在 Vue 2 中,您可以在 created
挂钩中访问 this.$root
。在 Vue 3 中,所有会进入 created
钩子的东西现在都进入了 setup()
.
在 setup()
中我们无法访问 this
,那么,我们如何访问根实例上的任何内容?
说,我在根实例上设置了一个 属性:
const app = createApp(App).mount('#app');
app.$appName = 'Vue3';
我可以使用 this.$root.$appName
从 mounted()
访问 this
,我如何在 setup()
中执行此操作?
更新
我可以访问它,如果我 import
它:
import app from '@/main';
...
setup() {
console.log(app.$appName) // Vue3
但是,如果我必须对每个文件都这样做,这会很麻烦。
更新 2
另一种解决方法是在 App.vue
中使用 provide()
,然后在任何其他组件中使用 inject()
:
setup() {
provide('$appName', 'Vue3')
setup() {
inject('$appName') // Vue3
看来你需要provide / inject。在你的 App.vue
:
import { provide } from 'vue';
export default {
setup() {
provide('appName', 'vue3')
}
}
或provide
它与你的app
:
const app = createApp(App);
app.mount('#app');
app.provide('appName', 'Vue3');
然后在您要访问此变量的任何子组件中,inject
它:
import { inject } from 'vue'
export default {
setup() {
const appName = inject('appName');
}
}
你可以在 vue 3 中定义 global property :
app.config.globalProperties.appName= 'vue3'
使用 setup
(组合 api),您可以使用 getcurrentinstance 访问 属性:
import { getCurrentInstance } from 'vue'
...
setup() {
const app= getCurrentInstance()
console.log(app.appContext.config.globalProperties.appName)
由于您仍然可以使用选项 api,您可以简单地执行以下操作:
mounted(){
console.log(this.appName)
}
对于想知道如何在 setup()
中访问 this
的任何人,一种方法是将 this
设置为 created()
挂钩中的记忆变量并使用 nextTick()
访问它:
const app = createApp(App);
app.config.globalProperties.$appName = 'Hello!';
<script>
import { nextTick } from 'vue';
let self;
export default {
name: 'HelloWorld',
setup() {
nextTick(() => console.log(self.$appName)); // 'Hello!'
},
created() {
self = this;
},
};
</script>
如果您只想将任何模板中的 {{ appName }}
替换为 'Vue 3'
(字符串),而无需导入任何内容,最干净的方法是使用 config.globalProperties,如其他答案建议:
const app = createApp(App).mount('#app');
app.config.globalProperties.appName = 'Vue 3'
但是,您应该尽量不要过度使用这个模式。它违背了推动 Composition 发展的可重用性和模块化原则 API.
你应该避免污染的主要原因 globalProperties
是因为它在 Vue3 应用程序中充当污染场,所以许多插件开发者可能决定使用它来提供他们的插件实例。 (显然,没有人会命名插件 appName
,因此您 运行 在这种特殊情况下没有风险)。
推荐的全球化替代方法是导出 useStuff()
函数。
在你的情况下:
export function useAppName () { return 'Vue 3' }
// or even:
export const useAppName = () => 'Vue 3'
在任何组件中:
import { useAppName } from '@/path/to/function'
setup () {
const appName = useAppName()
return {
appName // make it available in template and hooks
}
}
优点:
- 它使用组合 API 命名约定
- 当共享比原语更复杂的东西时(可以是一个模块、一组函数、一项服务等...)所有类型 是开箱即用的推断。这在
setup()
函数中特别有用。 - 您只在需要公开的地方公开和确定
stuff
的范围,而不是在应用的每个组件中公开。另一个优点是:如果你只在setup()
函数中需要它,你不必将它暴露给模板或钩子。
使用随机(但真实)插件的示例:
创建插件文件(即:/plugins/gsap.ts
):
import gsap from 'gsap'
import ScrollToPlugin from 'gsap/ScrollToPlugin'
// configure the plugin globally
gsap.registerPlugin(ScrollToPlugin)
export function useGsap () {
return gsap
}
在任何组件中:
import { defineComponent } from 'vue'
import { useGsap } from '@/plugins/gsap'
export defineComponent({
setup () {
const gsap = useGsap()
// gsap here is typed correctly (if the plugin has typings)
// no need for casting
return {
gsap // optionally provide it to hooks and template
} // if needed outside setup()
}
})