js定义全局变量 vue页面_vue + typescript,定义全局变量或者方法
众所周知,在 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,定义全局变量或者方法相关推荐
- js定义全局变量 vue页面_vue.js中如何定义全局变量?
vue.js中如何定义全局变量?下面本篇文章给大家介绍一下在 Vuejs 项目中如何定义全局变量.有一定的参考价值,有需要的朋友可以参考一下,希望对大家有所帮助. 在 Vuejs 项目中如何定义全局变 ...
- js定义全局变量 vue页面_vue项目中定义全局变量、函数的几种方法
前言 在项目中,经常会复用一些变量和函数,比如用户的登录token,用户信息等.这时将它们设为全局的就显得很重要了,全局变量和全局函数之间有一些相通之处,它们其实很简单,但是有些人可能还不太了解.简单 ...
- js定义全局变量 vue页面_vue定义全局变量,以及方法的调用
记录一下自己忘记的东西,省的下回到处找. 在vue项目中经常会用全局的变量,或者定义全局的方法 首先新建一个utils.js的文件,里面放上你需要的全局方法以及变量呀 举个例子 /** * 时间戳 * ...
- vue与外部html通信,VUE页面实现加载外部HTML方法
VUE页面实现加载外部HTML方法 VUE页面实现加载外部HTML方法 前后端分离,后端提供了接口.但有一部分数据,比较产品说明文件,是存在其他的服务器上的.所以,在页面显示的时候,如果以页面内嵌的形 ...
- js定义全局变量 vue页面_使用vue.js怎么定义全局变量?
使用vue.js怎么定义全局变量?下面本篇文章给大家介绍一下在 Vuejs 项目中如何定义全局变量.有一定的参考价值,有需要的朋友可以参考一下,希望对大家有所帮助. 一.在需要的地方引用进全局变量模块 ...
- js定义全局变量 vue页面_在vue项目中 实现定义全局变量 全局函数操作
写在前面: 如题,在项目中,经常有些函数和变量是需要复用,比如说网站服务器地址,从后台拿到的:用户的登录token,用户的地址信息等,这时候就需要设置一波全局变量和全局函数,这两个设置不太难,而且有一 ...
- js定义全局变量 vue页面_详解Vue.js 定义全局变量的几种实现方式
详解Vue.js 定义全局变量的几种实现方式 发布于 2020-8-11| 复制链接 本篇文章主要介绍了VUE 全局变量的几种实现方式,小妖觉得挺不错的,现在分享给大家,也给大家做个参考.一起跟随小妖 ...
- vue页面引入多个组件的方法
通常我们使用的是单个文件引入,但是这样就会有很多代码是重复的,怎样才能实现"按需"引入呢? 如上图 no_started中引入no_bac1,no_bac2,no_bac3,no_ ...
- VUE页面实现加载外部HTML方法
本文思路是把HTML请求以来,以v-html的形式加载到页面内部.注册全局组件[v-html-panel] 1.HtmlPanel.vue文件 1 2 3 4 5 6 7 8 9 10 11 12 1 ...
最新文章
- rman命令学习-tina(下)
- 5G 信令流程 — 5GC 的移动性管理(MM,Mobility Management)
- JavaScript存在的原因
- 【DA算法】基于DA算法的FIR滤波器的FPGA实现
- des解密不完整,前面几位是乱码的解决办法
- SVN 签出源码 Struts Spring Hibernate
- python云计算面试题_云计算工程师面试问题及答案解析
- Blazor WebAssembly 3.2.0 正式起飞,blazor 适合你吗?
- React开发(245):ant design form自定义验证
- python自定义函数的关键字_Python3.x中自定义比较函数
- Win10开机提示蓝屏错误ntoskrnl.exe怎么修复?
- 非平衡电桥电阻计算_绝缘检测电桥法中的几个重要概念
- POJ 2886 Who Gets the Most Candies?
- 周刷题第一期总结(two sum and two numbers)
- k2p 刷breed_斐讯路由器系列「K1-K2-K2P-K2T」-Breed刷入工具v1.1支持XP系统
- MapGIS格式转ArcGIS方法
- 阿里云天池Python训练营-打卡Task3
- heroku常用命令示例(三)与AWS S3互动
- ubuntu更新过程中出现错误:校验数字签名时出错。此仓库未被更新,下列签名无效
- 阿里人绝不服输,用 7 部分讲明白百亿级高并发系统(全彩版小册开源
热门文章
- 苹果8p电池多少毫安的_iPhone12 mini换屏幕多少钱?苹果官方更换屏幕和电池报价来了...
- 聊天机器人之同义变换
- 美好停驻,荟语酒店温柔亮相”于姑苏深处,遇锦绣江南”品牌沙龙会
- 记录我深深浅浅的脚印
- 苹果x手机防水吗_苹果XR快充伤手机吗?
- 解决:在 flash.net.NetStream 上找不到属性 onMetaData
- 读《墨菲定律》笔记—洛克定律:确定目标、专注行动
- wordpress搬家换域名
- ios android gpu,流畅秒杀iOS Android 4.0 GPU加速测试
- c语言十以内加减法,求助 给小学生出题,自己选加减乘除 做10题 10以内的数 然后统计分...