在将代码重构为组合 API 时,我偶然发现了一个完全意想不到的问题:似乎没有任何(已记录的)方法可以从生命周期挂钩访问当前实例。
示例代码:
import { defineComponent, onMounted } from 'vue';
export default defineComponent({
setup() {
onMounted(() => {
console.log(this); // <-- will be undefined
});
},
mounted() {
console.log(this); // <-- will be the component
},
}
我花了几个小时试图找到解决方案,最终只是使用旧的选项 API 来得到我想要的。我读过的示例、教程或文档都没有在挂钩中使用
this
。
但我发现难以置信的是,只有未记录的
getCurrentInstance
才能从钩子中获取当前实例。
那么,我错过了哪位医生?
更新2.
如果需要,您可以混合使用
Composition API
和 Options API
来访问 this
。
在
this
中使用Options API
,您可以访问setup
中定义的所有对象,例如变量、方法、计算、引用等。
但是您无法访问使用
Options API
内的 setup
定义的任何内容。检查以下示例,Vue 如何混合 data
属性。
通过
data
提供的 Options API
与来自 setup
的数据混合。 setup
中的对象会覆盖 Options API
中提供的定义。
在以下示例中了解 Vue 如何混合
data
属性。
const { createApp, ref } = Vue;
const MyComponent = {
setup() {
const setupVar = ref('setupVar content')
const collisionVar = ref('content from setup')
// there is no way to access the `optionsVar` inside the `setup`
const collisionObj = ref({ setup: true })
return { setupVar, collisionVar, collisionObj }
},
data() {
return {
optionsVar: 'optionsVar content',
collisionVar: 'content from data()',
collisionObj: { options: true }
}
},
methods: {
log() {
console.log(`setupVar: ${this.setupVar}`)
console.log(`collisionVar : ${this.collisionVar}`)
console.log(`collisionObj: ${JSON.stringify(this.collisionObj)}`)
}
},
template: `<button type="button" @click="log()">log()</button>`
}
const App = {
components: {
MyComponent
}
}
const app = createApp(App)
app.mount('#app')
<div id="app">
<my-component />
</div>
<script src="https://unpkg.com/vue@3/dist/vue.global.prod.js"></script>
更新1.
这是带有组件的相同示例
const { createApp, ref, onMounted } = Vue;
const MyComponent = {
setup() {
const id = ref(Math.round(Math.random() * 100000));
const count = ref(0);
const plus = () => { count.value++; }
const minus = function() { count.value--; }
onMounted(() => {
count.value = Math.round(Math.random() * 10)
});
return {id, count, plus, minus }
},
template: `id: {{id}} <button type="button" @click="minus()">-1</button>
{{count}}
<button type="button" @click="plus()">+1</button><hr/>`
}
const App = {
components: {
MyComponent
}
}
const app = createApp(App)
app.mount('#app')
<div id="app">
<my-component v-for="i in 5" />
</div>
<script src="https://unpkg.com/vue@3/dist/vue.global.prod.js"></script>
组件中需要
this
来做什么?
如果您使用 Composition API 创建组件,那么您可以直接访问所有属性,而无需使用
this
。
这是一个非常基本的例子:
const { createApp, ref, onMounted } = Vue;
const App = {
setup() {
const count = ref(0);
const up = () => { count.value++; }
const down = function() { count.value--; }
onMounted(() => {
count.value = 10
});
return {count, up, down }
}
}
const app = createApp(App)
app.mount('#app')
<div id="app">
<button type="button" @click="down()">-1</button>
{{count}}
<button type="button" @click="up()">+1</button>
</div>
<script src="https://unpkg.com/vue@3/dist/vue.global.prod.js"></script>