如何利用vue3实现一个俄罗斯方块

目录
  • 前言
  • 游戏相关设置
    • 游戏界面设置
    • 存储还在移动的俄罗斯方块信息
    • 存储已经不能移动的俄罗斯方块信息
    • 使用之前在贪吃蛇中使用的颜色渲染工具
  • 让方块移动起来(不考虑切换方块的形态切换)
    • 检测移动的俄罗斯方块二维数组在移动后它的每个坐标点数组是否有超出范围的
    • 检测移动的俄罗斯方块二维数组在移动后它的每个坐标点数组是否会触碰到不可移动的俄罗斯方块上
    • 特殊情况(得分)
    • 移动方法
  • 切换操作书写
    • 设计检测该形状形态的方法
    • 检测z形和反z形形态的方法
    • 检测L形、反L形、三角形形态的方法
    • 设计切换方法
    • 切换L形形态(代码过多只解释一个,其余的可以看我仓库代码)
  • 单个方格组件展示
  • 总结

前言

之前写了一个贪吃蛇的demo,但是公司最近没业务还得继续摸鱼。所以趁热打铁,在下又去攒了一个俄罗斯方块。代码地址

游戏相关设置

游戏界面设置

构建一个16×25的游戏界面,使用响应式数据存储一个二维数组,该二维数据中存储着每一个有关该方格信息的数组,该数组格式为[从上到下的坐标位置,从左到右的坐标位置, 该方格颜色(0为白色,1为红色,2为绿色)]

//游戏界面(作为俄罗斯方块在各个格子上渲染颜色的依据)
let checkerboardInfo = reactive([]);

//设置游戏界面
const setCheckerboard = () =>{
  for (let i = 0; i < 25; i++) {
    for (let j = 0; j < 16; j++) {
      checkerboardInfo.push([i, j, 0])
    }
  }
}

存储还在移动的俄罗斯方块信息

可移动的俄罗斯方块一共分为7种:正方形、长方形、L形、反L形、z形、反z形、三角形,使用随机数选取每个可移动的俄罗斯方块,使用二维数组存储可移动的俄罗斯方块四个坐标点,并确保其从游戏界面中间落下(实力有限,直接将七种形态用代码穷举了(●'◡'●))

/存储当前还在坠落的方格坐标
let moveSquareCoordinate = null;

/方块类型(长方形、三角形、正方形,z字型, 反z字型,l型, 反l型)
let squareType = [0, 1, 2, 3, 4, 5, 6];

//方块类型下标
let squareTypeIndex = -1;

//随机选取方块
const randomSquareType = ()=>{
  squareTypeIndex = Math.floor(Math.random()*(7));
};

//构造方块
const setSquare = () =>{
  randomSquareType();
  switch(squareTypeIndex) {

    //长方形
    case 0:
      moveSquareCoordinate = [[0, 6], [0, 7], [0, 8], [0, 9]]
      break;

    //三角形
    case 1:
      moveSquareCoordinate = [[0, 8], [0, 9], [0, 10], [1, 9]]
      break;

    //正方形
    case 2:
      moveSquareCoordinate = [[0, 7], [0, 8], [1, 7], [1, 8]]
      break;

    //z字型
    case 3:
      moveSquareCoordinate = [[0, 7], [0, 8], [1, 8], [1, 9]]
      break;

    //反z字型
    case 4:
      moveSquareCoordinate = [[0, 8], [0, 7], [1, 7], [1, 6]]
      break;

    //l型
    case 5:
      moveSquareCoordinate = [[0, 8], [0, 9], [0, 10], [1, 8]]
      break;

    //反l型
    case 6:
      moveSquareCoordinate = [[0, 8], [0, 9], [0, 10], [1, 10]]
      break;
  }
}

存储已经不能移动的俄罗斯方块信息

当俄罗斯方块触碰到底部边界或者,触碰到不能移动的俄罗斯方块时,可移动的俄罗斯方块就会变成不可移动的方块,所以需要也需要用一个专门的数组存储

//存储当前已经稳定坠落的方块的坐标
let stabilitySquareCoordinate = [];

使用之前在贪吃蛇中使用的颜色渲染工具

//改变棋盘格子颜色([A, B]为坐标,color是需要渲染为什么颜色(0为白色,1为红色,2为绿色))
const changeCheckerboard = ([A, B], color) => {
  for (let i = 0; i < checkerboardInfo.length; i++) {
      let [x, y, num] = checkerboardInfo[i];
      if( A===x && B===y ){
        checkerboardInfo[i][2]=color;
        break
      }
    }
};

//清空棋盘颜色
const clearCheckerboard = () => {
  for (let index = 0; index < checkerboardInfo.length; index++) {
    checkerboardInfo[index][2] = 0
  }
};

让方块移动起来(不考虑切换方块的形态切换)

可移动的俄罗斯方块会一直向下移动,能通过键盘左右键控制其向左右移动,通过键盘下键加速向下移动,不能向上移动(键盘上键控制该方块形态的切换),移动时不能超过该游戏界面的范围,如果移动的俄罗斯方块触碰到不可移动的俄罗斯方块,则停止移动,并且会积累在不可移动的俄罗斯方块上

在移动之前得先设置工具函数,用于检测移动后的俄罗斯方块二维数组中存储的坐标点数组是否会超出游戏界面的范围,以及是否会触碰到不可移动的俄罗斯方块上

检测移动的俄罗斯方块二维数组在移动后它的每个坐标点数组是否有超出范围的

在范围之中则不管,不在范围之中则不允许移动

//判断是否碰到边界(arr为可移动俄罗斯方块上单个的坐标点)
const judgeBoundary = (arr) => {
  if((arr[0]<0||arr[0]>24)||(arr[1]<0||arr[1]>15)){
    return true
  };
  return false
}

检测移动的俄罗斯方块二维数组在移动后它的每个坐标点数组是否会触碰到不可移动的俄罗斯方块上

观察可知,移动的俄罗斯方块和不可移动的俄罗斯方块触碰到一起就是在它们存储的坐标点数组下标为0的值相差一,而下标为1的值相等时,该移动的俄罗斯方块变成不可移动的俄罗斯方块

特殊情况:当移动方块没碰到不可移动的方块,但是触碰到游戏界面的最底部,即存储的坐标点数组下标为0的值为24时该移动方块亦会变成不可移动的方块

//查看方块是否碰到已经存在的方格中(arr为可移动俄罗斯方块上单个的坐标点)
const judgeStabilitySquareCoordinate = (arr) =>{
  //移动到最后一格时
  if( arr[0] === 24 ){
    return true
  }

  //遍历不可移动的俄罗斯方块与该点做比较
  for (let index = 0; index < stabilitySquareCoordinate.length; index++) {
    if(stabilitySquareCoordinate[index][0]-1 === arr[0] && stabilitySquareCoordinate[index][1] === arr[1]){
      return true
    }
  };
  return false;
}

特殊情况(得分)

得分是在可移动的俄罗斯变为不可移动的俄罗斯方块发生的一个判断

如果在不可移动的俄罗斯方块二维数组中,有坐标点数组下标为0的值相同且存在16个,那么这16个点应该被删除出不可移动的俄罗斯方块二维数组,这16个点被删除后,在这些点上的坐标得向下移动一格(如下图所示)

//得分(arr为可移动俄罗斯方块上单个的坐标点)
const score = (arr)=>{
  let num = 0;
  for (let index = 0; index < stabilitySquareCoordinate.length; index++) {
    if(arr[0] === stabilitySquareCoordinate[index][0]){
      num++;
      //等于16后满足当前销毁需求(直接跳出循环减少性能消耗)
      if(num === 16){
        break;
      }
    }
  };
  if(num === 16){

    //删除已经在该数组中凑齐能得分的行数(小技巧,倒着循环数组能保证每个符合删除条件的数据都能被删除)
    for (let index = stabilitySquareCoordinate.length-1; index >-1; index--) {
      if(arr[0] === stabilitySquareCoordinate[index][0]){
        stabilitySquareCoordinate.splice(index, 1)
      }
    }

    //将所有在销毁行上面的稳定方块移动至下一行去
    for (let index = 0; index < stabilitySquareCoordinate.length; index++) {
      if(arr[0] > stabilitySquareCoordinate[index][0]){
        stabilitySquareCoordinate[index][0]++
      }
    }
  }
}

移动方法

移动就是通过监听键盘弹起事件,通过对应的keycode更改可移动的俄罗斯方块中每个坐标点的值,然后再将获取到的新的二维数组去执行之前的三个方法依次判断

//事件(方便后期摘除事件)
const listener = (event)=>{
  //只监听上下左右四个按键
  const keyCodeArr =  [37, 39, 40];
  if(keyCodeArr.includes(event.keyCode)){
    //监听方向键变化(执行方块移动方向)
    moveSquare(event.keyCode);
  }
}

//定时器(一直会有一个下移方块指令执行)
let timer = setInterval(()=>{
  moveSquare(40)
},500);

//在window上挂载事件监听器
window.addEventListener("keydown", listener);
//移动方块的指令
const moveSquare = (num) => {
  if( !isShowSquare.value ){
    return
  };

  //移动
  for (let index = 0; index < moveSquareCoordinate.length; index++) {
    switch (num) {
      //键盘对应数字如下
      //40:下;37:左;39:右;
      case 37:
        moveSquareCoordinate[index][1] = moveSquareCoordinate[index][1]-1
        break;
      case 39:
        moveSquareCoordinate[index][1] = moveSquareCoordinate[index][1]+1
        break;
      case 40:
        moveSquareCoordinate[index][0] = moveSquareCoordinate[index][0]+1
        break;
    };
  };

  //是否超过边界的标杆
  let flag1 = false;
  for (let index = 0; index < moveSquareCoordinate.length; index++) {
    if(judgeBoundary(moveSquareCoordinate[index])){
      flag1 = true;
    }
  }

  //标杆满足后方块复位
  if(flag1){
    for (let index = 0; index < moveSquareCoordinate.length; index++) {
      switch (num) {
        case 37:
          moveSquareCoordinate[index][1] = moveSquareCoordinate[index][1]+1
          break;
        case 39:
          moveSquareCoordinate[index][1] = moveSquareCoordinate[index][1]-1
          break;
        case 40:
          moveSquareCoordinate[index][0] = moveSquareCoordinate[index][0]-1
          break;
      };
    };
  }

  //能否触碰到已稳定方块的标杆
  let flag2 = false;
  let coordinate = [];
  for (let index = 0; index < moveSquareCoordinate.length; index++) {
    if(judgeStabilitySquareCoordinate(moveSquareCoordinate[index])){
      flag2 = true;
    }
  };

  //只要碰到了
  if (flag2) {

    //添加进入不移动的方块坐标数组
    for (let index = 0; index < moveSquareCoordinate.length; index++) {
      stabilitySquareCoordinate.push(moveSquareCoordinate[index]);
      if(moveSquareCoordinate[index][0]-1 === 0){
        //输了就跳出循环,不必再给已稳定的方块坐标添加新坐标了
        isFail.value = true;
        break
      }
    }

    //如果已经失败则停止移动
    if (isFail.value) {
      return
    }
    isShowSquare.value = false;

    //将移动方块中每个点坐标去做得分判断
    for (let index = 0; index < moveSquareCoordinate.length; index++) {
      score(moveSquareCoordinate[index]);
    }
  }

  //重新渲染游戏界面颜色
  clearCheckerboard();
  for (let index = 0; index < moveSquareCoordinate.length; index++) {
    changeCheckerboard(moveSquareCoordinate[index], 2)
  }
  for (let index = 0; index < stabilitySquareCoordinate.length; index++) {
    changeCheckerboard(stabilitySquareCoordinate[index], 1)
  }
};

经过一系列的操作,我们已经得到了一个可以玩的俄罗斯方块,它能够移动方块,也能得分,但是不能将移动的俄罗斯方块切换形态,十分没有游戏体验感,那就再加切换形态的操作(这个操作把我差点带走,看到这里多少给个赞呗o( ̄▽ ̄)ブ)

切换操作书写

先穷举七种形状的不同形态(如下图)

形态变化  
长方形 2种
正方形 1种
z形 2种
反z形 2种
三角形 4种
L形 4种
反L形 4种

设计检测该形状形态的方法

检测长方形形态的方法

通过判断A、B两点的下标为0是的值是否相同来返回形态

const detectionToolAboutRectangle = () => {
  if (moveSquareCoordinate[0][0] !== moveSquareCoordinate[1][0]) {
    //竖直的方块
    return 0
  }

  //横着的长方形方块
  return 1
};

检测z形和反z形形态的方法

通过判断A、B两点的下标为0是的值是否相同来返回形态

//检验工具(z字形和反z字形)
const detectionToolAboutZOr_Z = () => {
  if(moveSquareCoordinate[0][0] === moveSquareCoordinate[1][0]){
    //z字形
    return 0
  }
  //n字形
  return 1
};

检测L形、反L形、三角形形态的方法

通过判断判断A、B、C三点构成的线与D点的相对位置来判断形态,第一种形态为D点在线段ABC下方,第二种形态为D点在线段ABC左边,第三种形态为D点在线段ABC上方,第四种形态为D点在线段ABC右边,

//检验工具(三角形、l型、反l型)
const detectionToolAboutTriangle = () => {

  //判断四种形态
  if ((moveSquareCoordinate[0][0] === moveSquareCoordinate[1][0] && moveSquareCoordinate[1][0] === moveSquareCoordinate[2][0]) && moveSquareCoordinate[1][0]<moveSquareCoordinate[3][0]) {
    return 0
  }
  if ((moveSquareCoordinate[0][1] === moveSquareCoordinate[1][1] && moveSquareCoordinate[1][1] === moveSquareCoordinate[2][1]) && moveSquareCoordinate[2][1]>moveSquareCoordinate[3][1]) {
    return 1
  }
  if ((moveSquareCoordinate[0][0] === moveSquareCoordinate[1][0] && moveSquareCoordinate[1][0] === moveSquareCoordinate[2][0]) && moveSquareCoordinate[1][0]>moveSquareCoordinate[3][0]) {
    return 2
  }
  if ((moveSquareCoordinate[0][1] === moveSquareCoordinate[1][1] && moveSquareCoordinate[1][1] === moveSquareCoordinate[2][1]) && moveSquareCoordinate[2][1]<moveSquareCoordinate[3][1]) {
    return 3
  }
};

设计切换方法

需要判断其现有形态,然后判断切换后是否会超出游戏范围界面,或者触碰到不能移动,如果不超出且不触碰则切换状态

切换L形形态(代码过多只解释一个,其余的可以看我仓库代码)

由于业务水平缘故,在下直接保证每次切换形态都是向右旋转90度(如图旋转)

在每一次旋转后,都以之前的B点坐标重构方块,(没错在下直接穷举了7种方块的18个类型变化,如果有其他好方法,欢迎评论区留言,谢谢大哥)

const toggleSquareShapeAboutL= () => {

  //改变后的俄罗斯方块数组
  let arr = null;

  //满足哪种形态则将后一种形态的坐标点存储进该数组中
  switch (detectionToolAboutTriangle()) {
    case 0:
      arr = [[moveSquareCoordinate[1][0]-1,moveSquareCoordinate[1][1]],[moveSquareCoordinate[1][0],moveSquareCoordinate[1][1]],[moveSquareCoordinate[1][0]+1,moveSquareCoordinate[1][1]],[moveSquareCoordinate[1][0]-1,moveSquareCoordinate[1][1]-1]];

      //判断每个点会不会超出游戏界面或者触碰到不可移动的俄罗斯方块上
      for (let index = 0; index < arr.length; index++) {
        if(judgeBoundary(arr[index]) || judgeStabilitySquareCoordinate(arr[index])){
          return
        }
      }
      moveSquareCoordinate = arr;
      clearCheckerboard();
      for (let index = 0; index < moveSquareCoordinate.length; index++) {
        changeCheckerboard(moveSquareCoordinate[index], 2)
      }
      for (let index = 0; index < stabilitySquareCoordinate.length; index++) {
        changeCheckerboard(stabilitySquareCoordinate[index], 1)
      }
      break;
    case 1:
      arr = [[moveSquareCoordinate[1][0],moveSquareCoordinate[1][1]+1],[moveSquareCoordinate[1][0],moveSquareCoordinate[1][1]],[moveSquareCoordinate[1][0],moveSquareCoordinate[1][1]-1],[moveSquareCoordinate[1][0]-1,moveSquareCoordinate[1][1]+1]];
      for (let index = 0; index < arr.length; index++) {
        if(judgeBoundary(arr[index]) || judgeStabilitySquareCoordinate(arr[index])){
          return
        }
      }
      moveSquareCoordinate = arr;
      clearCheckerboard();
      for (let index = 0; index < moveSquareCoordinate.length; index++) {
        changeCheckerboard(moveSquareCoordinate[index], 2)
      }
      for (let index = 0; index < stabilitySquareCoordinate.length; index++) {
        changeCheckerboard(stabilitySquareCoordinate[index], 1)
      }
      break;
    case 2:
      arr = [[moveSquareCoordinate[1][0]+1,moveSquareCoordinate[1][1]],[moveSquareCoordinate[1][0],moveSquareCoordinate[1][1]],[moveSquareCoordinate[1][0]-1,moveSquareCoordinate[1][1]],[moveSquareCoordinate[1][0]+1,moveSquareCoordinate[1][1]+1]];
      for (let index = 0; index < arr.length; index++) {
        if(judgeBoundary(arr[index]) || judgeStabilitySquareCoordinate(arr[index])){
          return
        }
      }
      moveSquareCoordinate = arr;
      clearCheckerboard();
      for (let index = 0; index < moveSquareCoordinate.length; index++) {
        changeCheckerboard(moveSquareCoordinate[index], 2)
      }
      for (let index = 0; index < stabilitySquareCoordinate.length; index++) {
        changeCheckerboard(stabilitySquareCoordinate[index], 1)
      }
      break;
    case 3:
      arr = [[moveSquareCoordinate[1][0],moveSquareCoordinate[1][1]-1],[moveSquareCoordinate[1][0],moveSquareCoordinate[1][1]],[moveSquareCoordinate[1][0],moveSquareCoordinate[1][1]+1],[moveSquareCoordinate[1][0]+1,moveSquareCoordinate[1][1]-1]];
      for (let index = 0; index < arr.length; index++) {
        if(judgeBoundary(arr[index]) || judgeStabilitySquareCoordinate(arr[index])){
          return
        }
      }

      //给移动的俄罗斯方块数组重新赋值
      moveSquareCoordinate = arr;

      //重新渲染游戏界面
      clearCheckerboard();
      for (let index = 0; index < moveSquareCoordinate.length; index++) {
        changeCheckerboard(moveSquareCoordinate[index], 2)
      }
      for (let index = 0; index < stabilitySquareCoordinate.length; index++) {
        changeCheckerboard(stabilitySquareCoordinate[index], 1)
      }
      break;
  }
};

单个方格组件展示

CheckerboardItem.vue

只通过存入的方格颜色信息(方格信息数组中的第三个值)来判断当前方格显示的颜色

const props = defineProps({
  checkerboardItemInfo:Array,
});

//通过toRefs解构方格信息数组中的第三个值(只有使用toRefs才能保持该引用数据解构后的数据依然保持响应式)
let [ x, y, num] = toRefs(props.checkerboardItemInfo)

let color = ref('');

//使用监听器完成数据监听,给背景色设置不同值
watchEffect(()=>{
  switch (num.value) {
    case 0:
      color.value = 'while'
      break;
    case 1:
      color.value = 'red'
      break;
    case 2:
      color.value = 'green'
      break;
  }
})
<style lang="less" scoped>
.checkerboardItem{
  //vue3.2能在css中使用v-bind绑定响应式数据
  background-color: v-bind(color);
}
</style>

好了,俄罗斯方块搞定

总结

到此这篇关于如何利用vue3实现一个俄罗斯方块的文章就介绍到这了,更多相关vue3写俄罗斯方块内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • 使用vue.js编写蓝色拼图小游戏

    之前在网上看到<蓝色拼图>这款小游戏,作者是用jquery写的.于是便考虑能不能用vue.js优雅简单的编写出来呢? Later equals never!说干就干.首先理解游戏的规则:第一关为1*1的方块,第二关为2*2以此类推 该图为第三关3*3的方块.点击一个小方块,该方块和它相邻的方块的的颜色会从黄色变为蓝色,全部变为蓝色就过关了. 现在规则清楚了,开动吧! /*style*/ .game_bg{ background: #333; width: 600px; height: 600p

  • Vue实现开心消消乐游戏算法

    之前做过一个算法题,算法要求就是写一个开心消消乐的逻辑算法,当时也是考虑了一段时间才做出来.后来想了想,既然核心算法都有了,能不能实现一个开心消消乐的小游戏呢,于是花了两天时间做了一个小游戏出来. 效果展示# 先在这里放一个最终实现的效果,还是一个比较初级的版本,大家有什么想法欢迎评论哦 游戏规则: 初始时会给玩家十分的初始分,每拖动一次就减一分,每消除一个方块就加一分,直到最后分数为0游戏结束 任意两个方块都可以拖动 界面设计# 页面的布局比较简单,格子的数据是一个二维数组的形式,说到这里大家

  • 基于Vue.js实现数字拼图游戏

    先来看看效果图: 功能分析 当然玩归玩,作为一名Vue爱好者,我们理应深入游戏内部,一探代码的实现.接下来我们就先来分析一下要完成这样的一个游戏,主要需要实现哪些功能.下面我就直接将此实例的功能点罗列在下了: 1.随机生成1~15的数字格子,每一个数字都必须出现且仅出现一次 2.点击一个数字方块后,如其上下左右有一处为空,则两者交换位置 3.格子每移动一步,我们都需要校验其是否闯关成功 4.点击重置游戏按钮后需对拼图进行重新排序 以上便是本实例的主要功能点,可见游戏功能并不复杂,我们只需一个个攻

  • vue实现打地鼠小游戏

    本文实例为大家分享了vue实现打地鼠小游戏的具体代码,供大家参考,具体内容如下 效果图如下: 代码如下: <template> <div class="game"> <h2>打地鼠游戏</h2> <div class="wraper"> <div class="item" v-for="n in TOTAL" :key="n"> <

  • 使用vue编写一个点击数字计时小游戏

    使用vue编写一个点击数字计时小游戏,列入你在文本框中输入3,点击开始会生成一个3行3列的表格,表格数据为1-9随机排列,这时候从1开始点击,按顺序点到9,当按正确顺序点击完毕,会提示所用的时间,如果顺序没有按对,会提示游戏结束. 1.首先下载vue源码,下载地址http://cn.vuejs.org 2.jquery是在面向dom操作,而vue是面向数据操作的,所以使用vue最好不要去操作dom,尽量发挥出vue的独到之处,(如果使用过angularjs可能更容易理解) 3.建立一个普通的ht

  • 如何利用vue3实现一个俄罗斯方块

    目录 前言 游戏相关设置 游戏界面设置 存储还在移动的俄罗斯方块信息 存储已经不能移动的俄罗斯方块信息 使用之前在贪吃蛇中使用的颜色渲染工具 让方块移动起来(不考虑切换方块的形态切换) 检测移动的俄罗斯方块二维数组在移动后它的每个坐标点数组是否有超出范围的 检测移动的俄罗斯方块二维数组在移动后它的每个坐标点数组是否会触碰到不可移动的俄罗斯方块上 特殊情况(得分) 移动方法 切换操作书写 设计检测该形状形态的方法 检测z形和反z形形态的方法 检测L形.反L形.三角形形态的方法 设计切换方法 切换L

  • 利用Vue3实现一个可以用js调用的组件

    目录 前言 一.常规Vue组件 1. 组件主要代码: 2. 使用方式 3. 实现效果 二.改为js调用组件 1. 实现步骤: 2. 具体实现代码: 3. 实现效果展示 总结 前言 项目开发中基本都会用到组件库,但是设计稿样式和功能不一定和组件库相同,尤其像是消息提示弹窗.确认弹窗,各个项目各个设计师都有自己的一套风格.虽然我们可以使用组件库中的组件对其进行样式覆盖来使用.但是一些定制功能还是不容易修改,这种情况我们就会选择自定义组件,然后通过 components 属性引入页面,显式写入标签调用

  • 利用vue3+ts实现管理后台(增删改查)

    简单的管理后台基本上就是数据的增删改查.主要就是 列表 + form 表单.每个页面的逻辑基本上都相同.不同的地方就是每个页面需要调用的具体 API 及参数. 以前 vue2 的时候最简单的做法是写出来一个页面的逻辑,然后直接 copy 到各个页面中,修改 API 及参数即可.高级一点的是利用 mixin 函数,将可复用逻辑抽离,每个页面引入 mixin. vue3 之后新增了composition API.本文就是利用composition API,将可复用的逻辑抽离到composition

  • 使用Vue3实现一个Upload组件的示例代码

    通用上传组件开发 开发上传组件前我们需要了解: FormData上传文件所需API dragOver文件拖拽到区域时触发 dragLeave文件离开拖动区域 drop文件移动到有效目标时 首先实现一个最基本的上传流程: 基本上传流程,点击按钮选择,完成上传 代码如下: <template> <div class="app-container"> <!--使用change事件--> <input type="file" @ch

  • 如何利用vue3实现放大镜效果实例详解

    目录 前言 一.封装的意义 二.如何封装? 1.  准备 2.  开始封装 3. 使用 三. 效果演示 总结 前言 逛购物网站的时候,想必大家都见过鼠标放到商品上,会有一个放大的效果.今天我们就自己动手封装一个放大镜效果的全局组件,一起来看下吧~ 一.封装的意义 从技术角度 通过vue插件方式封装为全局组件,整个项目其他位置也可以使用,且使用方便 模块化开发思想,一个模块实现一个功能 用户角度 可以带来更好的浏览体验 可以看到商品的细节 二.如何封装? 1.  准备 需要用到@vueuse/co

  • 利用vue3自己实现计数功能组件封装实例

    目录 前言 一.封装的意义 二.如何封装? 1. 思路 2. 准备 2. 使用 三. 效果演示 总结 前言 本文将带你用vue3自己封装一个实现计数功能的全局组件,其应用场景相信各位一看便知,那就是购物网站中常见的数量选择模块,一起来看看如何实现哇 一.封装的意义 项目中需要用到的地方较多 模块化开发,降低了代码冗余,是开发更加高效 一次封装,到处使用 二.如何封装? 1. 思路 使用vue3中v-model来完成父子组件之间的相互传值,本文章使用vueuse/core中封装好的useVMode

  • 利用vue3+threejs仿iView官网大波浪特效实例

    目录 前言 一.效果图 二.代码 三.背景图片素材 总结 前言 Threejs可以理解为是一个web端三维引擎(渲染模型,数据可视化),如果有接触过UnralEngine 4(虚幻四)等游戏引擎的,应该很容易理解在一个三维场景必备的每一个部件(场景,渲染器,网格模型,材质,光源,色相机).好的,基础知识咱们先跳过,直接上实现的过程 一.效果图 先上最终效果图: 具体效果可参考iview官方界面iView - 一套高质量的UI组件库 大波浪效果,使用的是three.js的官方例子,需要先安装thr

  • 如何利用Vue3管理系统实现动态路由和动态侧边菜单栏

    目录 前言 动态路由 动态侧边菜单栏 总结 前言 在做Vue管理系统的时候,都会遇到的一个需求:每个用户的权限是不一样的,那么他可以访问的页面(路由),可以操作的菜单选项是不一样的,如果由后端控制,我们前端需要去实现动态路由,动态渲染侧边菜单栏. 动态路由 在本示例管理系统中,由于每个用户的权限不一样,拥有的可以访问的路由页面也不一样,用户能访问的路由页面都是后端根据权限动态配置的 我们前端需要根据后端接口返回的路由表去动态增删路由,从而生成这个用户所拥有的路由. 重点:实现动态路由api ro

  • 利用Vue3和element-plus实现图片上传组件

    目录 前言 具体代码 图片上传 上传组件 前言 element-plus 提供了 uploader 组件,但是不好定制化,所以自己又造了个轮子,实现了一个图片上传的组件,它的预期行为是: 1.还没上传图片时,显示上传卡片 2.上传图片时显示进度条,隐藏上传卡片 3.上传成功时显示图片缩略图,上传失败则显示失败提示 4.支持上传图片的预览和删除 具体如下图所示: 具体代码 图片上传 这里使用的图床是牛图网,无需注册,貌似也没有图片大小的限制,但是请不要上传违规图像. <code>import a

随机推荐