工作中的笔记整理,记录下来,方便下次使用
1. 视频图片轮播
1. vue2 版本的视频和图片混合轮播
效果如下:
- 安装 "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)
- 可实现代码如下:接口换成自己的接口就可以
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 数据量大的情况下使用虚拟滚动
- 安装:
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: []
}
}
- el-table-virtual-scroll 组件
- 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 |
- 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 | 【扩展树形表格】收起所有树节点,懒加载节点除外 | - |
- 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 事件集合
来自于网络资源整理:
一:鼠标事件
-
click
当用户点击元素时触发。javascriptdocument.getElementById('myButton').addEventListener('click', () => { alert('按钮被点击了!'); });
-
dblclick
当用户双击元素时触发。javascriptdocument.getElementById('myDiv').addEventListener('dblclick', () => { alert('区域被双击了!'); });
-
mousedown
当用户按下鼠标按钮时触发。javascriptdocument.addEventListener('mousedown', (event) => { console.log('鼠标按钮被按下:', event.button); });
-
mouseup
当用户松开鼠标按钮时触发。javascriptdocument.addEventListener('mouseup', () => { console.log('鼠标按钮被松开'); });
-
mousemove
当用户在元素上移动鼠标时触发。javascriptdocument.addEventListener('mousemove', (event) => { console.log('鼠标位置:', event.clientX, event.clientY); });
-
mouseenter
当鼠标进入元素时触发。javascriptjavascript 代码解读 复制代码 document.getElementById('myDiv').addEventListener('mouseenter', () => { console.log('鼠标进入区域'); });
-
mouseleave
当鼠标离开元素时触发。javascriptdocument.getElementById('myDiv').addEventListener('mouseleave', () => { console.log('鼠标离开区域'); });
-
wheel
当用户使用鼠标滚轮时触发。javascriptdocument.addEventListener('wheel', (event) => { console.log('滚轮事件:', event.deltaY); });
二:键盘事件
-
keydown
当用户按下键盘上的某个键时触发。javascriptdocument.addEventListener('keydown', (event) => { console.log('按键按下:', event.key); });
-
keyup
当用户松开键盘上的某个键时触发。javascriptdocument.addEventListener('keyup', (event) => { console.log('按键松开:', event.key); });
-
keypress
当用户按下字符键时触发(已弃用)。javascriptdocument.addEventListener('keypress', (event) => { console.log('按键按下:', event.key); });
三:表单事件
-
submit
当用户提交表单时触发。javascriptdocument.getElementById('myForm').addEventListener('submit', (event) => { event.preventDefault(); // 阻止默认的表单提交行为 console.log('表单已提交!'); });
-
change
当用户改变输入框内容时触发。javascriptdocument.getElementById('myInput').addEventListener('change', (event) => { console.log('输入框内容已改变:', event.target.value); });
-
input
当用户输入内容时实时触发(即内容改变时立即触发)。javascriptdocument.getElementById('myInput').addEventListener('input', (event) => { console.log('输入框内容:', event.target.value); });
-
focus
当输入框获得焦点时触发。javascriptdocument.getElementById('myInput').addEventListener('focus', () => { console.log('输入框获得焦点'); });
-
blur
当输入框失去焦点时触发。javascriptdocument.getElementById('myInput').addEventListener('blur', () => { console.log('输入框失去焦点'); });
四:窗口和文档事件
-
load
当整个页面加载完毕,包括所有依赖资源时触发。javascriptwindow.addEventListener('load', () => { console.log('页面完全加载'); });
-
resize
当浏览器窗口大小改变时触发。javascriptwindow.addEventListener('resize', () => { console.log('窗口大小改变:', window.innerWidth, window.innerHeight); });
-
scroll
当用户滚动文档时触发。javascriptwindow.addEventListener('scroll', () => { console.log('页面滚动'); });
-
unload
当文档或子资源被卸载时触发。javascriptwindow.addEventListener('unload', () => { console.log('页面卸载'); });
-
beforeunload
当用户要离开页面时触发,可以用来提示用户是否确认离开。javascriptwindow.addEventListener('beforeunload', (event) => { event.preventDefault(); event.returnValue = '你确定要离开吗?'; });
五:触控事件
-
touchstart
当用户手指触碰触控板时触发。javascriptdocument.addEventListener('touchstart', (event) => { console.log('触控开始'); });
-
touchmove
当用户手指在触控板上移动时触发。javascriptdocument.addEventListener('touchmove', (event) => { console.log('触控移动'); });
-
touchend
当用户手指离开触控板时触发。javascriptdocument.addEventListener('touchend', (event) => { console.log('触控结束'); });
六:剪贴板事件
-
copy
当用户复制内容时触发。javascriptdocument.addEventListener('copy', () => { console.log('内容已复制到剪贴板'); });
-
cut
当用户剪切内容时触发。javascriptdocument.addEventListener('cut', () => { console.log('内容已剪切到剪贴板'); });
-
paste
当用户粘贴内容时触发。javascriptdocument.addEventListener('paste', () => { console.log('内容已粘贴从剪贴板'); });
七:媒体事件
-
play
当媒体开始播放时触发。javascriptconst video = document.getElementById('myVideo'); video.addEventListener('play', () => { console.log('视频正在播放'); });
-
pause
当媒体暂停时触发。javascriptvideo.addEventListener('pause', () => { console.log('视频已暂停'); });
-
ended
当媒体播放完毕时触发。javascriptvideo.addEventListener('ended', () => { console.log('视频播放结束'); });
-
volumechange
当音量改变时触发。javascriptvideo.addEventListener('volumechange', () => { console.log('音量已改变为:', video.volume); });
-
canplay
当浏览器能够播放媒体时触发。javascriptvideo.addEventListener('canplay', () => { console.log('浏览器能够播放视频'); });
-
canplaythrough
当浏览器能够播放整个媒体时触发。javascriptvideo.addEventListener('canplaythrough', () => { console.log('浏览器能够播放整个视频'); });
-
durationchange
当媒体时长改变时触发。javascriptvideo.addEventListener('durationchange', () => { console.log('视频时长改变'); });
-
emptied
当媒体数据被清空时触发。javascriptjavascript 代码解读 复制代码 video.addEventListener('emptied', () => { console.log('视频数据被清空'); });
-
error
当媒体加载失败时触发。javascriptvideo.addEventListener('error', () => { console.log('视频加载失败'); });
-
loadeddata
当媒体数据已加载到浏览器时触发。javascriptvideo.addEventListener('loadeddata', () => { console.log('视频数据已加载'); });
-
loadedmetadata
当媒体元数据已加载到浏览器时触发。javascriptvideo.addEventListener('loadedmetadata', () => { console.log('视频元数据已加载'); });
-
loadstart
当媒体开始加载时触发。javascriptvideo.addEventListener('loadstart', () => { console.log('视频开始加载'); });
-
progress
当媒体加载进度改变时触发。javascriptvideo.addEventListener('progress', () => { console.log('视频加载进度改变'); });
-
ratechange
当媒体播放速度改变时触发。javascriptvideo.addEventListener('ratechange', () => { console.log('视频播放速度改变'); });
-
seeking
当用户正在寻求视频中的特定位置时触发。javascriptvideo.addEventListener('seeking', () => { console.log('用户正在寻找视频中的特定位置'); });
八:自定义事件
-
CustomEvent
创建和触发自定义事件。javascriptconst event = new CustomEvent('myCustomEvent', { detail: { key: 'value' } }); document.dispatchEvent(event); document.addEventListener('myCustomEvent', (e) => { console.log('自定义事件触发:', e.detail); });
九:其他值得注意的事件
-
focusin
当元素或其任何子元素获得焦点时触发。javascriptdocument.getElementById('myInput').addEventListener('focusin', () => { console.log('输入框或其子元素获得焦点'); });
-
focusout
当元素或其任何子元素失去焦点时触发。javascriptdocument.getElementById('myInput').addEventListener('focusout', () => { console.log('输入框或其子元素失去焦点'); });
-
contextmenu
当用户点击鼠标右键时触发。javascriptdocument.addEventListener('contextmenu', (event) => { event.preventDefault(); // 阻止默认的右键菜单 console.log('自定义右键菜单打开'); });
-
animationstart
当 CSS 动画开始时触发。javascriptdocument.getElementById('myElement').addEventListener('animationstart', () => { console.log('动画开始'); });
-
animationend
当 CSS 动画结束时触发。javascriptdocument.getElementById('myElement').addEventListener('animationend', () => { console.log('动画结束'); });
-
transitionend
当 CSS 过渡结束时触发。javascriptdocument.getElementById('myElement').addEventListener('transitionend', () => { console.log('过渡结束'); });
-
abort
当用户中止媒体加载时触发。javascriptconst 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 | 收尾工作 | 确认销毁完成 |