众所周知,在 vue中,如果想定义一个全局变量的方法很简单,直接在 vue的原型上挂载属性或者方法即可。

但是,加上了typescript之后, Vue.prototype.$xxx = xxx  这种挂载方式就不行了。无论在哪里都访问不了挂载的内容。Vue原型上也没有。那怎么办呢?

第一种方式:插件

官方文档在 TypeScript 支持 这一项中的  增强类型以配合插件使用表示了可以用插件的方式来定义全局变量,然后用 xxx.d.ts 这种文件来声明类型。

那就开始开发插件:官方开发插件说明

插件最重要的就是 install 方法。举个最简单的例子:

testInstall.ts

const protoInstall ={

install: (Vue:any,options:any)=>{

Vue.prototype.$install= function(){

console.log('install')

};

Vue.prototype.$testData= 'testData';

}

}

exportdefault protoInstall;

(1)不要说我Vue:any,options:any 这种写法,因为我不知道这两个的类型到底是什么ヾ(。 ̄□ ̄)ツ゜゜゜

main.ts

import hhInstall from './assets/js/testInstall';

Vue.use(hhInstall);

使用的时候:

结果:

(1)可以看到,虽然报未找到该属性,或者该方法的错误,但是不影响结果。

(2)那怎么解决这个问题呢?这时就需要添加 声明文件了。

解决:

(1)在src 下新建一个 xxx.d.ts 文件  。我是在src下再新建一个type文件夹,然后再把刚才的声明文件放到 这文件夹中,方便管理。

(2)xxx 名称可以随便写,反正我写的 vue-prototype.d.ts  更清晰一点。

vue-prototype.d.ts

declare module "vue/types/vue"{

interface Vue {

$testData:string;

$install:Function;

}

}

保存后,如果未生效,再重新启动一下项目就行。然后就有类型提示了。以后如果还需要添加全局属性或者方法,在插件里面挂载之后,声明文件里面再添加类型说明。

不过我有不明白的地方:

(1) 官方文档说,确保在声明补充的类型之前导入 'vue'。我的声明文件 vue.prototype.d.ts 并未导入vue,但是没问题。为什么呢?难道是我用vue-cli3 脚手架搭建的项目,shims-vue.d.ts 这个文件已经导入就不用了吗?

(2) 这种 xxx.d.ts 文件,vue内部是怎么识别的?又是怎么处理的呢?

第二种方法:mixin混入

由于是想全局定义属性和方法,那么mixin也能实现。比如:

main.ts

const vueMixins ={

data(){return{

$testData:'mixin testData',

}

},

methods:{

$install:function(){

console.log('mixin install')

}

}

}

Vue.mixin(vueMixins)

使用:

结果:

可以看到,定义的属性 $testData 是undefined。而去看vue实例,发现挂载到 $data 里面的。但是为什么访问不了,而只有 通过  this.$data.$testData 来访问?这个我也不太清楚

相同的,出现属性不存在的问题,还是要添加 声明文件来说明一下。

用这种方式,如果定义一个构造函数在data里面,后面的方法都没提示。不太方便。

第三种方式(推荐):继承

1. 定义一个 vueBase.ts 文件,名称随意起,位置随意放。定义一个基类用于继承。

import { Vue } from 'vue-property-decorator';

export class VueBase extends Vue{

public testArr = [1,2];

public say(param:string){

console.log(this.testArr,param);

return 222;

}

}

(1) 这里面的属性或者方法,只能使用public关键字,不要使用 private;

2. 其它.ts页面使用的时候

import { Component } from 'vue-property-decorator'import { VueBase } from '@/core/base/vueBase';

@Component

export defaultclass AvatarCardPage extends VueBase{

private test = 123;

private created(){

console.log(super.testArr)

console.log(this.testArr)

console.log(super.say('super'))

console.log(this.say('this'))

}

}

(1)在派生类(子类)中使用的时候,如果要使用基类(父类)的方法,则需要调用 super 即可。

(2)如果要调用属性,则只能通过 this ,super 调用无效,这是 class类 的规则。

(3)如果子类需要自己实现constructor 构造函数的时候, 则需要调用 super() 。这里没写是因为默认会被默认添加。

这样,在其它页面使用的时候,只要在 vueBase 中定义了的 属性和方法,都能访问到,并且不用再去 新建 xxx.d.ts 等声明文件。

果然还是实践出真知,网上的大部分答案都不靠谱 (⊙﹏⊙)。

最后贴上我自己的全局事件总线代码,就是为了不想用的时候还要引入,才知道了 typescript 不能直接定义全局变量的问题。

ヾ(゚∀゚ゞ)

如果不想全局引入,那就不搞成插件的方式就行了,直接export default class xxx。

代码比较垃圾,轻喷。

assets/js/eventBus.ts

/**

* @desc 全局事件总线*/

/**

* 事件信息接口*/interface EventItem {

name:string;

fun:Function;

}/**

* 判断是否存在已经绑定的事件接口*/interface JudgeStatus{

status:boolean;

index:number

}

export class EventBusHandler{

private EventArr:EventItem[]=[];

private static _instance: EventBusHandler;

public static get instance(): EventBusHandler {if (!EventBusHandler._instance) {

EventBusHandler._instance= newEventBusHandler();

}returnEventBusHandler._instance;

}/**

* 判断是否已经存在注册的事件

* @param eventName 事件名*/private judgeHadEventAlready(eventName: string):JudgeStatus{

let status= false;

let pos= -1;this.EventArr.forEach((val,index) =>{if(val.name ===eventName){

status= true;

pos=index;

}

})return{

status:status,

index: pos

}

}/**

* 事件监听

* @param eventName 事件名

* @param func 回调函数*/public on(eventName: string, func: Function) {

const statusTarget= this.judgeHadEventAlready(eventName);//如果未监听过则添加进去

if (!statusTarget.status) {this.EventArr.push({

name:eventName,

fun:func

})

}

}/**

* 事件触发

* @param eventName 事件名

* @param arg 传入的参数。如果想传多个参数,可把 arg:any 换成 ...arg:any[]*/public emit(eventName: string, arg:any) {

const statusTarget= this.judgeHadEventAlready(eventName);if(statusTarget.status){

const func= this.EventArr[statusTarget.index].fun;this.EventArr[statusTarget.index].fun =func;

func(arg);

}else{

console.warn('暂未监听:'+eventName+ '事件');

}

}/**

* 事件移除

* @param eventName

* @param func*/public remove(eventName: string) {

const statusTarget= this.judgeHadEventAlready(eventName);if(statusTarget.status){this.EventArr.splice(statusTarget.index,1);

}else{

console.warn('未监听:'+eventName+ '事件');

}

}

}

const EventBusFunc={

install: (Vue:any,options:object)=>{

Vue.prototype.$eventBus=EventBusHandler.instance;

}

}

exportdefault EventBusFunc;

View Code

声明文件:

import {EventBusHandler} from '@/assets/js/eventBus';

declare module"vue/types/vue"{

interface Vue {

$eventBus:EventBusHandler;

}

}

main.ts 引入:

import EventBus from './assets/js/eventBus';

Vue.use(EventBus);

使用:

this.$eventBus.on('func',() =>{})this.$eventBus.emit('func','1111')this.$eventBus.remove('func')

js定义全局变量 vue页面_vue + typescript,定义全局变量或者方法相关推荐

  1. js定义全局变量 vue页面_vue.js中如何定义全局变量?

    vue.js中如何定义全局变量?下面本篇文章给大家介绍一下在 Vuejs 项目中如何定义全局变量.有一定的参考价值,有需要的朋友可以参考一下,希望对大家有所帮助. 在 Vuejs 项目中如何定义全局变 ...

  2. js定义全局变量 vue页面_vue项目中定义全局变量、函数的几种方法

    前言 在项目中,经常会复用一些变量和函数,比如用户的登录token,用户信息等.这时将它们设为全局的就显得很重要了,全局变量和全局函数之间有一些相通之处,它们其实很简单,但是有些人可能还不太了解.简单 ...

  3. js定义全局变量 vue页面_vue定义全局变量,以及方法的调用

    记录一下自己忘记的东西,省的下回到处找. 在vue项目中经常会用全局的变量,或者定义全局的方法 首先新建一个utils.js的文件,里面放上你需要的全局方法以及变量呀 举个例子 /** * 时间戳 * ...

  4. vue与外部html通信,VUE页面实现加载外部HTML方法

    VUE页面实现加载外部HTML方法 VUE页面实现加载外部HTML方法 前后端分离,后端提供了接口.但有一部分数据,比较产品说明文件,是存在其他的服务器上的.所以,在页面显示的时候,如果以页面内嵌的形 ...

  5. js定义全局变量 vue页面_使用vue.js怎么定义全局变量?

    使用vue.js怎么定义全局变量?下面本篇文章给大家介绍一下在 Vuejs 项目中如何定义全局变量.有一定的参考价值,有需要的朋友可以参考一下,希望对大家有所帮助. 一.在需要的地方引用进全局变量模块 ...

  6. js定义全局变量 vue页面_在vue项目中 实现定义全局变量 全局函数操作

    写在前面: 如题,在项目中,经常有些函数和变量是需要复用,比如说网站服务器地址,从后台拿到的:用户的登录token,用户的地址信息等,这时候就需要设置一波全局变量和全局函数,这两个设置不太难,而且有一 ...

  7. js定义全局变量 vue页面_详解Vue.js 定义全局变量的几种实现方式

    详解Vue.js 定义全局变量的几种实现方式 发布于 2020-8-11| 复制链接 本篇文章主要介绍了VUE 全局变量的几种实现方式,小妖觉得挺不错的,现在分享给大家,也给大家做个参考.一起跟随小妖 ...

  8. vue页面引入多个组件的方法

    通常我们使用的是单个文件引入,但是这样就会有很多代码是重复的,怎样才能实现"按需"引入呢? 如上图 no_started中引入no_bac1,no_bac2,no_bac3,no_ ...

  9. VUE页面实现加载外部HTML方法

    本文思路是把HTML请求以来,以v-html的形式加载到页面内部.注册全局组件[v-html-panel] 1.HtmlPanel.vue文件 1 2 3 4 5 6 7 8 9 10 11 12 1 ...

最新文章

  1. rman命令学习-tina(下)
  2. 5G 信令流程 — 5GC 的移动性管理(MM,Mobility Management)
  3. JavaScript存在的原因
  4. 【DA算法】基于DA算法的FIR滤波器的FPGA实现
  5. des解密不完整,前面几位是乱码的解决办法
  6. SVN 签出源码 Struts Spring Hibernate
  7. python云计算面试题_云计算工程师面试问题及答案解析
  8. Blazor WebAssembly 3.2.0 正式起飞,blazor 适合你吗?
  9. React开发(245):ant design form自定义验证
  10. python自定义函数的关键字_Python3.x中自定义比较函数
  11. Win10开机提示蓝屏错误ntoskrnl.exe怎么修复?
  12. 非平衡电桥电阻计算_绝缘检测电桥法中的几个重要概念
  13. POJ 2886 Who Gets the Most Candies?
  14. 周刷题第一期总结(two sum and two numbers)
  15. k2p 刷breed_斐讯路由器系列「K1-K2-K2P-K2T」-Breed刷入工具v1.1支持XP系统
  16. MapGIS格式转ArcGIS方法
  17. 阿里云天池Python训练营-打卡Task3
  18. heroku常用命令示例(三)与AWS S3互动
  19. ubuntu更新过程中出现错误:校验数字签名时出错。此仓库未被更新,下列签名无效
  20. 阿里人绝不服输,用 7 部分讲明白百亿级高并发系统(全彩版小册开源

热门文章

  1. 苹果8p电池多少毫安的_iPhone12 mini换屏幕多少钱?苹果官方更换屏幕和电池报价来了...
  2. 聊天机器人之同义变换
  3. 美好停驻,荟语酒店温柔亮相”于姑苏深处,遇锦绣江南”品牌沙龙会
  4. 记录我深深浅浅的脚印
  5. 苹果x手机防水吗_苹果XR快充伤手机吗?
  6. 解决:在 flash.net.NetStream 上找不到属性 onMetaData
  7. 读《墨菲定律》笔记—洛克定律:确定目标、专注行动
  8. wordpress搬家换域名
  9. ios android gpu,流畅秒杀iOS Android 4.0 GPU加速测试
  10. c语言十以内加减法,求助 给小学生出题,自己选加减乘除 做10题 10以内的数 然后统计分...