Vue是如何访问到Date这种全局(window)的内置对象的。

这篇博客探讨了在Vue中如何访问到全局的Date对象但无法直接调用window内置函数的问题。Vue官方指出,只有全局变量白名单内的对象可以直接使用,如Date。在示例代码中,{{Date.now()}

今天遇到了一个问题,关于Vue是如何访问到Date这种全局window的内置对象的。

我们都知道Date是window的一个内置对象,而alert()是window的一个内置函数,为什么能访问到内置对象,却不能访问到window的内置函数呢?

在Vue官方里有这样一句话
在这里插入图片描述
意思是说,只能访问到,全局变量列在白名单里的一些对象。
值得注意的是,访问的时候我们直接用就行了,不要在前面加上window,因为这样回默认是从vm实例对象上找window这个属性。

 <div id="root">
        <h2>今天天气很不错, {{Date.now()}}</h2>
        <button @click="alert('你好')">切换天气</button>
    </div>

    <script>
        const vm = new Vue({
            el: '#root',
        })
    </script>

Thanks for watching💕

<think>我们正在讨论的是Vue3中如何将变量或方法绑定到window全局对象上。注意,这与Vue全局属性(globalProperties)不同,globalProperties是在Vue实例内部通过this访问的,而window对象是浏览器全局对象,在任何地方都可以通过window访问。 根据引用[2]和[4],我们知道了在Vue3中如何设置全局属性(通过app.config.globalProperties)和通过provide/inject来提供全局变量和方法。但是,这些都是在Vue应用内部的全局,而不是挂载到window对象上。 要将变量或方法挂载到window对象上,实际上与Vue无关,因为window是浏览器环境下的全局对象。我们可以在任何地方直接给window对象赋值。但是,在Vue项目中,我们通常会在入口文件(如main.js)中,或者某个组件的生命周期钩子中(如mounted)进行挂载。 需要注意的是,在Vue3的setup语法中,我们通常不会使用this,因此直接操作window对象即可。 下面我将介绍两种常见的方式: ### 方式1:在入口文件(main.js)中挂载 在创建Vue应用之前或之后,我们可以直接将需要全局的方法或变量挂载到window上。 例如,在main.js中: ```javascript import { createApp } from 'vue' import App from './App.vue' // 定义一个方法或变量 const myGlobalMethod = () => { console.log('This is a global method on window') } // 挂载到window window.myGlobalMethod = myGlobalMethod const app = createApp(App) app.mount('#app') ``` 这样,在应用的任何地方(包括非Vue模块)都可以通过`window.myGlobalMethod`来调用这个方法。 ### 方式2:在组件中挂载 如果只需要在某个组件中使用,或者需要等待组件挂载后再挂载到window,可以在组件的`setup`函数或`mounted`生命周期钩子中进行。 例如: ```vue <script> import { onMounted } from 'vue' export default { setup() { const myMethod = () => { console.log('Component method mounted to window') } onMounted(() => { // 将方法挂载到window window.myMethod = myMethod }) // 注意:如果组件被卸载,最好清理掉挂载到window上的方法,以免造成内泄漏或方法冲突 // 可以在onUnmounted钩子中清理 } } </script> ``` ### 注意事项 1. 避免污染全局命名空间:不要过度使用window对象,因为可能会与其他库冲突。 2. 如果使用TypeScript,你可能需要扩展Window接口以避免类型错误。例如: ```typescript declare global { interface Window { myGlobalMethod: () => void } } ``` 3. 在组件卸载时,如果挂载到window上的方法或变量不再需要,应该将其移除,以避免潜在的问题。 ### 与Vue全局属性的区别 - `app.config.globalProperties` 添加的属性只能在Vue实例内部通过`this`访问(在组合式API中,可以通过`getCurrentInstance()`获取当前实例,然后通过`proxy`访问,但不推荐,引用[3]提到长期方案是使用provide/inject或Pinia)。 - 而挂载到`window`上则可以在任何地方(包括非VueJavaScript代码)访问。 ### 示例 假设我们有一个工具函数,希望在任何地方都能通过window访问,可以这样: **utils/myGlobal.js** ```javascript export function sayHello() { console.log('Hello from window!') } ``` **main.js** ```javascript import { createApp } from 'vue' import App from './App.vue' import { sayHello } from './utils/myGlobal' // 挂载到window window.sayHello = sayHello const app = createApp(App) app.mount('#app') ``` 然后,在任意地方(比如浏览器的控制台)都可以调用`window.sayHello()`。 ### 总结 在Vue3中,将变量或方法绑定到window全局对象上,实际上就是直接给window对象赋值。这与Vue全局属性(globalProperties)不同,它是在浏览器全局作用域上,而不是Vue应用内部。 §§相关问题§§ 1. Vue3中如何通过`app.config.globalProperties`添加全局属性?它与挂载到window上有什么区别? 2.Vue3中,如何避免在window上挂载过多全局变量导致命名冲突? 3.Vue3的TypeScript项目中,如何扩展Window接口的类型定义?</think>在 Vue3 中将变量或方法绑定到 window 全局对象上,可以通过以下方式实现: ### 方法 1:直接在入口文件挂载 在 `main.js/ts` 中直接挂载到 window 对象: ```javascript import { createApp } from 'vue' import App from './App.vue' // 定义要全局暴露的方法/变量 const globalMethod = () => console.log('Global method called') const globalVar = { key: 'value' } // 挂载到 window 对象 window.$myGlobalMethod = globalMethod window.$myGlobalVar = globalVar const app = createApp(App) app.mount('#app') ``` ### 方法 2:通过插件封装(推荐) 创建 `global-window-plugin.js`: ```javascript export default { install: (app) => { // 定义要暴露的全局对象 const globals = { utils: { formatDate: (date) => new Date(date).toLocaleString(), deepClone: (obj) => JSON.parse(JSON.stringify(obj)) }, config: { API_BASE: import.meta.env.VITE_API_BASE } } // 挂载到 window 对象 window.$vueGlobals = globals } } ``` 在 `main.js` 中使用插件: ```javascript import { createApp } from 'vue' import App from './App.vue' import globalWindowPlugin from './plugins/global-window-plugin' const app = createApp(App) app.use(globalWindowPlugin) // 挂载全局对象window app.mount('#app') ``` ### 使用示例 在任何组件或 JS 文件中: ```javascript // 调用全局方法 window.$vueGlobals.utils.formatDate(new Date()) // 访问全局变量 console.log(window.$vueGlobals.config.API_BASE) ``` ### 注意事项 1. **命名空间规范** 使用特定前缀如 `$vueGlobals` 避免污染全局命名空间 2. **类型安全(TS 项目)** 扩展 Window 接口类型: ```typescript // global.d.ts declare interface Window { $vueGlobals: { utils: { formatDate: (date: Date) => string deepClone: <T>(obj: T) => T } config: { API_BASE: string } } } ``` 3. **使用限制** - 仅适用于浏览器环境(SSR 不可用) - 避免在组件模板中直接使用 - 优先考虑 Vue 的 provide/inject 或 Pinia 状态管理[^3] 4. **安全建议** 敏感数据(如 API 密钥)不应暴露在全局对象中,可通过环境变量注入: ```javascript window.$vueGlobals.config.API_BASE = import.meta.env.VITE_API_BASE ``` ### 替代方案比较 | 方式 | 作用域 | 典型用例 | |------|--------|----------| | `window` 挂载 | 全局 (任何 JS访问) | 与第三方库集成,调试工具 | | `app.config.globalProperties` | Vue 实例内部 | 全局组件方法/工具[^2] | | `provide/inject` | 组件树作用域 | 主题配置,多级组件通信 | | `Pinia(Vuex)` | 状态管理 | 跨组件数据共享[^3] | > 最佳实践:优先使用 Vue 生态的全局方案(provide/inject 或 Pinia),仅在需要与外部脚本交互时使用 window 挂载[^4]。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值