我的第一个项目 :处理全局变量(解决模块化后变量无法获取的问题)
Posted 养肥胖虎
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了我的第一个项目 :处理全局变量(解决模块化后变量无法获取的问题)相关的知识,希望对你有一定的参考价值。
好家伙,
飞机大战分包分的差不多了,
但是又出现了问题:
文件目录如下:
然而关于变量
helloworld.vue完整代码
<template>
<div>
<div ref="stage"></div>
</div>
</template>
<script>
// Award,
// Bullet,
// Enemy,
// Hero,
// Loading,
// Main,
// Sky
//七个大类引进来
import Award from "./js/award"
import Bullet from "./js/bullet"
import Enemy from "./js/enemy"
import Hero from "./js/hero"
import Loading from "./js/loading"
// import Main from "./js/main"
import Sky from "./js/sky"
// import SKYY from "./js/config"
import START, STARTING, RUNNING, PAUSE, END, LOADINGING from "./js/config"
import SKY, LOADING, HERO, BULLET, E1, E2, E3, C1 from "./js/config"
import bg, copyright, pause from "./js/config"
export default
mounted()
//console测试
console.log("模块化测试")
//canvas初始化
console.log("我被执行啦")
let canvas = document.createElement(\'canvas\');
this.$refs.stage.appendChild(canvas);
canvas.width = 480;
canvas.height = 650;
canvas.ref = canvas;
canvas.style = "border: 1px solid red;"
const context = canvas.getContext("2d");
//state表示游戏的状态 取值必须是以上的五种状态
let state = START;
//score 分数变量 life 变量
let score = 0;
let life = 3;
//初始化奖励类
// class Loading
// constructor(config)
// this.frame = config.frame;
// this.img = this.frame;
// this.frameIndex = 0;
// this.width = config.width;
// this.height = config.height;
// this.x = config.x;
// this.y = config.y;
// this.speed = config.speed;
// this.lastTime = new Date().getTime();
//
// judge()
// const currentTime = new Date().getTime();
// if (currentTime - this.lastTime > this.speed)
// this.frameIndex++;
// if (this.frameIndex === 4)
// state = RUNNING;
//
// this.lastTime = currentTime;
//
//
// paint(context)
// if (this.frameIndex < 3)
// context.drawImage(this.img[this.frameIndex], this.x, this.y);
//
//
class Main
//一下全为全局变量或方法 (全局的!!)
//初始化一个天空实例
//主启动方法
maingame()
const sky = new Sky(SKY);
//初始化一个飞机界面加载实例
const loading = new Loading(LOADING);
loading.prototype =this;
//初始化一个英雄实例 英雄是会变的
let hero = new Hero(HERO);
//该变量中有所有的敌机实例
let enemies = [];
//该变量中存放所有的奖励实例
let awards = [];
//敌机产生的速率
let ENEMY_CREATE_INTERVAL = 800;
let ENEMY_LASTTIME = new Date().getTime();
function stateControl()
//为canvas绑定一个点击事件 且他如果是START状态的时候需要修改成STARTING状态
canvas.addEventListener("click", () =>
if (state === START)
state = STARTING;
);
// 为canvas绑定一个鼠标移动事件 鼠标正好在飞机图片的正中心
canvas.addEventListener("mousemove", (e) =>
let x = e.offsetX;
let y = e.offsetY;
hero.x = x - hero.width / 2;
hero.y = y - hero.height / 2;
);
// 为canvas绑定一个鼠标离开事件 鼠标离开时 RUNNING -> PAUSE
canvas.addEventListener("mouseleave", () =>
if (state === RUNNING)
state = PAUSE;
);
// 为canvas绑定一个鼠标进入事件 鼠标进入时 PAUSE => RUNNING
canvas.addEventListener("mouseenter", () =>
if (state === PAUSE)
state = RUNNING;
);
//为canvas绑定一个屏幕移动触摸点事件 触碰点正好在飞机图片的正中心
canvas.addEventListener("touchmove", (e) =>
// let x = e.pageX;
// let y = e.pageY;
console.log(e);
// let x = e.touches[0].clientX;
// let y = e.touches[0].clinetY;
let x = e.touches[0].pageX;
let y = e.touches[0].pageY;
// let x = e.touches[0].screenX;
// let y = e.touches[0].screenY;
let write1 = (document.body.clientWidth - 480) / 2;
let write2 = (document.body.clientHeight - 650) / 2;
hero.x = x - write1 - hero.width / 2;
hero.y = y - write2 - hero.height / 2;
// hero.x = x - hero.width / 2;
// hero.y = y - hero.height / 2;
console.log(x, y);
console.log(document.body.clientWidth, document.body.clientHeight);
e.preventDefault(); // 阻止屏幕滚动的默认行为
)
stateControl();
// 碰撞检测函数
//此处的碰撞检测包括
//1.子弹与敌机的碰撞
//2.英雄与敌机的碰撞
//3.英雄与随机奖励的碰撞
function checkHit()
// 遍历所有的敌机
for (let i = 0; i < awards.length; i++)
//检测英雄是否碰到奖励类
if (awards[i].hit(hero))
//当然了,这个随机奖励的样式也要删了
awards.splice(i, 1);
//清除所有的敌机
// for (let i = 0; i < enemies.length; i++)
// enemies.splice(i, 1);
//
enemies.length = 0;
for (let i = 0; i < enemies.length; i++)
//检测英雄是否撞到敌机
if (enemies[i].hit(hero))
//将敌机和英雄的destory属性改为true
enemies[i].collide();
hero.collide();
for (let j = 0; j < hero.bulletList.length; j++)
enemies[i].hit(hero.bulletList[j]);
//检测子弹是否撞到敌机
if (enemies[i].hit(hero.bulletList[j]))
//将敌机和子弹的destory属性改为true
enemies[i].collide();
hero.bulletList[j].collide();
// 全局函数 隔一段时间就来初始化一架敌机/奖励
function createComponent()
const currentTime = new Date().getTime();
if (currentTime - ENEMY_LASTTIME >= ENEMY_CREATE_INTERVAL)
let ran = Math.floor(Math.random() * 100);
if (ran < 55)
enemies.push(new Enemy(E1));
else if (ran < 85 && ran > 55)
enemies.push(new Enemy(E2));
else if (ran < 95 && ran > 85)
enemies.push(new Enemy(E3));
else if (ran > 95)
awards.push(new Award(C1));
ENEMY_LASTTIME = currentTime;
// 全局函数 来判断所有的子弹/敌人组件 "负责移动"
function judgeComponent()
for (let i = 0; i < hero.bulletList.length; i++)
hero.bulletList[i].move();
for (let i = 0; i < enemies.length; i++)
enemies[i].move();
for (let i = 0; i < awards.length; i++)
awards[i].move();
// 全局函数 来绘制所有的子弹/敌人组件 绘制score&life面板
function paintComponent()
for (let i = 0; i < hero.bulletList.length; i++)
hero.bulletList[i].paint(context);
for (let i = 0; i < enemies.length; i++)
enemies[i].paint(context);
for (let i = 0; i < awards.length; i++)
awards[i].paint(context);
context.font = "20px 微软雅黑";
context.fillStyle = "green";
context.textAlign = "left";
context.fillText("score: " + score, 10, 20);
context.textAlign = "right";
context.fillText("life: " + life, 480 - 10, 20);
//重置样式
context.fillStyle = "black";
context.textAlign = "left";
// 全局函数 来销毁所有的子弹/敌人组件 销毁掉英雄
function deleteComponent()
if (hero.destory)
life--;
hero.destory = false;
if (life === 0)
state = END;
else
hero = new Hero(HERO);
for (let i = 0; i < hero.bulletList.length; i++)
if (hero.bulletList[i].outOfBounds() || hero.bulletList[i].destory)
hero.bulletList.splice(i, 1);
for (let i = 0; i < enemies.length; i++)
if (enemies[i].outOfBounds() || enemies[i].destory)
enemies.splice(i, 1);
//当图片加载完毕时,需要做某些事情
bg.addEventListener("load", () =>
setInterval(() =>
switch (state)
case START:
sky.judge();
sky.paint(context);
let logo_x = (480 - copyright.naturalWidth) / 2;
let logo_y = (650 - copyright.naturalHeight) / 2;
context.drawImage(copyright, logo_x, logo_y);
break;
case STARTING:
sky.judge();
sky.paint(context);
loading.judge();
loading.paint(context);
break;
case RUNNING:
sky.judge();
sky.paint(context);
hero.judge();
hero.paint(context);
hero.shoot(context);
createComponent();
judgeComponent();
deleteComponent();
paintComponent();
checkHit();
break;
case PAUSE:
let pause_x = (480 - pause.naturalWidth) / 2;
let pause_y = (650 - pause.naturalHeight) / 2;
context.drawImage(pause, pause_x, pause_y);
break;
case END:
//给我的画笔设置一个字的样式
//后面写出来的字都是这个样式的
context.font = "bold 24px 微软雅黑";
context.textAlign = "center";
context.textBaseline = "middle";
context.fillText("GAME_OVER", 480 / 2, 650 / 2);
break;
, 10);
);
let main_1 = new Main()
main_1.maingame();
</script>
<style>
#stage
width: 480px;
height: 650px;
margin: 0 auto;
</style>
来看helloworld.vue中的部分代码
import Loading from "./js/loading"
/**
*
*
**/
let state = START;
const loading = new Loading(LOADING);
/**
*
*
**/
loading.judge();
loading.js
// import state from "./config"
// 初始化一个飞机界面加载类
import RUNNING from "./config";
class Loading
constructor(config)
this.frame = config.frame;
this.img = this.frame;
this.frameIndex = 0;
this.width = config.width;
this.height = config.height;
this.x = config.x;
this.y = config.y;
this.speed = config.speed;
this.lastTime = new Date().getTime();
judge()
const currentTime = new Date().getTime();
if (currentTime - this.lastTime > this.speed)
this.frameIndex++;
if (this.frameIndex === 4)
state = RUNNING;
this.lastTime = currentTime;
paint(context)
if (this.frameIndex < 3)
context.drawImage(this.img[this.frameIndex], this.x, this.y);
export default Loading
若我把Loading这个类写在Helloworld.vue中,是不会有报错的,
但我把Loading这个类写在外部的.js文件,然后再使用模块化导入,
可见,es6模块化把原先的作用域分隔开了
那么这个问题怎么解决呢?
同时我还有另外两个全局变量life(生命值)和score(分数)要处理
//state表示游戏的状态 取值必须是以上的五种状态
let state = START;
//score 分数变量 life 变量
let score = 0;
let life = 3;
只能委屈一下window了,把他们都变成全局变量
//state表示游戏的状态 取值必须是以上的五种状态
window.state = START;
//score 分数变量 life 变量
window.score = 0;
window.life = 3;
搞定,不报错了
在vue项目中 如何定义全局变量 全局函数
如题,在项目中,经常有些函数和变量是需要复用,比如说网站服务器地址,从后台拿到的:用户的登录token,用户的地址信息等,这时候就需要设置一波全局变量和全局函数
定义全局变量
原理:
设置一个专用的的全局变量模块文件,模块里面定义一些变量初始状态,用export default 暴露出去,在main.js里面使用Vue.prototype挂载到vue实例上面或者在其它地方需要使用时,引入该模块便可。
全局变量模块文件:
Global.vue文件:
<script> const serverSrc=‘www.baidu.com‘; const token=‘12345678‘; const hasEnter=false; const userSite="中国钓鱼岛"; export default userSite,//用户地址 token,//用户token身份 serverSrc,//服务器地址 hasEnter,//用户登录状态 </script>
使用方式1:
在需要的地方引用进全局变量模块文件,然后通过文件里面的变量名字获取全局变量参数值。
在text1.vue组件中使用:
<template> <div> token </div> </template> <script> import global_ from ‘../../components/Global‘//引用模块进来 export default name: ‘text‘, data () return token:global_.token,//将全局变量赋值到data里面,也可以直接使用global_.token </script> <style lang="scss" scoped> </style>
使用方式2:
在程序入口的main.js文件里面,将上面那个Global.vue文件挂载到Vue.prototype。
import global_ from ‘./components/Global‘//引用文件 Vue.prototype.GLOBAL = global_//挂载到Vue实例上面
接着在整个项目中不需要再通过引用Global.vue模块文件,直接通过this就可以直接访问Global文件里面定义的全局变量。
text2.vue:
<template> <div> token </div> </template> <script> export default name: ‘text‘, data () return token:this.GLOBAL.token,//直接通过this访问全局变量。 </script> <style lang="scss" scoped> </style>
Vuex也可以设置全局变量
定义全局函数
原理
新建一个模块文件,然后在main.js里面通过Vue.prototype将函数挂载到Vue实例上面,通过this.函数名,来运行函数。
1. 在main.js里面直接写函数
简单的函数可以直接在main.js里面直接写
Vue.prototype.changeData = function ()//changeData是函数名 alert(‘执行成功‘);
组件中调用:
this.changeData();//直接通过this运行函数
2. 写一个模块文件,挂载到main.js上面。
base.js文件,文件位置可以放在跟main.js同一级,方便引用
exports.install = function (Vue, options) Vue.prototype.text1 = function ()//全局函数1 alert(‘执行成功1‘); ; Vue.prototype.text2 = function ()//全局函数2 alert(‘执行成功2‘); ; ;
main.js入口文件:
import base from ‘./base‘//引用 Vue.use(base);//将全局函数当做插件来进行注册
组件里面调用:
this.text1(); this.text2();
上面就是如何定义全局变量 全局函数的内容了,这里的全局变量全局函数可以不局限于vue项目,vue-cli是用了webpack做模块化,其他模块化开发,定义全局变量、函数的套路基本上是差不多。上文只是对全局变量
以上是关于我的第一个项目 :处理全局变量(解决模块化后变量无法获取的问题)的主要内容,如果未能解决你的问题,请参考以下文章