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

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

1. 视频图片轮播

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

效果如下:

  1. 安装 "vue-video-player": "^5.0.1"
JS 复制代码
npm install vue-video-player@5.0.1

2:全局引入main.js

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. 可实现代码如下:接口换成自己的接口就可以
js 复制代码
<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

js 复制代码
npm install video.js @videojs-player/vue --save

2:全局 main.ts中引入

js 复制代码
import VideoPlayer from '@videojs-player/vue'
import 'video.js/dist/video-js.css'
js 复制代码
<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. 安装:
css 复制代码
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属性。

js 复制代码
<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 必填
keyProp key值,data数据中的唯一id【⚠️若keyProp未设置或keyProp值不唯一,可能导致表格空数据或者滚动时渲染的数据断层、不连贯、滚动不了】 string --- id
itemSize 每一行的预估高度 number --- 60
scrollBox 指定滚动容器;在指定滚动容器时,如果表格设置了height高度,则滚动容器为表格内的滚动容器;如果表格未设置height高度,则自动获取外层的滚动容器,直至window容器为止 string 'window'、css选择器 -
buffer 顶部和底部缓冲区域,值越大显示表格的行数越多 Number --- 200
throttleTime 滚动事件的节流时间 number --- 16
dynamic 动态获取表格行高度,默认开启。设置为false时,则以itemSize为表格行的真实高度,能大大减少虚拟滚动计算量,减少滚动白屏;如果itemSize与表格行的真实高度不一致,可能导致滚动时表格数据错乱、抖动、底部有空白 boolean --- true
virtualized 是否开启虚拟滚动 boolean --- true
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 切换表格显示时,会保持原来滚动位置 boolean --- true
  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. 递归调用创建树

完整可实现代码:

html 复制代码
<!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创建树

js 复制代码
    /**
     * 将扁平化的目录数据转换为树形结构
     * @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. 查找多棵树中节点的完整路径

完整可运行代码如下:

html 复制代码
<!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 当用户点击元素时触发。

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

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

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

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

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

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

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

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

二:键盘事件

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

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

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

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

三:表单事件

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

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

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

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

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

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

四:窗口和文档事件

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

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

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

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

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

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

五:触控事件

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

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

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

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

六:剪贴板事件

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

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

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

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

七:媒体事件

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

八:自定义事件

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

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

九:其他值得注意的事件

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

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

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

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

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

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

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

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

5. git基础配置命令

1. 初始化配置

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

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

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

2. 仓库初始化

创建新的 Git 仓库:

js 复制代码
# 初始化新仓库
git init

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

日常工作命令

3. 状态查看

实时了解仓库状态:

js 复制代码
# 查看工作区状态
git status

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

# 查看分支情况
git branch -v

4. 添加和提交

基本的版本控制操作:

js 复制代码
# 添加指定文件到暂存区
git add <file-name>

# 添加所有更改
git add .

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

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

5. 分支操作

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

js 复制代码
# 创建新分支
git branch <branch-name>

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

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

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

高级协作命令

6. 远程仓库操作

与远程仓库交互:

js 复制代码
# 添加远程仓库
git remote add origin <repository-url>

# 查看远程仓库
git remote -v

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

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

7. 合并与衍合

处理分支合并:

js 复制代码
# 合并分支
git merge <branch-name>

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

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

8. 暂存操作

临时保存工作进度:

js 复制代码
# 保存当前工作进度
git stash

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

# 恢复最近的进度
git stash pop

# 删除所有进度
git stash clear

高级查看命令

9. 日志查看

查看提交历史:

js 复制代码
# 查看提交日志
git log

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

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

10. 差异比较

比较文件差异:

js 复制代码
# 查看工作区和暂存区的差异
git diff

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

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

撤销与重置

11. 撤销操作

修正错误操作:

js 复制代码
# 撤销工作区的修改
git checkout -- <file-name>

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

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

6. vue 生命周期

直接上图

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 收尾工作 确认销毁完成
相关推荐
LCG元1 小时前
Vue.js组件开发-如何实现路由懒加载
vue.js
m0_672449601 小时前
基础vue3前端登陆注册界面以及主页面设计
前端·vue.js·elementui
匹马夕阳1 小时前
Vue3中使用组合式API通过路由传值详解
前端·javascript·vue.js
zpjing~.~1 小时前
VUE中css样式scope和deep
前端·css·vue.js
fxshy1 小时前
Vue3父子组件双向绑定值用例
前端·javascript·vue.js
LCG元1 小时前
Vue.js组件开发-如何实现表头搜索
vue.js
风茫1 小时前
如何在vue中渲染markdown内容?
前端·javascript·vue.js
蓝黑20202 小时前
从Vant图标的CSS文件提取图标文件
前端·css·python·vant
勤劳的进取家2 小时前
XML、HTML 和 JSON 的区别与联系
前端·python·算法
IT培训中心-竺老师3 小时前
Apache Web服务器技术指南 - 基于Kylin麒麟操作系统
服务器·前端·apache