vue实现列表自动滚动(纯与原生方式)

Vue实现列表自动滚动(纯与原生方式)

源码放在最后!

1.效果展示:

请添加图片描述

2.功能说明:

该滚动可能存在的Bug:

  • 1.如果你写的大屏不是使用的接口轮询的方式可能会存在也页面空白的情况(需要手动刷新才能触发列表滚动),因为我使用的是监听数据的变化然后做出响应,一般来说写大屏都会有个数据更新的机制。这一点需要你对源码进行改动。

3.原理分析:

1.核心数据和变量:
  • CityData:包含了所有的表格数据,是一个二维数组,每一行数据代表一个城市的信息。
  • CURRENTDATA:存储当前显示在屏幕上的行数据,动态更新以实现滚动效果。
  • COLUMNHEIGHT:存储每一行的高度,在滚动时通过调整前几行的高度来实现滑动效果。
  • CURRENTINDEX:表示当前显示的首行索引,在滚动过程中不断递增,最终通过循环回到起始行。
2.数据初始化:

当组件挂载时,会通过 onMounted 钩子初始化表格数据。关键步骤包括:

  • 计算每列的宽度 HandelHeaderAverageWidthHandelColumnAverageWidth
  • 计算行的高度 HandelAverageHeight
  • 格式化数据并初始化 CityData,为每一行数据添加索引列,并根据 Alluserdata 动态填充内容。
3.高度变化实现(核心!)

滚动动画的关键在于每行的高度如何变化。为了模拟滚动,我们让行逐渐“消失”并再“出现”。具体实现步骤如下:

  • 初始行高度:表格中的每一行都有固定的高度,在初始化时通过 HandelAverageHeight 计算每行的平均高度,并将结果存储在 COLUMNHEIGHT 中。

    const HandelAverageHeight = () => {
        const AverageHeight = height.value / columnNumber.value;
        AverageHeighT.value = AverageHeight;
        const TotalCount = 23;  // 表示总的行数
        COLUMNHEIGHT.value = new Array(TotalCount).fill(AverageHeight);
    };
    

    例如,假设每行的高度为 50px,这意味着表格中的所有行在初始时都是统一高度的。

  • 高度变化模拟滚动:在开始动画时,StartAnimation 函数负责将某些行的高度设置为 0,模拟这些行滚动出可视区域。

    COLUMNHEIGHT.value.splice(0, MoveNumber, ...new Array(MoveNumber).fill(0));
    

    这个 splice 操作将 COLUMNHEIGHT 数组中前 MoveNumber 行的高度设置为 0,因此这些行会逐渐缩小到不可见,产生滚动的效果。

    当行的高度变为 0 时,浏览器会根据 CSS 的 transition 动画特性让该行逐渐收缩,这就是为什么行从视野中“滑动”出去,而不是瞬间消失。

4.数据无限循环的过程:

为了让滚动效果无限循环,需要对 CityData(存储所有表格数据)和 CURRENTDATA(存储当前显示的行数据)进行操作,使得数据能够循环显示。

  • 当前索引控制:通过 CURRENTINDEX 控制当前显示的起始行。在每次动画开始时,会计算新的起始行索引,并根据这个索引来更新当前显示的数据。

    const alldataLenght = CityData.value.length;  // 获取所有数据的长度
    const MoveNumber = 1;  // 表示每次滚动多少行
    const index = CURRENTINDEX.value;  // 当前滚动的索引
    

    CURRENTINDEX 会随着每次滚动递增,当它达到数据集的长度时,循环回到开头,确保表格数据可以无限滚动。

  • 数据循环拼接:为了避免滚动到最后几行时的“断层”,StartAnimation 函数会将 CityData 从当前索引开始的数据提取出来,并将前面的数据拼接到后面,形成一个无缝连接的效果。

    const rowdata = cloneDeep(CityData.value);  // 深拷贝 CityData 避免直接修改
    const rows = rowdata.slice(index);  // 从当前索引开始提取数据
    rows.push(...rowdata.slice(0, index));  // 将索引之前的行拼接到后面
    

    比如当表格已经滚动到倒数第二行时,slice(index) 提取出剩下的最后几行,而 slice(0, index) 则从头部提取最开始的几行,并将它们拼接在一起。这使得滚动能够无缝连接。

    这样,在 CURRENTDATA 中,数据始终是连续的,模拟了数据无限循环滚动的效果。

5.递归定时器控制滚动:

滚动效果通过递归调用 StartAnimation 来实现,每次滚动后等待一段时间,然后再执行下一次滚动。这就像一个“无尽的循环”,使表格持续滚动。

  • 延迟机制:在每次滚动之前,会通过 await 等待一段时间,控制滚动的速度。

    await new Promise(resolve => setTimeout(resolve, awaitTime));  // 等待500ms
    

    这里的 awaitTime 控制了滚动的速度,500ms 表示每次滚动间隔 0.5 秒。

  • 高度动画延迟:滚动分为两个阶段,先将行的高度逐渐设置为 0,然后让下一行进入视野。这个过程通过两次 setTimeout 来控制。

    await new Promise(resolve => setTimeout(resolve, 800 - awaitTime));  // 额外等待800ms
    

    这个延迟的机制让滚动变得平滑,防止表格中的数据瞬间跳跃。

4.完整源码

首先你要有pinia、loadsh、uuid这些库

这是我的文件目录,有点不规范,你可以自己修改hook可以抽取一下!
请添加图片描述

PlanList.vue
<template>
    <div class="AutoScrollTabel" :id="ID">
        <div class="header">
            <template v-for="(item, index) in Headerdata">
                <div class="headeritem" :style="{ width: `${AVERAGEWIDTH[index]}px` }">
                    {{ item }}
                </div>
            </template>
        </div>
        <div class="ColumLIst">
            <template v-for="(item, index) in CURRENTDATA" :key="item.Rowindex + '-' + index">
                <div class="itemWrapper"
                    :style="{ height: `${COLUMNHEIGHT[index]}px`, lineHeight: `${COLUMNHEIGHT[index]}px`, backgroundColor: item.Rowindex % 2 === 0 ? BGCOLOR2 : BGCOLOR1 }">
                    <template v-for="(iten, idx) in item.data" :key="item.Rowindex + '-' + idx">
                        <!-- 使用 Rowindex 和 idx 组合,确保每一项唯一 -->
                        <div class="item" :align="align[idx]" :style="{ width: `${COLUMNAVERAGEWIDTH[idx]}px` }"
                            v-html="iten"></div>
                    </template>
                </div>
            </template>
        </div>
    </div>
</template>

<script setup>
import { onMounted, ref, watch, nextTick } from 'vue'
import { v4 as uuidv4 } from 'uuid'
import cloneDeep from 'loadsh/cloneDeep'

import { storeToRefs } from 'pinia' // pinia
import { useAllUserDataStore } from '../../../store/index'; // pinia
const AllUserData = useAllUserDataStore() // pinia
const { Alluserdata } = storeToRefs(AllUserData) // pinia

import init from '../utils/init'
// CityData: 用于存储城市数据的二维数组,每行代表一条记录,每列代表不同的数据项
const CityData = ref([])

// columnIndex: 存储每行数据的索引列,通常用来表示行号或某种标识符
const columnIndex = ref([])

// Headerdata: 存储表格的表头数据,代表每列的标题
const Headerdata = ["城市订单量", "店铺数", "接单骑手人数", "新店铺数量", "人均订单量"]

// AVERAGEWIDTH: 存储表头每列的平均宽度
const AVERAGEWIDTH = ref([])

// COLUMNAVERAGEWIDTH: 存储每列的平均宽度,除了第一列的额外宽度(通常用于索引列)
const COLUMNAVERAGEWIDTH = ref([])

// columnNumber: 表示每列的数量或展示的列数,可能会影响表格的布局
const columnNumber = ref(10)

// AverageHeighT: 存储每行的平均高度,用于控制行高
const AverageHeighT = ref(0)

// COLUMNHEIGHT: 存储每行的高度,用于控制行的高度
const COLUMNHEIGHT = ref([])

// Datalenght: 存储数据的长度,即行数
const Datalenght = ref(0)

// CURRENTINDEX: 当前滚动到的索引位置,用于动画或分页等功能
const CURRENTINDEX = ref(0)

// CURRENTDATA: 存储当前显示的数据,用于表格的内容展示
const CURRENTDATA = ref([])

// ID: 每个表格的唯一标识符,使用 UUID 来确保唯一性
const ID = `BaseScorelist+${uuidv4()}`

// BGCOLOR1: 表格背景颜色 1,用于奇数行或默认背景色
const BGCOLOR1 = 'rgb(55,55,55)'

// BGCOLOR2: 表格背景颜色 2,用于偶数行或替代背景色
const BGCOLOR2 = 'rgb(44,44,44)'

// align: 表格每列的对齐方式,这里是全部居中
const align = ["center", "center", "center", "center", "center", "center"]

const { width, height } = init(ID)
// 生成 UUID 的函数
function generateUUID() {
    return uuidv4();
}
// 处理数据行,将数据转换为适合显示的格式
const Handeldata = () => {
    // 为每一行数据添加行索引
    CityData.value.map((item, index) => {
        item.unshift(columnIndex.value[index])
    })

    // 生成包含行数据和行索引的数组
    const data = CityData.value.map((item, index) => {
        return {
            data: item,
            Rowindex: index
        }
    })

    // 更新 CityData
    CityData.value = data
}

// 处理表头的宽度
const HandelHeaderAverageWidth = () => {
    const needAverage = Headerdata.length
    const currentWidth = 50
    // 计算表头的平均宽度
    const averagewidth = (width.value - currentWidth) / needAverage
    AVERAGEWIDTH.value = new Array(Headerdata.length)
    AVERAGEWIDTH.value.fill(averagewidth)
}
// 处理表格列的平均宽度(除了索引列)
const HandelColumnAverageWidth = () => {
    let needAverage = 5
    const averagewidth = (width.value - 40) / needAverage
    COLUMNAVERAGEWIDTH.value = new Array(5)
    COLUMNAVERAGEWIDTH.value.fill(averagewidth)
    COLUMNAVERAGEWIDTH.value.unshift(50)
}
// 处理每行的平均高度
const HandelAverageHeight = () => {
    const AverageHeight = height.value / columnNumber.value
    AverageHeighT.value = AverageHeight
    const TotalCount = 23
    COLUMNHEIGHT.value = new Array(TotalCount).fill(AverageHeight)
}
// 启动动画,控制表格内容的滚动
const StartAnimation = async () => {
    console.log("111")
    // 获取真实数据长度
    const alldataLenght = CityData.value.length;
    const MoveNumber = 1;
    const index = CURRENTINDEX.value;

    // 当数据长度小于需要移动的数量时,直接退出
    // if (alldataLenght <= MoveNumber) return;
    console.log("进入了动画函数 StartAnimation")

    const rowdata = cloneDeep(CityData.value);
    const rows = rowdata.slice(index); // 获取当前起始位置后的数据

    // 连接数据头尾,避免卡顿
    rows.push(...rowdata.slice(0, index));

    CURRENTDATA.value = rows;
    COLUMNHEIGHT.value = new Array(alldataLenght).fill(AverageHeighT.value);

    const awaitTime = 500;
    await new Promise(resolve => setTimeout(resolve, awaitTime));

    // 更新前几个行的高度为 0
    COLUMNHEIGHT.value.splice(0, MoveNumber, ...new Array(MoveNumber).fill(0));

    // 更新当前索引
    CURRENTINDEX.value += MoveNumber;
    const ISLAST = CURRENTINDEX.value - alldataLenght;
    if (ISLAST >= 0) {
        CURRENTINDEX.value = ISLAST; // 循环回到数据开始位置
    }

    await new Promise(resolve => setTimeout(resolve, 800 - awaitTime));
    await StartAnimation(); // 递归调用自身进行动画
    console.log("调用了动画函数 StartAnimation");
};

watch(() => Alluserdata.value, (NewData) => {
    Datalenght.value = NewData.length;
    CityData.value = [];  // 清空原有数据

    for (let i = 0; i < Datalenght.value; i++) {
        CityData.value[i] = [];
        // 生成列索引和内容
        if (i % 2 === 0) {
            columnIndex.value[i] = `<div style="width:100%; padding-left=5px; height:100%; display:flex; align-items:center; justify-content:center; background:rgb(44,44,44)">
            <div style="width:15px;height:15px;background:rgb(72,122,72);border-radius:50%;border:1px solid #fff;"/>
            </div>`;
        } else {
            columnIndex.value[i] = `<div style="width:100%; height:100%; display:flex; align-items:center; justify-content:center; background:rgb(44,44,44)">
            <div style="width:15px;height:15px;background:rgb(38,88,104);border-radius:50%;border:1px solid #fff;"/>
            </div>`;
        }
        // 生成数据行
        for (let i = 0; i < Datalenght.value; i++) {
            CityData.value[i] = [];

            // 根据行索引来决定前面点的背景颜色
            const pointBgColor = i % 2 === 0 ? 'rgb(44,44,44)' : 'rgb(55,55,55)'; // 偶数行和奇数行的背景颜色

            columnIndex.value[i] = `
        <div style="width:100%; height:100%; display:flex; align-items:center; justify-content:center; background:${pointBgColor}">
            <div style="width:15px;height:15px;background:rgb(72,122,72);border-radius:50%;border:1px solid #fff;"></div>
        </div>`;

            // 生成数据行
            for (let j = 0; j < 5; j++) {
                let text = '';
                switch (j) {
                    case 0: text = NewData[i].order; break;
                    case 1: text = NewData[i].shop; break;
                    case 2: text = NewData[i].rider; break;
                    case 3: text = NewData[i].newShop; break;
                    case 4: text = NewData[i].avgOrder; break;
                }
                // 其他列的内容颜色保持不变
                if (j === 1 || j === 3) {
                    CityData.value[i].push(`<div style="color:rgb(178,209,126)">${text}</div>`);
                } else {
                    CityData.value[i].push(`<div>${text}</div>`);
                }
            }
        }

    }
    Handeldata();
});

onMounted(() => {

    StartAnimation()
    Handeldata()
    HandelHeaderAverageWidth()
    HandelColumnAverageWidth()
    HandelAverageHeight()
})

</script>

<style scoped lang="less">
.AutoScrollTabel {
    width: 100%;
    height: 100%;
    // margin: 30px;
    user-select: none;
    box-sizing: border-box;

    .header {
        display: flex;
        align-items: center;
        // justify-content: space-around;
        background-color: rgb(90, 90, 90);
        color: rgb(255, 255, 255);
        padding-left: 50px;

        .headeritem {
            font-size: 15px;
            padding: 10px 0;
            text-align: center;
        }

    }

    .ColumLIst {
        .itemWrapper {
            overflow: hidden;
            display: flex;
            font-size: 30px;
            align-items: center;
            transition: all 0.3s linear;

            .item {
                width: 100%;
                height: 100%;
                overflow: hidden;
                text-align: center;
                // align-items: center;
                font-size: 20px;
                // padding: 10px 0px;
            }
        }

    }
}
</style>
init.ts
import { ref, onMounted } from 'vue'

const init = (id: string) => {
    const width = ref<number>(0)
    const height = ref<number>(0)

    // 获取 dom
    onMounted(() => {
        const container = document.getElementById(id) as HTMLElement | null
        if (container) {
            const domwidth = container.clientWidth
            const domheight = container.clientHeight
            // 初始化宽高
            width.value = domwidth
            height.value = domheight
        }
    })

    return {
        width,
        height
    }
}

export default init
PanList文件夹下的Index.vue
<template>
    <div class="plan-list">
        <div class="title">区域销售大盘环比分析</div>
        <div class="planlistScore">
            <PanlList />

        </div>
    </div>
</template>

<script setup>
import { onMounted } from 'vue';
import PanlList from './cpns/PanlList.vue';

import { useAllUserDataStore } from '../../store/index'; // 引入 Pinia store

// 获取 Pinia store 实例
const AllUserDataStore = useAllUserDataStore();

// 定义更新数据函数
const updateData = () => {
    // 直接触发更新,而不是生成随机数据
    const newData = AllUserDataStore.getAllUserData();  // 假设这个函数获取当前的用户数据
    AllUserDataStore.setAllUserData(newData); // 直接更新数据
};

// 使用 onMounted 生命周期钩子来定时更新数据
onMounted(() => {
    // 每隔 3 秒触发一次更新
    setInterval(() => {
        updateData();
    }, 1000); // 每 3 秒更新一次
});
</script>

<style scoped lang="less">
.plan-list {
    width: 100%;
    height: 100%;
    background: rgb(55, 55, 55);
    padding: 20px 10px;
    color: #fff;
    box-sizing: border-box;

    .title {
        font-size: 26px;
        text-align: center;
    }

    .planlistScore {
        width: 100%;
        height: calc(100% - 40px);
        background: rgb(40, 40, 40);
        overflow: hidden;
    }
}
</style>
Store文件夹下面的index.ts
import { defineStore } from 'pinia'

// 定义 `UserData` 数据结构类型
interface UserData {
    order: string;  // 修改为 string 类型
    shop: string;   // 修改为 string 类型
    rider: string;  // 修改为 string 类型
    newShop: string; // 修改为 string 类型
    avgOrder: string; // 修改为 string 类型
    Rowindex?: number; // 添加 RowIndex 字段
}

// 定义 store
export const useAllUserDataStore = defineStore('AllUserData', {
    state: (): { Alluserdata: UserData[] } => ({
        Alluserdata: [
            { "order": "北京 -17%", "shop": "北京 -3%", "rider": "北京 +20%", "newShop": "北京 +14%", "avgOrder": "北京 -16%" },
            { "order": "上海 -19%", "shop": "上海 +12%", "rider": "上海 -15%", "newShop": "上海 +15%", "avgOrder": "上海 -21%" },
            { "order": "广州 +20%", "shop": "广州 -5%", "rider": "广州 +17%", "newShop": "广州 -15%", "avgOrder": "广州 +10%" },
            { "order": "深圳 -4%", "shop": "深圳 -23%", "rider": "深圳 -5%", "newShop": "深圳 +15%", "avgOrder": "深圳 -4%" },
            { "order": "南京 +10%", "shop": "南京 -6%", "rider": "南京 -7%", "newShop": "南京 -5%", "avgOrder": "南京 -22%" },
            { "order": "杭州 -3%", "shop": "杭州 +20%", "rider": "杭州 +16%", "newShop": "杭州 -11%", "avgOrder": "杭州 -17%" },
            { "order": "合肥 +8%", "shop": "合肥 +17%", "rider": "合肥 -23%", "newShop": "合肥 +6%", "avgOrder": "合肥 -11%" },
            { "order": "济南 -13%", "shop": "济南 -11%", "rider": "济南 +6%", "newShop": "济南 -7%", "avgOrder": "济南 +18%" },
            { "order": "太原 -11%", "shop": "太原 -10%", "rider": "太原 +18%", "newShop": "太原 -14%", "avgOrder": "太原 -2%" },
            { "order": "成都 +19%", "shop": "成都 -6%", "rider": "成都 +14%", "newShop": "成都 -19%", "avgOrder": "成都 +10%" },
            { "order": "重庆 -12%", "shop": "重庆 +12%", "rider": "重庆 +12%", "newShop": "重庆 +7%", "avgOrder": "重庆 -3%" },
            { "order": "苏州 +15%", "shop": "苏州 +18%", "rider": "苏州 -8%", "newShop": "苏州 -3%", "avgOrder": "苏州 +4%" },
            { "order": "无锡 -15%", "shop": "无锡 -19%", "rider": "无锡 -14%", "newShop": "无锡 +21%", "avgOrder": "无锡 -21%" },
            { "order": "常州 +12%", "shop": "常州 +10%", "rider": "常州 +5%", "newShop": "常州 -22%", "avgOrder": "常州 -13%" },
            { "order": "温州 -14%", "shop": "温州 -16%", "rider": "温州 -15%", "newShop": "温州 +14%", "avgOrder": "温州 +17%" },
            { "order": "哈尔滨 +5%", "shop": "哈尔滨 -18%", "rider": "哈尔滨 -18%", "newShop": "哈尔滨 -18%", "avgOrder": "哈尔滨 -20%" },
            { "order": "长春 +14%", "shop": "长春 -5%", "rider": "长春 -17%", "newShop": "长春 +18%", "avgOrder": "长春 +4%" },
            { "order": "大连 -4%", "shop": "大连 -15%", "rider": "大连 -22%", "newShop": "大连 +14%", "avgOrder": "大连 +14%" },
            { "order": "沈阳 -1%", "shop": "沈阳 -21%", "rider": "沈阳 -15%", "newShop": "沈阳 +24%", "avgOrder": "沈阳 +8%" },
            { "order": "拉萨 +18%", "shop": "拉萨 +5%", "rider": "拉萨 -6%", "newShop": "拉萨 -24%", "avgOrder": "拉萨 -10%" },
            { "order": "呼和浩特 +14%", "shop": "呼和浩特 -12%", "rider": "呼和浩特 +8%", "newShop": "呼和浩特 +9%", "avgOrder": "呼和浩特 -21%" },
            { "order": "武汉 -21%", "shop": "武汉 +13%", "rider": "武汉 -10%", "newShop": "武汉 -14%", "avgOrder": "武汉 +10%" },
            { "order": "南宁 -22%", "shop": "南宁 +23%", "rider": "南宁 -9%", "newShop": "南宁 +6%", "avgOrder": "南宁 -12%" }
        ] // 初始数据
    }),
    actions: {
        // 更新数据,并保持 RowIndex 一致
        setAllUserData(newData: UserData[]) {
            // 更新数据时可以保持 RowIndex
            this.Alluserdata = newData.map((item, index) => ({
                ...item,
                Rowindex: index + 1 // 给每一行加上递增的 RowIndex,从 1 开始
            }));
            console.log("Store updated");
        },
        // 添加新数据
        addData(data: UserData) {
            const newRowIndex = this.Alluserdata.length ? Math.max(...this.Alluserdata.map(item => item.Rowindex!)) + 1 : 1;
            this.Alluserdata.push({ ...data, Rowindex: newRowIndex });
        },

        getAllUserData() {
            return this.Alluserdata;
        }
    }
});
App.vue
<template>
  <div class="Wrapper">
    <div class="PanListWrapper">
      <PanList></PanList>
    </div>
  </div>
</template>

<script setup lang="ts">
import PanList from './components/PanList/index.vue'

</script>

<style scoped lang="less">
.Wrapper {
  width: 100%;
  height: 100vh;
  display: flex;
  align-items: center;
  justify-content: center;

  .PanListWrapper {
    width: 700px;
    height: 700px;
  }
}
</style>

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/890189.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【C++】关联式容器——map和set的使用

文章目录 一、 序列式容器和关联式容器二、set的介绍1.set的构造和迭代器2.set的增删查3.接口lower_bound和upper_bound4.multiset和set的差异 三、map的介绍1.map的构造2.map的增删查3.multimap和map的差异 四、map和set相关OJ 一、 序列式容器和关联式容器 序列式容器&#…

WordPress添加meta标签做seo优化

一、使用function.php文件添加钩子函数添加 方法1、使用is_page()判断不同页面的page_id进行辨别添加不同页面keyword和description &#xff08;1&#xff09;通过页面前台源码查看对应页面的id &#xff08;2&#xff09;或者通过wordpress后台&#xff0c;点击页面列表&…

【网易云音乐】--源代码分享

最近写了一个网易云音乐的音乐实现部分&#xff0c;是通过JavaScript和jQuery实现的&#xff0c;具体效果大家可以参照下面的视频 源代码分享 - git地址: 网易云音乐源代码 下面将着重讲解一下音乐实现部分 视频有点模糊&#xff0c;不好意思&#xff0c;在b站上添加视频的时候…

Ping32:专业的终端安全管理解决方案

在当今数字化转型迅速发展的时代&#xff0c;终端安全管理已成为企业信息安全的重要环节。随着远程办公和移动设备的普及&#xff0c;企业面临着越来越多的网络安全挑战。Ping32作为一款专业的终端安全管理解决方案&#xff0c;以其卓越的性能和易用性&#xff0c;成为众多企业…

[Linux] Linux 进程程序替换

标题&#xff1a;[Linux] Linux 进程程序替换 个人主页水墨不写bug &#xff08;图片来源于网络&#xff09; 目录 O、前言 一、进程程序替换的直观现象&#xff08;什么是进程程序替换&#xff1f;&#xff09; 二、进程程序替换的原理 三、进程程序替换的函数&#xff08…

几种Word Embedding技术详解

NLP 中的词嵌入是一个重要术语&#xff0c;用于以实值向量的形式表示用于文本分析的单词。这是 NLP 的一项进步&#xff0c;提高了计算机更好地理解基于文本的内容的能力。它被认为是深度学习在解决具有挑战性的自然语言处理问题方面最重要的突破之一。 在这种方法中&#xff…

有了WPF后Winform还有活路吗?

近年来&#xff0c;随着技术的不断发展&#xff0c;Windows Presentation Foundation&#xff08;WPF&#xff09;和Windows Forms&#xff08;WinForms&#xff09;这两种技术在开发桌面应用程序方面一直备受关注。虽然WPF以其强大的功能和灵活性吸引了众多开发者&#xff0c;…

快速上手C语言【上】(非常详细!!!)

目录 1. 基本数据类型 2. 变量 2.1 定义格式 和 命名规范 2.2 格式化输入和输出&#xff08;scanf 和 printf&#xff09; ​编辑 2.3 作用域和生命周期 3. 常量 4. 字符串转义字符注释 5. 操作符 5.1 双目操作符 5.1.1 算数操作符 5.1.2 移位操作符 5.1.3 位操作符…

架构设计笔记-7-系统架构设计基础知识

目录 知识要点 单选 案例分析 1.质量属性 / 管道过滤器 / 数据仓库风格 2.面向对象风格 / 控制环路风格 3.软件架构风格 / 架构风格选择 4.体系结构方案对比 5.面向对象风格 / 基于规则风格 6.解释器风格 / 管道过滤器风格 7.面向对象风格 / 解释器风格 8.软件架构复…

【宝可梦】游戏

pokemmo https://pokemmo.com/zh/ 写在最后&#xff1a;若本文章对您有帮助&#xff0c;请点个赞啦 ٩(๑•̀ω•́๑)۶

OpenCV 环境配置

首先下载opencv&#xff0c;在opencv官网进行下载。 按照上面的步骤&#xff0c;点击进去 滑至底部&#xff0c;不切换至不同页&#xff0c;选择合适的版本进行下载(Window系统选择Windows版本进行下载)。 接下来以4.1.2版本为例&#xff1a; 点击之后会进入这个页面&#xff…

linux源码安装slurm以及mung和openssl

一、源码安装munge 1、编译安装munge &#xff08;1&#xff09;下载munge地址&#xff1a;https://github.com/dun/munge/releases &#xff08;2&#xff09;解压编译安装&#xff1a; 1 2 3 4 5 6 7 8 创建/data目录 复制文件munge-0.5.15.tar.xz 到/data目录下 tar -Jx…

闭着眼学机器学习——朴素贝叶斯分类

引言&#xff1a; 在正文开始之前&#xff0c;首先给大家介绍一个不错的人工智能学习教程&#xff1a;https://www.captainbed.cn/bbs。其中包含了机器学习、深度学习、强化学习等系列教程&#xff0c;感兴趣的读者可以自行查阅。 1. 算法介绍 朴素贝叶斯是一种基于贝叶斯定理…

C# 屏幕录制工具

屏幕录制工具 开发语音&#xff1a;C# vb.net 下载地址&#xff1a;https://download.csdn.net/download/polloo2012/89879996 功能&#xff1a;屏幕录制&#xff0c;声卡采集&#xff0c;麦克风采集。 屏幕录制&#xff1a;录制屏幕所有操作&#xff0c;并转换视频格式&…

uniapp-小程序开发0-1笔记大全

uniapp官网&#xff1a; https://uniapp.dcloud.net.cn/tutorial/syntax-js.html uniapp插件市场&#xff1a; https://ext.dcloud.net.cn/ uviewui类库&#xff1a; https://www.uviewui.com/ 柱状、扇形、仪表盘库&#xff1a; https://www.ucharts.cn/v2/#/ CSS样式&…

Springboot 接入 WebSocket 实战

Springboot 接入 WebSocket 实战 前言&#xff1a; WebSocket协议是基于TCP的一种新的网络协议。它实现了浏览器与服务器全双工(full-duplex)通信——允许服务器主动发送信息给客户端。 简单理解&#xff1a; 1&#xff0c;常见开发过程中我们知道 Http协议&#xff0c;客户端…

详解安卓和IOS的唤起APP的机制,包括第三方平台的唤起方法比如微信

网页唤起APP是一种常见的跨平台交互方式&#xff0c;它允许用户从网页直接跳转到移动应用程序。 这种技术广泛应用于各种场景&#xff0c;比如让用户在浏览器中点击链接后直接打开某个应用&#xff0c;或者从网页引导用户下载安装应用。实现这一功能主要依赖于URL Scheme、Univ…

QD1-P21-P22 CSS 基础语法、注释、使用方法

本节学习&#xff1a;CSS 基础语法和注释&#xff0c;以及如何使用CSS定义的样式。 本节视频 https://www.bilibili.com/video/BV1n64y1U7oj?p21 CSS 基本语法 CSS&#xff08;层叠样式表&#xff09;的基本语法相对简单&#xff0c;由选择器和一组包含在花括号 {}​ 中的声…

深入Postman- 自动化篇

前言 在前两篇博文《Postman使用 - 基础篇》《玩转Postman:进阶篇》中,我们介绍了 Postman 作为一款专业接口测试工具在接口测试中的主要用法以及它强大的变量、脚本功能,给测试工作人员完成接口的手工测试带来了极大的便利。其实在自动化测试上,Postman 也能进行良好的支…

【Adobe全家桶】 Adobe 全家桶 AE AU PR ME WIN MAC 各个版本

话不多说今天直接分享 Adobe 全家桶&#xff0c;2017-2024版本 包含 window版本 和MAC版本 Adobe Photoshop 2017-2023 CS5-6 mac版本下载地址 WIN版本下载地址 Adobe After Effects 2017-2024 CS5-6 WIN版本下载地址 mac版本下载地址 Adobe Media Encoder 2017-2024 WIN版…