摘要
在vue3中并没有暴露出一个获取全局方法的的接口
所以我们并不能通过 import {全局方法} from 'vue' 的方法来获取
首先在main.js中定义全局的内容
const app = createApp(App)
app.config.globalProperties.$test = '666'
app.mount('#app')
方法一(不推荐)
-
使用
getCurrentInstance
方法区获取 具体获取方法 // v3官网文档说是只能在生命周期内执行 但是setup其实也是一个生命周期 执行顺序在挂载之前 const ctx = getCurrentInstance() console.log('ctx', ctx)
这时我们就能在控制台中看到我们定义的内容了
不推荐原因
其实在官网中已经说的很明白了 v3.cn.vuejs.org/api/composi…
在生产环境内可能会获取不到该实例!!,而且我们确实不应该用该方法去代替this
方法二(推荐)
-
使用 Provide / Inject
在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并保存
首先现在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!!!
一些问题
- 为什么要创建两个script标签?
- 因为在setup标签中是不绑定this的 所以只能在另一个script标签中获取
- 为什么一定要在onBeforeMount之后才能获取呢?
- 因为setup的生命周期是在beforeCreate,created之前执行的 我们在beforeCreate时保存的this,所以要在beforeCreate之后获取,onBeforeMount是在beforeCreate之后执行的 所以可以获取到 note
- 如果按这样写了两个script标签那么就不可以在没写setup中再执行setup函数
<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() {
// 这里面的内容不会执行
console.log('非单标签的setup')
}
})
</script>
<script setup>
console.log('setup')
onBeforeMount(() => {
console.log('that', that.myOption)
})
</script>
- 为啥
- 因为在标签中写setup本身就是一个语法糖 vue会检验是否有<script setup> 如果有,他将会执行执行其中的内容,并替代 options方式中的setup。也就是说 哪怕<script setup>中没有任何内容 只要有这个标签存在,他都不会执行options方式中的setup方法。
// 这是options方式
<script>
import HelloWorld from './components/HelloWorld.vue'
export default defineComponent({
setup() {
// 这里面的内容还是不会执行
console.log('非单标签的setup')
}
})
</script>
// 这是<script setup>
<script setup></script>
你可能回想(会不会是因为 setup标签放到下方 所以覆盖了上方的setup方法呢?) 经测试 这个执行方式无关你放置<script setup></script>的位置 哪怕将其放到options方式上方他仍然不会执行!