工作笔记-图片和视频轮播、虚拟滚动、js 树形结构常见操作-递归创建树,map创建树,查找多棵树中节点的完整路径、javaScript事件、git命令、生命周期

313 阅读18分钟

工作中的笔记整理,记录下来,方便下次使用

1. 视频图片轮播

1. vue2 版本的视频和图片混合轮播

效果如下: image.png

  1. 安装 "vue-video-player": "^5.0.1"
npm install vue-video-player@5.0.1

2:全局引入main.js

import VideoPlayer from 'vue-video-player'
import 'vue-video-player/src/custom-theme.css'
import 'video.js/dist/video-js.css'

Vue.use(VideoPlayer)
  1. 可实现代码如下:接口换成自己的接口就可以
<template>
  <div class="m-left">
    <!-- <img src="@/common/imgs/main-left.png" alt="" /> -->
    <el-carousel height="400px" :autoplay="autoplay" :interval="interval" :initial-index="initialIndex" ref="carousel" @change="onChange">
      <!-- //判断视频格式使用播放器 -->
      <el-carousel-item v-for="item in banner" :key="item.InfoId">
        <video-player id="player" class="video-player vjs-custom-skin" v-if="item.img.indexOf('mp4') !== -1" ref="videoPlayer" :playsinline="true" :options="playerOptions" @ended="onPlayerEnded($event)" @loadeddata="onPlayerLoadeddata($event)" style="height: 100%;width:100%;"></video-player>
        <!-- // 否则使用Img -->
        <img v-else :src="item.img" style="height: 100%;width:100%;" />
      </el-carousel-item>
    </el-carousel>

  </div>
</template>
<script>
import { getInformationMessApi } from '@/api/common.js'

export default {
  name: 'ConLeft',
  data() {
    return {
      // bannerList: [],

      autoplay: true, //自动播放
      interval: 3000, //轮播时常
      initialIndex: 1, //从下标第几个开始轮播
      duration: NaN, //计算总时长
      banner: [], //从后端获取来的轮播图数据

      //vue-video-play  播放器默认的设置
      playerOptions: {
        autoplay: true, //如果true,浏览器准备好时开始回放。实现自动播放,autoplay、muted都设置为true
        muted: true, // 默认情况下将会消除任何音频。
        loop: false, // 导致视频一结束就重新开始。
        preload: 'auto', // 建议浏览器在<video>加载元素后是否应该开始下载视频数据。auto浏览器选择最佳行为,立即开始加载视频(如果浏览器支持)
        language: 'zh-CN',
        aspectRatio: '16:9', // 将播放器置于流畅模式,并在计算播放器的动态大小时使用该值。值应该代表一个比例 - 用冒号分隔的两个数字(例如"16:9"或"4:3")
        fluid: true, // 当true时,Video.js player将拥有流体大小。换句话说,它将按比例缩放以适应其容器。
        sources: [
          {
            type: 'video/mp4', //这里的种类支持很多种:基本视频格式、直播、流媒体等,具体可以参看git网址项目
            src: '', //url地址
          },
        ],
        width: document.documentElement.clientWidth, //播放器宽度
        notSupportedMessage: '此视频暂无法播放,请稍后再试', //允许覆盖Video.js无法播放媒体源时显示的默认信息。
      },
    }
  },

  methods: {
  //这里换成自己的接口地址
    gstBannerInfo() {
      getInformationMessApi().then((res) => {
        console.log('查询首页轮播信息', res)
        const { CurrentPageData } = res
        this.banner = CurrentPageData.map((el) => ({ ...el, img: `/Content/HomeCarousel/${el.LinkeUrl}` }))
        console.log('轮播图数据', this.banner)
      })
    },
    onPlayerLoadeddata(player) {
      //获取视频总时长
      this.duration = player.cache_.duration
    },
    //监听轮播图改变
    onChange(index) {
      // 判断是否为视频,如果是视频,就等播放完再进行下一个
      if (this.banner[index].img.indexOf('mp4') != -1) {
        //把获取来的视频赋值给sources的src
        this.playerOptions['sources'][0]['src'] = this.banner[index].img
        this.$refs.videoPlayer[0].player.src(this.playerOptions['sources'][0]['src']) // 重置进度条,再次轮播时让视频重新播放
        this.interval = this.duration * 1000 //获取视频总时长*1000,赋值给轮播图间隔时间
        this.autoplay = false //自动播放停止
      }
    },
    //监听视频是否播放完毕
    onPlayerEnded(player) {
      this.autoplay = true //自动播放开启
      this.interval = 3000 //轮播间隔改为3秒
    },
  },
  mounted() {
    this.gstBannerInfo()
  },
}
</script>
<style lang="scss" scoped>
.m-left {
  min-width: 600px;
  min-height: 400px;
  box-sizing: border-box;
  padding: 10px;
  background: rgba(255, 255, 255, 0.3);
  border-radius: 5px;
}
.m-left img {
  border-radius: 4px;
}
@media (max-width: 970px) {
}
</style>

2.vue3版本

1:安装   @videojs-player/vue

npm install video.js @videojs-player/vue --save

2:全局 main.ts中引入

import VideoPlayer from '@videojs-player/vue'
import 'video.js/dist/video-js.css'

image.png

<template>
    <el-carousel id="myCarousel"
                 :autoplay="autoplay"
                 :interval="interval"
                 :initial-index="initialIndex"
                 @change="onChange">
        <el-carousel-item v-for="(item, index) in props.imgList" :key="index" name="index">
            <img
                 v-if="item.type == 1"
                 :src="item.url"
                 alt="这是图片"
                 class="banner" />
            <!-- :playback-rates="[0.7, 1.0, 1.5, 2.0]" 几倍速-->
            <!-- controls 控制台显示  -->
            <!-- crossorigin="anonymous" 可设置跨域属性-->
            <video-player v-else
                          class="video-player vjs-big-play-centered"
                          :src="src"
                          ref="playerRef"
                          playsinline
                          autoplay="true"
                          muted
                          controls
                          :volume="0.6"
                          :height="320"
                          @ended="onPlayerEnded($event)"
                          @loadeddata="onPlayerLoadeddata($event)" />

        </el-carousel-item>
    </el-carousel>
</template>
   
<script lang="ts" setup>
import internal from 'stream';
import { ref, withDefaults, getCurrentInstance, onMounted } from "vue"
const { proxy } = getCurrentInstance() as any;
interface IImgList {
    id?: number,
    type: number,
    url: string
}
const props = withDefaults(
    defineProps<{
        imgList: IImgList[],
    }>(),
    {
        imgList: () => []
    }
)
const playerRef = ref()
let src = ref('')
//可打印出当前所触发的事件
let autoplay = ref(true)
let interval = ref(3000)
let initialIndex = ref(0)
let duration = ref(0)




function onPlayerLoadeddata(player: any) {
    // 获取资源总时长 
    duration.value = player.target.player.cache_.duration;
}
//监听媒体是否已到达结尾,播放完
function onPlayerEnded(player: any) {
    autoplay.value = true
    interval.value = 3000
}
// 监听轮播图改变
function onChange(index: number) {
    // 如果是视频,就等播放完再进行下一个
    if (props.imgList[index].type == 2) {
        debugger
        //props.imgList[index].url
        //https://vjs.zencdn.net/v/oceans.mp4
        //https:**********/bottom_2.mp4
        src.value = '**********/bottom_2.mp4' //视频赋值
        interval.value = duration.value * 1000;
        autoplay.value = false;
    } else {
        src.value = ''
    }
}
onMounted(() => {
    props.imgList.forEach(e => {
        e.url = proxy.$imagePath + e.url
    })
    debugger
});




</script>
<style lang="scss">
#myCarousel img {
    width: 100%;
    height: 100%;
}
</style>
   
<style lang="scss" scoped>
.video-player {
    width: 100%;
    height: 100%;
}
</style>

有问题可以参考这篇文章

2. Vue2 el-table虚拟滚动

1. Vue2 el-table 数据量大的情况下使用虚拟滚动

  1. 安装:
npm i el-table-virtual-scroll -S

2.注意事项:

VirtualScroll组件中必须设置key-prop,否则会出现错行

使用 <el-table-virtual-scroll> 做表格虚拟滚动,是不支持ElementUI 表格的原有的索引、多选、扩展行等功能,需要使用<virtual-column>来兼容。<virtual-column> 组件内封装了 <el-table-column>,支持传入 <el-table-column>组件的props属性。


<virtual-scroll
  :data="list"
  :item-size="62"
  key-prop="id"//这个是一定要有,不能重复,如果没有可以自己循环设置数据id
  @change="(renderData) => virtualList = renderData">
  <el-table 
    row-key="id" //这个是一定要有不能重复相互对应
    :data="virtualList" 
    height="500px">
  </el-table>
</virtual-scroll>
...

import VirtualScroll from 'el-table-virtual-scroll'

export default {
  component: {
    VirtualScroll
  },
  data () {
    list: [
      {
        id: 1,
        text: 'content'
      },
      // ...... 省略n条
      {
        id: 2000,
        text: 'content2'
      }
    ],
    virtualList: []
  }
}
  1. el-table-virtual-scroll 组件

  1. Props

参数说明类型可选值默认值
data总数据Array必填
keyPropkey值,data数据中的唯一id【⚠️若keyProp未设置或keyProp值不唯一,可能导致表格空数据或者滚动时渲染的数据断层、不连贯、滚动不了】stringid
itemSize每一行的预估高度number60
scrollBox指定滚动容器;在指定滚动容器时,如果表格设置了height高度,则滚动容器为表格内的滚动容器;如果表格未设置height高度,则自动获取外层的滚动容器,直至window容器为止string'window'、css选择器-
buffer顶部和底部缓冲区域,值越大显示表格的行数越多Number200
throttleTime滚动事件的节流时间number16
dynamic动态获取表格行高度,默认开启。设置为false时,则以itemSize为表格行的真实高度,能大大减少虚拟滚动计算量,减少滚动白屏;如果itemSize与表格行的真实高度不一致,可能导致滚动时表格数据错乱、抖动、底部有空白booleantrue
virtualized是否开启虚拟滚动booleantrue
rowSpanKey当使用了el-table的合并行,必须设置rowSpanKey函数并返回每组合并行中共用的key值Function(row, index)-
selectionSort支持多选可自定义选中数据的排序规则,默认为 true 按选择顺序排,传入 false 为按列表中的顺序排,传入函数为自定义排序规则Boolean、Function-
getElTable获取 <el-table> 组件,默认获取 <virtual-scroll> 的第一个子组件;如果 <el-table> 组件经过用户封装,那么需要使用该方法返回正确的 <el-table> 组件【可通过 ref、$children 返回正确的值】Function-
keepScroll当使用v-show,keep-alive 切换表格显示时,会保持原来滚动位置booleantrue
  1. Methods

方法名说明参数
scrollTo滚动到第几行;index - 行数索引值;offset - 偏移位置(index: number, offset: number)
scrollToRow滚动到对应的行;row;offset - 偏移位置(row: object, offset: number)
update更新,会重新计算实际渲染数据和位置-
setCurrentRow用于单选 <virtual-column type="radio">, 设定某一行为选中行row
slowOnMousewheel减缓滚轮滚动的速度,slowNum参数为减缓参数,默认为1,数值越大滚动越慢;在mac电脑上,谷歌、火狐浏览器在 自定义固定列 demo 上快速滚动会有白屏,可以使用该方法减少白屏。请根据实际情况使用,使用不当可能会让表格滚动卡顿。【注意:滚轮滚动有效,拖动滚动条滚动无效】slowNum
getParentNode【扩展树形表格】获取父节点row
getParentNodes【扩展树形表格】获取所有父节点row
getChildNodes【扩展树形表格】获取子节点row
reloadNode【扩展树形表格】重新加载节点row
expandAllNodes【扩展树形表格】展开所有树节点-
unexpandAllNodes【扩展树形表格】收起所有树节点,懒加载节点除外-
  1. Events

事件名称说明参数
change计算完成真实显示的表格行数(renderData, start, end):renderData 真实渲染的数据,start和end指的是渲染的数据在总数据的开始到结束的区间范围

查看官网

3. js 处理数据转成树结构

1. 递归调用创建树

完整可实现代码:

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta
    name="viewport"
    content="width=device-width, initial-scale=1.0"
  >
  <title>Document</title>
</head>

<body>
  <script>
    let arr = [
      { id: 1, name: '部门1', pid: 0 },
      { id: 2, name: '部门2', pid: 1 },
      { id: 3, name: '部门3', pid: 1 },
      { id: 4, name: '部门4', pid: 3 },
      { id: 5, name: '部门5', pid: 4 },
    ]

  // 定义一个函数 getChildren,用于根据父ID从数据中获取子节点,并将结果存储在 result 数组中
const getChildren = (data, result, pid) => {
    // 遍历数据数组中的每一个元素
    for (const item of data) {
        // 检查当前元素的父ID是否等于传入的父ID pid
        if (item.pid === pid) {
            // 创建一个 newItem 对象,包含当前元素的所有属性,并添加一个空的 children 数组
            const newItem = { ...item, children: [] };
            // 将 newItem 对象推入 result 数组中
            result.push(newItem);
            // 递归调用 getChildren 函数,获取 newItem 的子节点,并将其存储在 newItem.children 数组中
            getChildren(data, newItem.children, item.id);
        }
    }
}


    /**
    * 转换方法
    */
    const arrayToTree = (arr, pid) => {
      console.log('data', arr);
      const result = [];
      getChildren(arr, result, pid)
      return result;
    }
    let treeData = arrayToTree(arr, 0);
    console.log('arrayToTree', treeData);
  </script>
</body>

</html>

2.利用map创建树

    /**
     * 将扁平化的目录数据转换为树形结构
     * @param {Array} data - 包含目录信息的数组
     * @param {string} ParentDirIdTag - 表示父目录ID的字段名,默认为'ParentDirIdTag'
     * @param {string} DirectoryId - 表示目录ID的字段名,默认为'DirectoryId'
     * @returns {Array} - 转换后的树形结构数组
     */
    listToTree(data, ParentDirIdTag = 'ParentDirIdTag', DirectoryId = 'DirectoryId') {
      // 初始化树形结构数组
      const tree = []
      // 创建一个Map来存储每个目录项及其子目录
      const map = new Map()
      
      // 将所有数据以DirectoryId为键存入map中,同时为每个目录项初始化一个children数组
      data.forEach((item) => {
        map.set(item[DirectoryId], { ...item, children: [] })
      })
      // 输出map内容以供调试
      console.log('map', map)
      
      // 遍历数据,构建父子关系
      data.forEach((item) => {
        // 获取当前目录项的父目录ID
        const parentId = item[ParentDirIdTag]
        
        // 如果父级id为0,说明是根节点,直接添加到树中
        if (parentId === 0) {
          tree.push(map.get(item[DirectoryId]))
        } else {
          // 获取父目录项
          const parent = map.get(parentId)
          // 输出父目录项以供调试
          console.log('parent', parent)
          
          // 如果父目录项存在,则将当前目录项添加到父目录项的children数组中
          if (parent) {
            parent.children.push(map.get(item[DirectoryId]))
          }
        }
      })
      
      // 输出最终构建的树形结构以供调试
      console.log('tree', tree)
      // 返回构建好的树形结构数组
      return tree
    },

3. 查找多棵树中节点的完整路径

完整可运行代码如下:

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta
    name="viewport"
    content="width=device-width, initial-scale=1.0"
  >
  <title>查找多棵树中节点的完整路径</title>
</head>

<body>

  <script>
    // 辅助函数:在单棵树中查找指定id的节点(递归查找)
    // 输入:root - 树的根节点, targetId - 要查找的目标节点的id
    // 输出:找到的节点或null
    function findNodeInTree (root, targetId) {
      // 先判断根节点是否存在
      if (!root) {
        return null; // 如果根节点不存在,返回null
      }
      // 判断当前根节点的DirectoryId是否等于目标id
      if (root.DirectoryId === targetId) {
        return root; // 如果相等,返回当前节点
      }
      // 如果当前节点有子节点,则递归查找每个子节点
      if (root.children && root.children.length > 0) {
        for (const child of root.children) {
          const result = findNodeInTree(child, targetId); // 递归查找子节点
          if (result) {
            return result; // 如果找到,返回结果
          }
        }
      }
      return null; // 如果未找到,返回null
    }

    // 辅助函数:在单棵树中查找指定节点的父节点(递归查找)
    // 输入:node - 当前查找的节点, parentId - 目标父节点的id, tree - 当前树的根节点
    // 输出:找到的父节点或null
    function findParentNodeInTree (node, parentId, tree) {
      // 判断当前节点的DirectoryId是否等于目标父节点id
      if (node.DirectoryId === parentId) {
        return node; // 如果相等,返回当前节点作为父节点
      }
      // 如果当前节点有子节点,则递归查找每个子节点
      if (node.children && node.children.length > 0) {
        for (const child of node.children) {
          // 传递当前子树的根节点,而不是整棵树的根节点
          const result = findParentNodeInTree(child, parentId, child);
          if (result) {
            return result; // 如果找到父节点,返回结果
          }
        }
      }
      return null; // 如果未找到,返回null
    }

    // 主函数:在多棵树组成的数组中查找节点的完整路径
    // 输入:targetNode - 目标节点对象, trees - 存放多棵树的数组
    // 输出:从目标节点到根节点的路径数组
    function findNodePathInTrees (targetNode, trees) {
      const path = []; // 初始化路径数组
      let currentNode = targetNode; // 当前节点初始化为目标节点
      // 循环直到当前节点为null或已经找到根节点
      while (currentNode) {
        path.push(currentNode); // 将当前节点添加到路径数组中
        const parentId = currentNode.ParentDirIdTag; // 获取当前节点的父节点id
        if (parentId === 0) {
          break; // 如果父节点id为0,表示已经找到根节点,结束循环
        }
        // 在多棵树中查找当前节点所在的树,并查找父节点
        for (const tree of trees) {
          const found = findParentNodeInTree(tree, parentId, tree);
          if (found) {
            currentNode = found; // 找到父节点后,将当前节点更新为父节点
            break; // 找到后结束循环
          }
        }
      }
      return path.reverse(); // 返回反转后的路径数组,使得路径从根节点到目标节点
    }

    // 示例数据,模拟存放多棵树的数组
    // 每棵树由多个节点组成,节点有DirectoryId, DirectoryName等属性
    const trees = [
      {
        "DirectoryId": 9, // 根节点id
        "DirectoryName": "恒祥自控资料库", // 根节点名称
        "DirectoryUrl": "hxzkLib", // 根节点url
        "DirectoryOrder": 1, // 根节点顺序
        "IsDisable": false, // 根节点是否禁用
        "ParentDirIdTag": 0, // 父节点id,根节点为0
        "PermissionTags": false, // 权限标签
        "ChildDirNumber": 2, // 子目录数量
        "FileNumber": 0, // 文件数量
        "children": [ // 子节点数组
          {
            "DirectoryId": 10, // 子节点id
            "DirectoryName": "目录1r", // 子节点名称
            "DirectoryUrl": "", // 子节点url
            "DirectoryOrder": 1, // 子节点顺序
            "IsDisable": false, // 子节点是否禁用
            "ParentDirIdTag": 9, // 父节点id
            "PermissionTags": false, // 权限标签
            "ChildDirNumber": 0, // 子目录数量
            "FileNumber": 2, // 文件数量
            "children": [] // 子节点数组为空
          },
          {
            "DirectoryId": 11, // 子节点id
            "DirectoryName": "目录2", // 子节点名称
            "DirectoryUrl": "", // 子节点url
            "DirectoryOrder": 1, // 子节点顺序
            "IsDisable": false, // 子节点是否禁用
            "ParentDirIdTag": 9, // 父节点id
            "PermissionTags": false, // 权限标签
            "ChildDirNumber": 0, // 子目录数量
            "FileNumber": 0, // 文件数量
            "children": [] // 子节点数组为空
          }
        ]
      },

      {
        "DirectoryId": 12, // 根节点id
        "DirectoryName": "运维系统资料库", // 根节点名称
        "DirectoryUrl": "ywsys", // 根节点url
        "DirectoryOrder": 2, // 根节点顺序
        "IsDisable": false, // 根节点是否禁用
        "ParentDirIdTag": 0, // 父节点id,根节点为0
        "PermissionTags": false, // 权限标签
        "ChildDirNumber": 1, // 子目录数量
        "FileNumber": 0, // 文件数量
        "children": [ // 子节点数组
          {
            "DirectoryId": 14, // 子节点id
            "DirectoryName": "目录1", // 子节点名称
            "DirectoryUrl": "", // 子节点url
            "DirectoryOrder": 1, // 子节点顺序
            "IsDisable": false, // 子节点是否禁用
            "ParentDirIdTag": 12, // 父节点id
            "PermissionTags": false, // 权限标签
            "ChildDirNumber": 0, // 子目录数量
            "FileNumber": 2, // 文件数量
            "children": [] // 子节点数组为空
          }
        ]
      }
    ];

    console.log('trees', trees); // 输出模拟的多棵树数组
    // 模拟点击了id为14的节点,先找到它所在的树和节点对象
    let targetNode = null; // 初始化目标节点为null
    for (const tree of trees) { // 遍历多棵树数组
      targetNode = findNodeInTree(tree, 14); // 在单棵树中查找id为14的节点
      if (targetNode) { // 如果找到目标节点
        break; // 结束循环
      }
    }

    if (targetNode) { // 如果目标节点存在
      const path = findNodePathInTrees(targetNode, trees); // 查找目标节点的完整路径
      console.log(path.map(node => node.DirectoryName)); // 输出路径中每个节点的名称
    } else {
      console.log("未找到指定节点"); // 如果未找到目标节点,输出提示信息
    }


  </script>
</body>

</html>

4. js 事件集合

来自于网络资源整理:

一:鼠标事件

  1. click 当用户点击元素时触发。

    
    document.getElementById('myButton').addEventListener('click', () => {
      alert('按钮被点击了!');
    });
    
  2. dblclick 当用户双击元素时触发。

    document.getElementById('myDiv').addEventListener('dblclick', () => {
      alert('区域被双击了!');
    });
    
  3. mousedown 当用户按下鼠标按钮时触发。

    
    document.addEventListener('mousedown', (event) => {
      console.log('鼠标按钮被按下:', event.button);
    });
    
  4. mouseup 当用户松开鼠标按钮时触发。

    
    document.addEventListener('mouseup', () => {
      console.log('鼠标按钮被松开');
    });
    
  5. mousemove 当用户在元素上移动鼠标时触发。

     
    document.addEventListener('mousemove', (event) => {
      console.log('鼠标位置:', event.clientX, event.clientY);
    });
    
  6. mouseenter 当鼠标进入元素时触发。

    javascript
     代码解读
    复制代码
    document.getElementById('myDiv').addEventListener('mouseenter', () => {
      console.log('鼠标进入区域');
    });
    
  7. mouseleave 当鼠标离开元素时触发。

    
    document.getElementById('myDiv').addEventListener('mouseleave', () => {
      console.log('鼠标离开区域');
    });
    
  8. wheel 当用户使用鼠标滚轮时触发。

    
    document.addEventListener('wheel', (event) => {
      console.log('滚轮事件:', event.deltaY);
    });
    

二:键盘事件

  1. keydown 当用户按下键盘上的某个键时触发。

    
    document.addEventListener('keydown', (event) => {
      console.log('按键按下:', event.key);
    });
    
  2. keyup 当用户松开键盘上的某个键时触发。

     
    document.addEventListener('keyup', (event) => {
      console.log('按键松开:', event.key);
    });
    
  3. keypress 当用户按下字符键时触发(已弃用)。

    
    document.addEventListener('keypress', (event) => {
      console.log('按键按下:', event.key);
    });
    

三:表单事件

  1. submit 当用户提交表单时触发。

    
    document.getElementById('myForm').addEventListener('submit', (event) => {
      event.preventDefault(); // 阻止默认的表单提交行为
      console.log('表单已提交!');
    });
    
  2. change 当用户改变输入框内容时触发。

    
    document.getElementById('myInput').addEventListener('change', (event) => {
      console.log('输入框内容已改变:', event.target.value);
    });
    
  3. input 当用户输入内容时实时触发(即内容改变时立即触发)。

    
    document.getElementById('myInput').addEventListener('input', (event) => {
      console.log('输入框内容:', event.target.value);
    });
    
  4. focus 当输入框获得焦点时触发。

    
    document.getElementById('myInput').addEventListener('focus', () => {
      console.log('输入框获得焦点');
    });
    
  5. blur 当输入框失去焦点时触发。

    
    document.getElementById('myInput').addEventListener('blur', () => {
      console.log('输入框失去焦点');
    });
    

四:窗口和文档事件

  1. load 当整个页面加载完毕,包括所有依赖资源时触发。

    window.addEventListener('load', () => {
      console.log('页面完全加载');
    });
    
  2. resize 当浏览器窗口大小改变时触发。

    window.addEventListener('resize', () => {
      console.log('窗口大小改变:', window.innerWidth, window.innerHeight);
    });
    
  3. scroll 当用户滚动文档时触发。

    
    window.addEventListener('scroll', () => {
      console.log('页面滚动');
    });
    
  4. unload 当文档或子资源被卸载时触发。

    window.addEventListener('unload', () => {
      console.log('页面卸载');
    });
    
  5. beforeunload 当用户要离开页面时触发,可以用来提示用户是否确认离开。

    
    window.addEventListener('beforeunload', (event) => {
      event.preventDefault();
      event.returnValue = '你确定要离开吗?';
    });
    

五:触控事件

  1. touchstart 当用户手指触碰触控板时触发。

    
    document.addEventListener('touchstart', (event) => {
      console.log('触控开始');
    });
    
  2. touchmove 当用户手指在触控板上移动时触发。

    
    document.addEventListener('touchmove', (event) => {
      console.log('触控移动');
    });
    
  3. touchend 当用户手指离开触控板时触发。

    
    document.addEventListener('touchend', (event) => {
      console.log('触控结束');
    });
    

六:剪贴板事件

  1. copy 当用户复制内容时触发。

    document.addEventListener('copy', () => {
      console.log('内容已复制到剪贴板');
    });
    
  2. cut 当用户剪切内容时触发。

    
    document.addEventListener('cut', () => {
      console.log('内容已剪切到剪贴板');
    });
    
  3. paste 当用户粘贴内容时触发。

    
    document.addEventListener('paste', () => {
      console.log('内容已粘贴从剪贴板');
    });
    

七:媒体事件

  1. play 当媒体开始播放时触发。

    
    const video = document.getElementById('myVideo');
    video.addEventListener('play', () => {
      console.log('视频正在播放');
    });
    
  2. pause 当媒体暂停时触发。

    
    video.addEventListener('pause', () => {
      console.log('视频已暂停');
    });
    
  3. ended 当媒体播放完毕时触发。

    video.addEventListener('ended', () => {
      console.log('视频播放结束');
    });
    
  4. volumechange 当音量改变时触发。

    video.addEventListener('volumechange', () => {
      console.log('音量已改变为:', video.volume);
    });
    
  5. canplay 当浏览器能够播放媒体时触发。

    
    video.addEventListener('canplay', () => {
      console.log('浏览器能够播放视频');
    });
    
  6. canplaythrough 当浏览器能够播放整个媒体时触发。

    
    video.addEventListener('canplaythrough', () => {
      console.log('浏览器能够播放整个视频');
    });
    
  7. durationchange 当媒体时长改变时触发。

     
    video.addEventListener('durationchange', () => {
      console.log('视频时长改变');
    });
    
  8. emptied 当媒体数据被清空时触发。

    javascript
     代码解读
    复制代码
    video.addEventListener('emptied', () => {
      console.log('视频数据被清空');
    });
    
  9. error 当媒体加载失败时触发。

    video.addEventListener('error', () => {
      console.log('视频加载失败');
    });
    
  10. loadeddata 当媒体数据已加载到浏览器时触发。

    
    video.addEventListener('loadeddata', () => {
      console.log('视频数据已加载');
    });
    
  11. loadedmetadata 当媒体元数据已加载到浏览器时触发。

    
    video.addEventListener('loadedmetadata', () => {
      console.log('视频元数据已加载');
    });
    
  12. loadstart 当媒体开始加载时触发。

    
    video.addEventListener('loadstart', () => {
      console.log('视频开始加载');
    });
    
  13. progress 当媒体加载进度改变时触发。

    
    video.addEventListener('progress', () => {
      console.log('视频加载进度改变');
    });
    
  14. ratechange 当媒体播放速度改变时触发。

    
    video.addEventListener('ratechange', () => {
      console.log('视频播放速度改变');
    });
    
  15. seeking 当用户正在寻求视频中的特定位置时触发。

    
    video.addEventListener('seeking', () => {
      console.log('用户正在寻找视频中的特定位置');
    });
    

八:自定义事件

  1. CustomEvent 创建和触发自定义事件。

    const event = new CustomEvent('myCustomEvent', { detail: { key: 'value' } });
    document.dispatchEvent(event);
    
    document.addEventListener('myCustomEvent', (e) => {
      console.log('自定义事件触发:', e.detail);
    });
    

九:其他值得注意的事件

  1. focusin 当元素或其任何子元素获得焦点时触发。

    document.getElementById('myInput').addEventListener('focusin', () => {
      console.log('输入框或其子元素获得焦点');
    });
    
  2. focusout 当元素或其任何子元素失去焦点时触发。

    document.getElementById('myInput').addEventListener('focusout', () => {
      console.log('输入框或其子元素失去焦点');
    });
    
  3. contextmenu 当用户点击鼠标右键时触发。

    document.addEventListener('contextmenu', (event) => {
      event.preventDefault(); // 阻止默认的右键菜单
      console.log('自定义右键菜单打开');
    });
    
  4. animationstart 当 CSS 动画开始时触发。

    
    document.getElementById('myElement').addEventListener('animationstart', () => {
      console.log('动画开始');
    });
    
  5. animationend 当 CSS 动画结束时触发。

    
    document.getElementById('myElement').addEventListener('animationend', () => {
      console.log('动画结束');
    });
    
  6. transitionend 当 CSS 过渡结束时触发。

    document.getElementById('myElement').addEventListener('transitionend', () => {
      console.log('过渡结束');
    });
    
  7. abort 当用户中止媒体加载时触发。

    
    const video = document.getElementById('myVideo');
    video.addEventListener('abort', () => {
      console.log('视频加载被中止');
    });
    

5. git基础配置命令

1. 初始化配置

配置用户信息是使用 Git 的第一步:

# 配置全局用户名和邮箱
git config --global user.name "FedJavaScript"
git config --global user.email "FedJavaScript@example.com"

# 查看配置信息
git config --list

2. 仓库初始化

创建新的 Git 仓库:

# 初始化新仓库
git init

# 克隆远程仓库
git clone <repository-url>

日常工作命令

3. 状态查看

实时了解仓库状态:

# 查看工作区状态
git status

# 查看简化状态信息
git status -s

# 查看分支情况
git branch -v

4. 添加和提交

基本的版本控制操作:

# 添加指定文件到暂存区
git add <file-name>

# 添加所有更改
git add .

# 提交到本地仓库
git commit -m "commit message"

# 添加并提交
git commit -am "commit message"

5. 分支操作

分支管理是 Git 的核心功能:

# 创建新分支
git branch <branch-name>

# 切换分支
git checkout <branch-name>

# 创建并切换分支
git checkout -b <branch-name>

# 删除分支
git branch -d <branch-name>

高级协作命令

6. 远程仓库操作

与远程仓库交互:

# 添加远程仓库
git remote add origin <repository-url>

# 查看远程仓库
git remote -v

# 推送到远程
git push origin <branch-name>

# 拉取远程更新
git pull origin <branch-name>

7. 合并与衍合

处理分支合并:

# 合并分支
git merge <branch-name>

# 变基操作
git rebase <branch-name>

# 解决冲突后继续变基
git rebase --continue

8. 暂存操作

临时保存工作进度:

# 保存当前工作进度
git stash

# 查看存储的工作进度
git stash list

# 恢复最近的进度
git stash pop

# 删除所有进度
git stash clear

高级查看命令

9. 日志查看

查看提交历史:

# 查看提交日志
git log

# 查看简化日志
git log --oneline

# 查看图形化日志
git log --graph --pretty=oneline --abbrev-commit

10. 差异比较

比较文件差异:

# 查看工作区和暂存区的差异
git diff

# 查看暂存区和最新提交的差异
git diff --staged

# 查看两个分支的差异
git diff <branch1> <branch2>

撤销与重置

11. 撤销操作

修正错误操作:

# 撤销工作区的修改
git checkout -- <file-name>

# 撤销暂存区的修改
git reset HEAD <file-name>

# 创建反向提交
git revert <commit-id>

6. vue 生命周期

直接上图

vue生命周期.png

1. 创建阶段

创建阶段是 Vue 实例初始化的过程,主要完成数据观察、方法绑定等。

  • beforeCreate
    触发时机:实例初始化后,但数据和方法尚未可用。
    用途:常用于插件初始化或全局变量设置。

  • created
    触发时机:实例初始化完成,数据和方法已可用,但 DOM 尚未挂载。
    用途:常用于初始化数据或调用后端接口。

2. 挂载阶段

挂载阶段是将 Vue 实例与 DOM 关联的过程。

  • beforeMount
    触发时机:模板编译完成,但还未挂载到真实 DOM 上。
    用途:可以调整数据,但不影响 DOM。

  • mounted
    触发时机:实例挂载到真实 DOM 后。
    用途:常用于初始化第三方插件或直接操作 DOM。

3. 运行阶段

运行阶段是组件响应式数据驱动视图更新的过程。

  • beforeUpdate
    触发时机:响应式数据变化,虚拟 DOM 更新前。
    用途:适合做更新前的数据快照。

  • updated
    触发时机:数据变化后,虚拟 DOM 更新完成。
    用途:可以进行与更新后的 DOM 相关的操作。

4. 销毁阶段

销毁阶段是 Vue 实例结束生命周期的过程。

  • beforeDestroy
    触发时机:实例销毁前,数据和方法仍然可用。
    用途:常用于清理定时器或事件监听。

  • destroyed
    触发时机:实例销毁后,数据和方法已不可用。
    用途:清理收尾工作,确认实例已完全移除。

四个阶段的八个钩子函数

生命周期钩子常见用途示例操作
beforeCreate插件初始化、全局设置初始化配置
created数据初始化、后端接口调用设置 data,发送网络请求
beforeMount数据调整最后修改数据
mounted操作真实 DOM、初始化插件使用第三方库,如 swiper
beforeUpdate数据快照日志记录
updated操作更新后的 DOM修改已更新的 DOM
beforeDestroy清理资源清理定时器、解绑事件监听
destroyed收尾工作确认销毁完成