手把手带你使用Vue实现一个图片水平瀑布流插件

2023-05-16

如何使用Vue实现一个图片水平瀑布流插件?这里给大家分享我在网上总结出来的一些知识,希望对大家有所帮助。

一.需求来源

今天碰到了一个需求,需要在页面里,用水平瀑布流的方式,将一些图片进行加载,这让我突然想起我很久以前写的一篇文章《JS两种方式实现水平瀑布流布局》

但是有个问题,这个需求是Vue项目的,那没办法,这里给大家分享下我的开发过程,项目主体用的是之前在学习的CRMEB的后端框架来开发,UI使用iView-UI,其余的场景与其他的vue项目一致。【相关推荐:vuejs视频教程】

二.逻辑设想

如果不是vue环境,我们的逻辑为

1.获取所有的p元素
2.获取盒子的宽度,宽度都是相同,高度不同
3.在浮动布局中每一行的盒子个数不固定,是根据屏幕宽度和盒子宽度决定
4.获取屏幕宽度
5.求出列数,屏幕宽度 / 盒子宽度 取整
6.瀑布流最关键的是第二行的盒子的排布方式,通过获取第一行盒子中最矮的一个的下标,绝对定位,top是最矮盒子的高度,left是最矮盒子的下标 * 盒子的宽度
7.循环遍历所有的盒子,通过列数找到第一行所有的盒子,将第一行盒子的高度放入数组,再取出数组中最小的一个的下标,就是第6步思路的第一行盒子中最矮盒子的下标。
8.循环继续,第二行第一个盒子,通过绝对定位,放进页面。
9.关键,需要将数组中最小的值加上放进的盒子的高度
10.继续循环,遍历所有
11.如果想要加载更多,需要判断最后一个盒子的高度和页面滚动的距离,再将数据通过创建元素,追加进页面,再通过瀑布流布局展示

但如果是Vue项目,我们可以把逻辑归结为以下几步

1.获取屏幕宽度
2..获取盒子的宽度,宽度都是相同,高度不同
3.在浮动布局中每一行的盒子个数不固定,是根据屏幕宽度和盒子宽度决定
4.求出列数,屏幕宽度 / 盒子宽度 取整
5.瀑布流最关键的是第二行的盒子的排布方式,通过获取第一行盒子中最矮的一个的下标,绝对定位,top是最矮盒子的高度,left是最矮盒子的下标 * 盒子的宽度
6.继续循环,遍历所有
7.如果想要加载更多,需要判断最后一个盒子的高度和页面滚动的距离,再将数据通过创建元素,追加进页面,再通过瀑布流布局展示

三.最终效果图片

四.代码分析

先看下我的html部分

<template>
  <div class="tab-container" id="tabContainer">
    <div class="tab-item" v-for="(item, index) in pbList" :key="index">
      <img :src="item.url" />
    </div>
  </div>
</template>
 
<style scoped>
* {
  margin: 0;
  padding: 0;
}
/* 最外层大盒子 */
.tab-container {
  padding-top: 20px;
  position: relative;
}
/* 每个小盒子 */
.tab-container .tab-item {
  position: absolute;
  height: auto;
  border: 1px solid #ccc;
  box-shadow: 0 2px 4px rgba(0, 0, 0, .12), 0 0 6px rgba(0, 0, 0, .04);
  background: white;
  /* 元素不能中断显示 */
  break-inside: avoid;
  text-align: center;
}
.tab-container .tab-item img {
  width: 100%;
  height: auto;
  display: block;
}
</style>

核心js部分

<script>
export default {
  name:'compList',
  props:{
    pbList:{
      type:Array,
      default:()=>{return []}
    }
  },
  data() {
    return {
    };
  },
  mounted() {
    this.$nextTick(()=>{
      this.waterFall("#tabContainer", ".tab-item"); //实现瀑布流
    })
  },
  methods: {
    waterFall(
        wrapIdName,
        contentIdName,
        columns = 5,
        columnGap = 20,
        rowGap = 20
    ) {
      // 获得内容可用宽度(去除滚动条宽度)
      const wrapContentWidth =
          document.querySelector(wrapIdName).offsetWidth;
 
      // 间隔空白区域
      const whiteArea = (columns - 1) * columnGap;
 
      // 得到每列宽度(也即每项内容宽度)
      const contentWidth = parseInt((wrapContentWidth - whiteArea) / columns);
 
      // 得到内容项集合
      const contentList = document.querySelectorAll(contentIdName);
 
      // 成行内容项高度集合
      const lineConentHeightList = [];
 
      for (let i = 0; i < contentList.length; i++) {
        // 动态设置内容项宽度
        contentList[i].style.width = contentWidth + "px";
 
        // 获取内容项高度
        const height = contentList[i].clientHeight;
 
        if (i < columns) {
          // 第一行按序布局
          contentList[i].style.top = "0px";
          contentList[i].style.left = contentWidth * i + columnGap * i + "px";
 
          // 将行高push到数组
          lineConentHeightList.push(height);
        } else {
          // 其他行
          // 获取数组最小的高度 和 对应索引
          let minHeight = Math.min(...lineConentHeightList);
          let index = lineConentHeightList.findIndex(
              (listH) => listH === minHeight
          );
 
          contentList[i].style.top = minHeight + rowGap +"px";
          contentList[i].style.left = (contentWidth + columnGap) * index + "px";
 
          // 修改最小列的高度 最小列的高度 = 当前自己的高度 + 拼接过来的高度 + 行间距
          lineConentHeightList[index] += height + rowGap;
        }
      }
    },
  },
};
</script>

这里要给大家提个醒,在当插件使用的时候,我们需要用this.$nextTick()来进行页面初始化,因为方法成功的前提是要等页面初始化加载完毕后才能进行获取和计算

总体插件代码为:

<template>
  <div class="tab-container" id="tabContainer">
    <div class="tab-item" v-for="(item, index) in pbList" :key="index">
      <img :src="item.url" />
    </div>
  </div>
</template>
 
<script>
export default {
  name:'compList',
  props:{
    pbList:{
      type:Array,
      default:()=>{return []}
    }
  },
  data() {
    return {
    };
  },
  mounted() {
    this.$nextTick(()=>{
      this.waterFall("#tabContainer", ".tab-item"); //实现瀑布流
    })
  },
  methods: {
    waterFall(
        wrapIdName,
        contentIdName,
        columns = 5,
        columnGap = 20,
        rowGap = 20
    ) {
      // 获得内容可用宽度(去除滚动条宽度)
      const wrapContentWidth =
          document.querySelector(wrapIdName).offsetWidth;
 
      // 间隔空白区域
      const whiteArea = (columns - 1) * columnGap;
 
      // 得到每列宽度(也即每项内容宽度)
      const contentWidth = parseInt((wrapContentWidth - whiteArea) / columns);
 
      // 得到内容项集合
      const contentList = document.querySelectorAll(contentIdName);
 
      // 成行内容项高度集合
      const lineConentHeightList = [];
 
      for (let i = 0; i < contentList.length; i++) {
        // 动态设置内容项宽度
        contentList[i].style.width = contentWidth + "px";
 
        // 获取内容项高度
        const height = contentList[i].clientHeight;
 
        if (i < columns) {
          // 第一行按序布局
          contentList[i].style.top = "0px";
          contentList[i].style.left = contentWidth * i + columnGap * i + "px";
 
          // 将行高push到数组
          lineConentHeightList.push(height);
        } else {
          // 其他行
          // 获取数组最小的高度 和 对应索引
          let minHeight = Math.min(...lineConentHeightList);
          let index = lineConentHeightList.findIndex(
              (listH) => listH === minHeight
          );
 
          contentList[i].style.top = minHeight + rowGap +"px";
          contentList[i].style.left = (contentWidth + columnGap) * index + "px";
 
          // 修改最小列的高度 最小列的高度 = 当前自己的高度 + 拼接过来的高度 + 行间距
          lineConentHeightList[index] += height + rowGap;
        }
      }
    },
  },
};
</script>
 
<style scoped>
* {
  margin: 0;
  padding: 0;
}
/* 最外层大盒子 */
.tab-container {
  padding-top: 20px;
  position: relative;
}
/* 每个小盒子 */
.tab-container .tab-item {
  position: absolute;
  height: auto;
  border: 1px solid #ccc;
  box-shadow: 0 2px 4px rgba(0, 0, 0, .12), 0 0 6px rgba(0, 0, 0, .04);
  background: white;
  /* 元素不能中断显示 */
  break-inside: avoid;
  text-align: center;
}
.tab-container .tab-item img {
  width: 100%;
  height: auto;
  display: block;
}
</style>

五.外层使用和懒加载

在使用这个插件的时候,有两个问题,就是因为内层是position: absolute;定位,不会撑开外部的p,会导致外层盒模型不好布局,还有就是页面下拉懒加载,那要怎么办呢?

这里我给出我的处理方法

 整体代码如下:

<template>
  <div>
    <div class="list-box" @scroll="scrollFun">
      <compList :pbList="pbList" ref="compList"></compList>
    </div>
  </div>
</template>
 
<script>
import compList from "@/pages/test/components/compList";
export default {
  name:'testList',
  components:{
    compList
  },
  data() {
    return {
      //瀑布流数据
      pbList: [
        {
          url: "https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fimg3.doubanio.com%2Fview%2Fphoto%2Fm%2Fpublic%2Fp2650049201.jpg&refer=http%3A%2F%2Fimg3.doubanio.com&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=auto?sec=1664935370&t=d4bf3e4d352c277a1bdebfcc8fda959f",
        },
        {
          url: "https://img1.baidu.com/it/u=2911909188,130959360&fm=253&fmt=auto&app=138&f=JPEG?w=440&h=641",
        },
        {
          url: "https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fimg3.doubanio.com%2Fview%2Fphoto%2Fm%2Fpublic%2Fp2650049201.jpg&refer=http%3A%2F%2Fimg3.doubanio.com&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=auto?sec=1664935370&t=d4bf3e4d352c277a1bdebfcc8fda959f",
        },
        {
          url: "https://img1.baidu.com/it/u=2911909188,130959360&fm=253&fmt=auto&app=138&f=JPEG?w=440&h=641",
        },
        {
          url: "https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fimg3.doubanio.com%2Fview%2Fphoto%2Fm%2Fpublic%2Fp2650049201.jpg&refer=http%3A%2F%2Fimg3.doubanio.com&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=auto?sec=1664935370&t=d4bf3e4d352c277a1bdebfcc8fda959f",
        },
        {
          url: "https://img1.baidu.com/it/u=2911909188,130959360&fm=253&fmt=auto&app=138&f=JPEG?w=440&h=641",
        },
        {
          url: "https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fimg3.doubanio.com%2Fview%2Fphoto%2Fm%2Fpublic%2Fp2650049201.jpg&refer=http%3A%2F%2Fimg3.doubanio.com&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=auto?sec=1664935370&t=d4bf3e4d352c277a1bdebfcc8fda959f",
        },
        {
          url: "https://img1.baidu.com/it/u=2911909188,130959360&fm=253&fmt=auto&app=138&f=JPEG?w=440&h=641",
        },
        {
          url: "https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fimg3.doubanio.com%2Fview%2Fphoto%2Fm%2Fpublic%2Fp2650049201.jpg&refer=http%3A%2F%2Fimg3.doubanio.com&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=auto?sec=1664935370&t=d4bf3e4d352c277a1bdebfcc8fda959f",
        },
        {
          url: "https://img1.baidu.com/it/u=2911909188,130959360&fm=253&fmt=auto&app=138&f=JPEG?w=440&h=641",
        },
        {
          url: "https://img1.baidu.com/it/u=2911909188,130959360&fm=253&fmt=auto&app=138&f=JPEG?w=440&h=641",
        }
      ],
      addList:[
        {
          url: "https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fimg3.doubanio.com%2Fview%2Fphoto%2Fm%2Fpublic%2Fp2650049201.jpg&refer=http%3A%2F%2Fimg3.doubanio.com&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=auto?sec=1664935370&t=d4bf3e4d352c277a1bdebfcc8fda959f",
        },
        {
          url: "https://img1.baidu.com/it/u=2911909188,130959360&fm=253&fmt=auto&app=138&f=JPEG?w=440&h=641",
        },
        {
          url: "https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fimg3.doubanio.com%2Fview%2Fphoto%2Fm%2Fpublic%2Fp2650049201.jpg&refer=http%3A%2F%2Fimg3.doubanio.com&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=auto?sec=1664935370&t=d4bf3e4d352c277a1bdebfcc8fda959f",
        },
        {
          url: "https://img1.baidu.com/it/u=2911909188,130959360&fm=253&fmt=auto&app=138&f=JPEG?w=440&h=641",
        },
        {
          url: "https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fimg3.doubanio.com%2Fview%2Fphoto%2Fm%2Fpublic%2Fp2650049201.jpg&refer=http%3A%2F%2Fimg3.doubanio.com&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=auto?sec=1664935370&t=d4bf3e4d352c277a1bdebfcc8fda959f",
        },
        {
          url: "https://img1.baidu.com/it/u=2911909188,130959360&fm=253&fmt=auto&app=138&f=JPEG?w=440&h=641",
        },
        {
          url: "https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fimg3.doubanio.com%2Fview%2Fphoto%2Fm%2Fpublic%2Fp2650049201.jpg&refer=http%3A%2F%2Fimg3.doubanio.com&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=auto?sec=1664935370&t=d4bf3e4d352c277a1bdebfcc8fda959f",
        },
        {
          url: "https://img1.baidu.com/it/u=2911909188,130959360&fm=253&fmt=auto&app=138&f=JPEG?w=440&h=641",
        },
        {
          url: "https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fimg3.doubanio.com%2Fview%2Fphoto%2Fm%2Fpublic%2Fp2650049201.jpg&refer=http%3A%2F%2Fimg3.doubanio.com&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=auto?sec=1664935370&t=d4bf3e4d352c277a1bdebfcc8fda959f",
        },
        {
          url: "https://img1.baidu.com/it/u=2911909188,130959360&fm=253&fmt=auto&app=138&f=JPEG?w=440&h=641",
        },
        {
          url: "https://img1.baidu.com/it/u=2911909188,130959360&fm=253&fmt=auto&app=138&f=JPEG?w=440&h=641",
        }
      ],
      bottomMain:true
    };
  },
  methods:{
    scrollFun(e) {
      const  offsetHeight= e.target.offsetHeight
      const  scrollHeight= e.target.scrollHeight
      const  scrollTop= e.target.scrollTop
      if((scrollHeight - (offsetHeight+scrollTop)) < 10){
        if(this.bottomMain){
          this.bottomMain = false
          this.addListDataFun()
        }
      }
    },
    addListDataFun(){
      this.$Spin.show({
        render: (h) => {
          return h('div', [
            h('Icon', {
              'class': 'demo-spin-icon-load',
              props: {
                type: 'ios-loading',
                size: 18
              }
            }),
            h('div', '数据更新中...')
          ])
        }
      });
      setTimeout(() => {
        this.pbList = this.pbList.concat(this.addList)
        this.bottomMain = true
        this.$nextTick(()=>{
          this.$refs.compList.waterFall("#tabContainer", ".tab-item")
          this.$Spin.hide()
        })
      },1000)
    }
  }
};
</script>
 
<style scoped>
.list-box{
  position: relative;
  width: 100%;
  height: calc(100vh - 240px);
  background: white;
  padding: 20px 30px 20px 20px;
  margin-top: 20px;
  box-sizing: border-box;
  overflow: auto;
}
</style>

下拉的核心代码为:

scrollFun(e) {
  const  offsetHeight= e.target.offsetHeight
  const  scrollHeight= e.target.scrollHeight
  const  scrollTop= e.target.scrollTop
  if((scrollHeight - (offsetHeight+scrollTop)) < 10){
    if(this.bottomMain){
      this.bottomMain = false
      this.addListDataFun()
    }
  }
},
addListDataFun(){
  this.$Spin.show({
    render: (h) => {
      return h('div', [
        h('Icon', {
          'class': 'demo-spin-icon-load',
          props: {
            type: 'ios-loading',
            size: 18
          }
        }),
        h('div', '数据更新中...')
      ])
    }
  });
  setTimeout(() => {
    this.pbList = this.pbList.concat(this.addList)
    this.bottomMain = true
    this.$nextTick(()=>{
      this.$refs.compList.waterFall("#tabContainer", ".tab-item")
      this.$Spin.hide()
    })
  },1000)
}

这里使用的是iView-UI的全局加载事件,如果你要用其他的UI框架,也可以自行修改

到这里,所有的思路就结束了

(学习视频分享:web前端开发、编程基础视频)

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

手把手带你使用Vue实现一个图片水平瀑布流插件 的相关文章

  • 带你详解vue中实现全页面或局部刷新的方法

    vue中怎么实现页面刷新 xff1f 下面本篇文章给大家介绍一下在vue中实现全页面刷新和局部刷新的方法 xff0c 希望对大家有所帮助 xff01 一 全页面刷新 1 修改 App vue xff0c 代码如下 xff1a lt temp
  • 深入浅析Angular指令如何保持关注点的分离?

    Angular指令如何保持关注点的分离 xff1f 本篇文章带大家了解一下通过 Angular 指令保持关注点分离的方法 xff0c 希望对大家有所帮助 xff01 假设在我们的应用程序中有一个日期选择器组件 用户每次更改日期的时 xff0
  • VSCode开发Python,这 14 个插件不可错过!

    VSCode怎么开发Python xff1f 下面本篇文章给大家整理分享VSCode中开发Python的14 个不可错过插件 xff0c 快来收藏 xff0c 看看有没有需要 xff01 可以说 xff0c Visual Studio Co
  • 软件测试 | 测试开发 | 使用charles 修改服务器返回数据

    使用charles 修改服务器返回数据 相信大家在做测试时 xff0c 一定有现有的返回结果不能覆盖到自己需要测试的全部场景的情况 xff0c 为了方便我们测试一些特殊情况 xff0c 我们就需要让服务器返回一些指定的内容以实现我们的测试c
  • 聊聊Vue3 style中新增了哪些特性(汇总)

    Vue3对style样式进行了升级 xff0c 下面本篇文章给大家汇总分享一下Vue3 style的新特性 xff0c 希望对大家有所帮助 xff01 Vue3 0后推出的setup函数 xff0c 像写JS一样开发Vue组件 xff0c
  • 原来利用纯CSS也能实现文字轮播与图片轮播!

    怎么制作文字轮播与图片轮播 xff1f 大家第一想到的是不是利用js xff0c 其实利用纯CSS也能实现文字轮播与图片轮播 xff0c 下面来看看实现方法 xff0c 希望对大家有所帮助 xff01 今天 xff0c 分享一个实际业务中能
  • 详解Node.js中Buffer对象的操作(创建、读写)

    本篇文章带大家了解一下Node中的Buffer对象 xff0c 介绍一下创建 Buffer 对象 读 Buffer 对象 写 Buffer 对象的方法 xff0c 希望对大家有所帮助 xff01 Buffer 是 Node js 的内置类型
  • Node.js学习之聊聊Events模块

    本篇文章带大家了解一下Node js中的Events模块 xff0c 介绍一下 Events 中的发布订阅模式 xff0c 希望对大家有所帮助 xff01 Events模块 参考官网 xff1a events 事件触发器 Node js h
  • 手把手教你安装和配置pm2,实现自动化部署node项目

    pm2怎么自动化部署nodejs项目 xff1f 下面本篇文章给大家介绍一下安装和配置pm2 xff0c 并实现自动化部署node项目的方法 xff0c 希望对大家有所帮助 xff01 1 pm2简介 pm2 xff08 process m
  • buffer是什么?深入了解Nodejs中的buffer模块

    buffer是什么 xff1f 下面本篇文章带大家深入了解一下Nodejs中的buffer模块 xff0c 介绍一下创建 复制 拼接 截取 填充Buffer xff0c 以及Buffer与String相互转换的方法 xff0c 希望对大家有
  • Angular进阶学习之深入了解路由和表单

    本篇文章是Angular的进阶学习 xff0c 我们一起来详细了解一下Angular中的路由和表单 xff0c 希望对大家有所帮助 xff01 Angular的路由介绍 在单页面应用中 xff0c 需要在定义好的不同视图中 xff08 组件
  • 浅析Vue前端路由中 hash 与 history的区别

    Vue前端路由hash与history间有什么区别 xff1f 下面本篇文章就来了解一下前端路由 hash 与 history 的差异 xff0c 希望对大家有所帮助 xff01 没了解这两种路由前 xff0c 不管是 vue还是 reac
  • 一文聊聊Angular中怎么操作DOM元素

    Angular中怎么操作DOM元素 xff1f 下面本篇文章给大家介绍一下angular操作DOM元素的方法 xff0c 希望对大家有所帮助 xff01 在angular获取DOM元素可以使用javascript的原生API xff0c 或
  • 浅析vscode中vue文件保存时怎么自动格式化

    vscode中vue文件保存时怎么自动格式化 xff1f 下面本篇文章给大家介绍一下vscode保存按照eslint规则自动格式化的方法 xff0c 希望对大家有所帮助 xff01 最近写vue用了vue admin template xf
  • 软件测试 | 测试开发 | Python 自动化测试技术面试真题

    本文为面试某公司测试开发 xff0f 自动化测试工程师时的面试题笔记 全部笔试内容没有全部写全 xff0c 只贴通用性的技术相关的笔试面试题 xff0c 至于测试理论和团队管理的问题 xff0c 都是大同小异 xff0c 也没什么实际的参考
  • VSCode中怎么配置扩展进行Arduino开发

    VSCode中怎么配置扩展进行Arduino开发 xff1f 下面本篇文章给大家介绍一下告别简陋的arduinoIDE xff0c 使用VSCode开发Arduino的方法 xff0c 希望对大家有所帮助 xff01 Arduino官方的I
  • 分享两个VSCode终端中的实用小技巧

    本篇文章给大家分享两个VSCode终端中的实用小技巧 xff0c 希望对大家有所帮助 xff01 使用VS Code终端也很有段时间了 xff0c 今天好奇发现两个小技巧 xff0c 记录一下现在激动的心情 那么这些技巧解决了什么问题呢 x
  • 聊聊Node中的各种I/O模型

    本篇文章带大家聊聊Node中的各种I O模型 xff0c 介绍一下阻塞式I O模型 非阻塞式I O模型和非阻塞异步I O xff0c 希望对大家有所帮助 xff01 我们以网络请求IO为例 xff0c 首先介绍服务端处理一次完整的网络IO请
  • Node.js深入学习之浅析require函数中怎么添加钩子

    如何为 Node 的 require 函数添加钩子 xff1f 下面本篇文章就来带大家了解一下require函数中添加钩子的方法 xff0c 希望对大家有所帮助 xff01 Node js 是一个基于 Chrome V8 引擎的 JavaS
  • 详解Vue3 Suspense:是什么?能干什么?如何用?

    本篇文章带大家深入了解一下Vue3 Suspense xff0c 聊聊Suspense是什么 能干什么 xff0c 以及如何使用它 xff0c 希望对大家有所帮助 xff01 Suspense 不是你想的那样 是的 xff0c 它帮助我们处

随机推荐

  • 2022年vue高频面试题分享(附答案分析)

    本篇文章给大家总结一些值得收藏的2022年精选vue高频面试题 xff08 附答案 xff09 有一定的参考价值 xff0c 有需要的朋友可以参考一下 xff0c 希望对大家有所帮助 Vue router 导航守卫有哪些 全局前置 钩子 x
  • 19个实用vscode开发插件分享

    工欲善其事必先利其器 本篇文章给大家总结分享19个我在开发中使用到的vscode插件 xff0c 希望对大家有所帮助 xff01 1 xff1a Chinese Simplified Language Pack 中文语言插件 适用于 VS
  • 带你使用CSS+jQuery实现一个文字转语音机器人

    本篇文章手把手带大家使用CSS 43 jQuery实现一个文字转语音机器人 xff0c 希望对大家有所帮助 xff01 素材 机器人眼睛 推荐学习 xff1a css视频教程 jQuery视频教程 web前端视频 页面布局 机器人样式参考了
  • 如何上手Angular,先从 8 个开源项目开始!

    多年的学习经验告诉我 xff0c 了解一个概念最快的方式是看他的实践 xff0c 所以我整理出了 8 个在学习 Angular 过程中可以参考的开源项目 xff0c 学习如何怎么使用 Angular 框架 xff5e 相关教程推荐 xff1
  • 如何安装并管理多版本node?方法介绍

    如何安装并管理多版本node xff1f 下面本篇文章给大家介绍一下多版本node的安装与切换详细操作 xff0c 希望对大家有所帮助 xff01 安装多版本node的原因 xff1a 在项目开发过程中 xff0c 不同项目使用的nodej
  • 软件测试 | 普罗米修斯-基本使用

    快速了解普罗米修斯 普罗米修斯是用 go 语言编写的软件并且利用了 go 语言的交叉编译特性编译成了纯二进制文件 xff0c 运行的时候不需要额外安装依赖 直接从官网上下载就可以 下载地址 xff1a Download Prometheus
  • 聊聊Node两种模块规范:CJS 与 ESM,有什么不同点?

    本篇文章给大家带大家了解一下Node的两种模块规范 xff08 难以相容的 CJS 与 ESM xff09 xff0c 介绍一下CJS 和 ESM 的不同点 xff0c 怎么实现 CJS ESM 混写 xff0c 希望对大家有所帮助 xff
  • 手把手教你怎么在vscode中创建maven工程(图文结合)

    怎么在vscode中创建maven工程 xff1f 下面本篇文章就通过图文结合的方式带大家一步步创建maven工程 xff0c 希望对大家有所帮助 xff01 由于 xff0c 鄙人最近正在学习设计模式 xff0c 并且是阅读 重学设计模式
  • VSCode插件分享:一个实时预览Vue/React组件的插件

    在VSCode中开发Vue React组件时 xff0c 怎么实时预览组件 xff1f 本篇文章就给大家分享一个VSCode 中实时预览Vue React组件的插件 xff0c 希望对大家有所帮助 xff01 最近年纪大了喜欢胡思乱想 xf
  • 什么是Mixin?带你了解Vue中的Mixin混入

    什么是Mixin xff1f 本篇文章带大家了解一下Vue中的Mixin混入 xff0c 介绍Mixin和Vuex的区别 xff0c Mixin的使用方法 xff0c 希望对大家有所帮助 xff01 Vue框架现在基本上已经占据了前端的半壁
  • vue中什么是自定义指令?怎么使用?

    本篇文章带大家了解一下vue中的自定义指令 xff0c 介绍一下如何注册自定义指令 自定义指令参数 自定义指令使用场景 xff0c 希望对大家有所帮助 xff01 如今Vue占据了国内前端市场的大壁江山 xff0c 在前端求职过程中 xff
  • Vue.js中如何优化性能?9个小技巧分享

    Vue js中如何优化性能 xff1f 下面本篇文章给大家分享Vue js 性能优化的九个小技巧 xff0c 希望对大家有所帮助 xff01 xff08 学习视频分享 xff1a vuejs教程 xff09 01 Functional co
  • 总结分享一些基于Node.js的前端面试题(附解析)

    本篇文章给大家总结分享一些基于Node js的前端面试题 xff08 附解析 xff09 xff0c 希望对大家有所帮助 xff01 一 Node基础概念 1 1 Node是什么 Node js 是一个开源与跨平台的 JavaScript
  • 【整理总结】VSCode常用插件和好用配置(小白必看)

    本篇文章给大家总结分享一些VSCode常用插件和好用配置 xff08 超详细 xff09 希望可以给刚入坑前端的小伙伴一些帮助 本文很长 xff0c 如果能认真看完 xff0c 你一定会有所收获 一 VSCode常用插件推荐 工欲善其事 x
  • 2023年最新最全的VScode插件推荐

    这篇文章主要介绍了这么多年来我在使用 VSCode 过程中用到的一些不错的插件 这些VSCode插件 xff0c 帮你打造地表最强IDE xff01 一 主题及图标 GitHub Theme 黑白两款皮肤 Material Theme 集成
  • 聊聊VSCode中Snippet插件的使用(提高编程效率)

    本文介绍的是 VSCode Snippet 插件 xff0c 一种代码片段配置插件 xff0c 可以节省你写样板代码的时间 你可能之前学习过 VSCode Snippet 插件 xff0c 知道它的作用也学习了配置的语法 xff0c 但是你
  • 软件测试 | 普罗米修斯- 初识PromQL

    理解监控数据 之前讲过普罗米修斯自己就是一个时序数据库 xff0c 它从 exporter 拉取的数据都会按时间戳保存到对应的文件里 xff0c 这个时序数据库默认会保存 14 天的数据 而它自己也开发了一套名为 PromQL 的类 SQL
  • 【整理分享】30个让开发效率倍增的实用VSCode 插件

    本篇文章给大家总结分享30个让开发效率倍增的实用VSCode 插件 xff0c 让你的日常开发工作效率倍增 xff0c 希望对大家有所帮助 xff01 1 Image preview 通过此插件 xff0c 当鼠标悬浮在图片的链接上时 xf
  • 10个提高开发效率的Vue3常用插件(快来收藏)

    本篇文章给大家总结分享几个好用的 Vue 插件 xff0c 可以帮助开发者提高开发效率 解决移动端各种滚动场景需求 xff0c 希望对大家有所帮助 xff01 1 vue multiselect next Vue js 的通用选择 多选 标
  • 手把手带你使用Vue实现一个图片水平瀑布流插件

    如何使用Vue实现一个图片水平瀑布流插件 xff1f 这里给大家分享我在网上总结出来的一些知识 xff0c 希望对大家有所帮助 一 需求来源 今天碰到了一个需求 xff0c 需要在页面里 xff0c 用水平瀑布流的方式 xff0c 将一些图