vue3中getCurrentInstance不推薦使用及在<script?setup>中獲取全局內容的三種方式
在vue3中并沒有暴露出一個獲取全局方法的的接口
所以我們并不能通過 import {全局方法} from 'vue' 的方法來獲取
首先在main.js中定義全局的內容
const app = createApp(App)
app.config.globalProperties.$test = '666'
app.mount('#app')
方法一(不推薦)
vue 中的 getCurrentInstance 方法返回了 ctx 和 proxy,控制臺打印 ctx 和 proxy 發(fā)現(xiàn)和 vue2.x 中的 this 等同,習慣使用 this 的朋友可以用 proxy 進行替代。
import {defineComponent, getCurrentInstance} from 'vue'
export default defineComponent ({
setup(){
//vue3-typescript
const { proxy, ctx } = (getCurrentInstance() as ComponentInternalInstance)
//vue3-javascript
const { proxy, ctx } = getCurrentInstance()
const _this = ctx
console.log('getCurrentInstance()中的ctx:', _this)
console.log('getCurrentInstance()中的proxy:', proxy)
return {}
}
})
本例中使用 getCurrentInstance 方法區(qū)獲取
const ctx = getCurrentInstance() console.log('ctx', ctx)
這時我們就能在控制臺中看到我們定義的內容了

但是不推薦使用,不推薦原因其實在官網(wǎng)中已經(jīng)說的很明白了

官方解說: 在 setup() 內部,this 不會是該活躍實例的引用(即不指向vue實例),因為 setup() 是在解析其它組件選項之前被調用的,所以 setup() 內部的 this 的行為與其它選項中的 this 完全不同。這在和其它選項式 API 一起使用 setup() 時可能會導致混淆。因此setup函數(shù)中不能使用this。所以Vue為了避免我們錯誤的使用,直接將setup函數(shù)中的this修改成了 undefined)
我理解: 在Vue3中,setup 在生命周期 beforecreate 和 created 前執(zhí)行,此時 vue 對象還未創(chuàng)建,因此,無法使用我們在 vue2.x 常用的 this。在生產(chǎn)環(huán)境內可能會獲取不到該實例!!,而且我們確實不應該用該方法去代替this
按照魷魚須的原話就是:
Because the instance is an internal instance that exposes non-public APIs. Anything you use from that instance can technically break between any release types, since they are not subject to semver constraints.
同時也給出了應該如何解決問題:
I’m not sure why you need the setup context in nested composables, but explicitly passing arguments to composables make then less coupled to the consuming component, thus easier to understand and test in isolation.
In general a library designed to work with Composition API should expose special variables via its own composables (e.g. useRoute from vue-router) instead of the requiring the user to grab it from the instance.
主要還是 getCurrentInstance 是一個內部的API,并不是公開的API,使用內部API去實現(xiàn)一些業(yè)務功能,可能會因為后續(xù) Vue 的版本迭代而造成業(yè)務上的 BUG。并且 Vue3 的 Composition API 強調的就是業(yè)務的解耦和復用性,依賴組件實例屬性并不是一個很好的開發(fā)方式。而 vue 相關生態(tài)的使用其實就是他們內部的事情了,他們有完善的測試用例可以跑測試,但是我們并沒有,如果后續(xù)的某一個版本Vue變更了這個API,那么如果沒有經(jīng)過完整測試就部署上去的項目就會出現(xiàn)大規(guī)模的BUG反饋了。
vue3 github issu反饋截圖

魷魚須反饋截圖

方法二(推薦)
使用 Provide / Inject
v3.cn.vuejs.org/guide/compo…
在main.js中provide
app.provide('$test', '666')
在組件內獲取
import { inject } from 'vue'
const test = inject('$test')
console.log('inject的$test', test)
這樣就可以獲取到了
擴展
掛載方法 在main.js中provide
import dayjs from 'dayjs'
const formatTime = (time, format) => (time ? dayjs(time).format(format || 'YYYY-MM-DD') : '-')
app.provide('dayjs', formatTime)
在組件中獲取
const dayjs = inject('dayjs')
const formatResult = dayjs(1639014286)
console.log('dayFormat', formatResult)
方式三(不推薦 只適合應急的時候使用 因為我覺得這樣用怪怪的)
使用兩個script標簽來獲取this并保存
首先現(xiàn)在main.js中像之前一樣定義全局變量
import { createApp } from 'vue'
import App from './App.vue'
const app = createApp(App)
// 官方推薦將全局變量寫進 globalProperties下
app.config.globalProperties.myOption = 'myOption'
app.mount('#app')
然后在組件中獲取
<script>
import HelloWorld from './components/HelloWorld.vue'
import { onBeforeMount, defineComponent } from 'vue'
let that = this
export default defineComponent({
beforeCreate() {
that = this
},
})
</script>
<script setup>
onBeforeMount(() => {
console.log('that', that.myOption)
})
</script>
這樣就可以獲取到啦
在setup標簽中一定要在 onBeforeMount之后再讀取this?。?!
一些問題
為什么要創(chuàng)建兩個script標簽?
因為在setup標簽中是不綁定this的 所以只能在另一個script標簽中獲取
為什么一定要在onBeforeMount之后才能獲取呢?
因為setup的生命周期是在beforeCreate,created之前執(zhí)行的 我們在beforeCreate時保存的this,所以要在beforeCreate之后獲取,onBeforeMount是在beforeCreate之后執(zhí)行的 所以可以獲取到 note
如果按這樣寫了兩個script標簽那么就不可以在沒寫setup中再執(zhí)行setup函數(shù)
<script>
import HelloWorld from './components/HelloWorld.vue'
import { onBeforeMount, defineComponent } from 'vue'
let that = this
export default defineComponent({
beforeCreate() {
console.log('beforeCreate')
that = this
},
setup() {
// 這里面的內容不會執(zhí)行
console.log('非單標簽的setup')
}
})
</script>
<script setup>
console.log('setup')
onBeforeMount(() => {
console.log('that', that.myOption)
})
</script>
為啥
因為在標簽中寫setup本身就是一個語法糖 vue會檢驗是否有
// 這是options方式
<script>
import HelloWorld from './components/HelloWorld.vue'
export default defineComponent({
setup() {
// 這里面的內容還是不會執(zhí)行
console.log('非單標簽的setup')
}
})
</script>
// 這是<script setup>
<script setup></script>
你可能回想(會不會是因為 setup標簽放到下方 所以覆蓋了上方的setup方法呢?) 經(jīng)測試 這個執(zhí)行方式無關你放置的位置 哪怕將其放到options方式上方他仍然不會執(zhí)行!
總結
到此這篇關于vue3中getCurrentInstance不推薦使用及在<script setup>中獲取全局內容的三種方式的文章就介紹到這了,更多相關vue3在<script setup>獲取全局內容內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
解決vue中el-date-picker?type=daterange日期不回顯的問題
這篇文章主要介紹了解決vue中el-date-picker?type=daterange日期不回顯的問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2022-10-10
el-select 下拉框多選實現(xiàn)全選的實現(xiàn)
這篇文章主要介紹了el-select 下拉框多選實現(xiàn)全選的實現(xiàn),文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2019-08-08

