...
 
Commits (2)
    https://gitcode.net/qq_39019768/test_git/-/commit/3798aec5828b5d2aecb36a4f58da9cfb548c74aa 2023-10-30 2023-10-30T17:05:24+08:00 wuyb wuyb@phxg.cn https://gitcode.net/qq_39019768/test_git/-/commit/77d375c143d563d7dcb0105a5d09bffe2f9c7941 2023-10-30 2023-11-03T08:58:00+08:00 wuyb wuyb@phxg.cn
......@@ -6,7 +6,7 @@ git stash
恢复暂存的代码
stash apply
wyb123456
保存当前未commit的代码并添加备注
git stash save "备注的内容"
......@@ -45,4 +45,4 @@ git log
[Git不要只会pull和push,学学这5条提高效率的命令](https://mp.weixin.qq.com/s/2_ad5DRsrD_LVqmp-EmMmw)
https://blog.csdn.net/yxlshk/article/details/79944535
\ No newline at end of file
https://blog.csdn.net/yxlshk/article/details/79944535
......@@ -135,6 +135,11 @@
"@otplib/plugin-thirty-two": "^12.0.1"
}
},
"@popperjs/core": {
"version": "npm:@sxzz/popperjs-es@2.11.7",
"resolved": "https://registry.npmjs.org/@sxzz/popperjs-es/-/popperjs-es-2.11.7.tgz",
"integrity": "sha512-Ccy0NlLkzr0Ex2FKvh2X+OyERHXJ88XJ1MXtsI9y9fGexlaXaVTPzBCRBwIxFkORuOb+uBqeu+RqnpgYTEZRUQ=="
},
"@rollup/plugin-node-resolve": {
"version": "13.1.3",
"resolved": "https://registry.npmjs.org/@rollup/plugin-node-resolve/-/plugin-node-resolve-13.1.3.tgz",
......@@ -714,11 +719,6 @@
"normalize-wheel-es": "^1.2.0"
},
"dependencies": {
"@popperjs/core": {
"version": "npm:@sxzz/popperjs-es@2.11.7",
"resolved": "https://registry.npmjs.org/@sxzz/popperjs-es/-/popperjs-es-2.11.7.tgz",
"integrity": "sha512-Ccy0NlLkzr0Ex2FKvh2X+OyERHXJ88XJ1MXtsI9y9fGexlaXaVTPzBCRBwIxFkORuOb+uBqeu+RqnpgYTEZRUQ=="
},
"async-validator": {
"version": "4.2.5",
"resolved": "https://registry.npmmirror.com/async-validator/-/async-validator-4.2.5.tgz",
......@@ -1864,6 +1864,11 @@
"is-plain-object": "3.0.1"
}
},
"vue-virtual-scroll-list": {
"version": "2.3.5",
"resolved": "https://registry.npmjs.org/vue-virtual-scroll-list/-/vue-virtual-scroll-list-2.3.5.tgz",
"integrity": "sha512-YFK6u5yltqtAOfTBcij/KGAS2SoZvzbNIAf9qTULauPObEp53xj22tDuohrrM2vNkgoD5kejXICIUBt2Q4ZDqQ=="
},
"vue-virtual-scroller": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/vue-virtual-scroller/-/vue-virtual-scroller-1.1.2.tgz",
......
......@@ -28,6 +28,7 @@
"vue-json-excel": "^0.3.0",
"vue-qr": "^4.0.9",
"vue-router": "^4.0.14",
"vue-virtual-scroll-list": "^2.3.5",
"vuex": "^4.0.2",
"xlsx": "^0.17.0"
},
......
<template>
<div class='multiseriate'>
<div class="wrapper" ref="wrapper" @scroll="wrapperScroll($event)">
<div class="wrapper-scroll" :style="{ height: containerHeight + 'px' }" style="position: relative;">
<div :style="{ transform: `translateY(${scrollTopWrapper}px)` }"
style="position: absolute; width: 100%;">
<slot :Items="showItem"></slot>
</div>
</div>
</div>
</div>
</template>
<script setup>
import {computed, nextTick, ref} from "vue";
const props = defineProps({
data: {
type: Array,
default: () => {
return []
}
},
column: {
type: Number,
default: 1
},
columnHeight: {
type: Number,
default: 40
}
})
const emits = defineEmits(['scroll'])
let arr = ref(props.data)
// 列高
let columnHeight = ref(props.columnHeight)
// 列数
let columnNum = ref(props.column)
//容器真实高度
let column = Math.ceil(arr.value.length / columnNum.value)
let containerHeight = ref(column * columnHeight.value);
//当前状态的索引
let startKey = ref(0);
//视窗内应该显示的 DOM 数量
let showItemNum = ref(0);
//容器dom节点
const wrapper = ref(null);
//容器高度
let wrapperHeight = ref(0);
nextTick(() => {
//获取容器高度
wrapperHeight.value = wrapper.value.clientHeight;
//运算出应该显示的 DOM 数量
showItemNum.value = Math.ceil(wrapperHeight.value / columnHeight.value * columnNum.value);
});
//片段容器偏移量
let scrollTopWrapper = ref(0);
//滚动事件
const wrapperScroll = (e) => {
// console.log('e', e);
//计算当前状态的索引
let tempNum = Math.floor(e.target.scrollTop / columnHeight.value * columnNum.value);
//当前状态的索引发生变化才触发视图层刷新
if (tempNum !== startKey.value) {
startKey.value = tempNum
scrollTopWrapper.value = e.target.scrollTop;
}
emits('scroll', e, showItem)
};
//对数据进行切片处理方法
const showItem = computed(() => {
return [...arr.value.slice(startKey.value, showItemNum.value + startKey.value + 3)];
});
</script>
<script>
import {defineComponent} from 'vue'
export default defineComponent({
name: 'virtualScroll'
})
</script>
<style lang="less" scoped>
.multiseriate {
.wrapper {
box-sizing: border-box;
position: relative;
width: 100%;
height: 200px;
overflow: auto;
border: 1px solid #ccc;
overflow-x: hidden;
}
.tags {
display: flex;
justify-content: space-between;
}
}
</style>
// let data = [
// { value: 1048, name: '搜索引擎', itemStyle: { color: '#d81e06' } },
// { value: 735, name: '直接访问' },
// { value: 580, name: '邮件营销' },
// { value: 484, name: '联盟广告' },
// { value: 300, name: '视频广告' }
// ]
let data = []
export let optionRoundData = {
tooltip: {
show: true
},
color:['#7293fc','#fd9797','#29edfe'],
legend: {
top: 'center',
selectedMode: false, // 点击事件
left: '40%',
icon: 'path://M289.921-4.311h51.747v1033.041h-51.747v-1033.041z',
align: 'left',
orient: 'vertical',
width: '45%',
itemGap: 0,
itemWidth:'6px',
textStyle: {
padding: [0, 0, 0, -10],
rich: {
nameStyle: {
width: 80,
color: '#333333',
fontSize: 12,
fontWeight: 'bolder',
height: 20
},
valStyle: {
width: 60,
color: '#666666',
fontSize: 12,
fontWeight: '600',
padding: [0, 0]
},
proportionStyle: {
fontSize: 16,
padding: [0, 0, 0, 5]
}
}
},
formatter: (params) => {
let total = 0
let target
for (let i = 0; i < data.length; i++) {
total += Number(data[i].value)
if (data[i].name === params) {
target = Number(data[i].value)
}
}
let percentageValue = Number(((target / total) * 100).toFixed(2))
if (typeof percentageValue != 'number' && (Number.isNaN(Number(percentageValue)) || Number.isFinite(Number(percentageValue)))) {
percentageValue = 0
}
return [
`{nameStyle|${params}} {valStyle|${target}} {proportionStyle|${percentageValue}%}`
].join('\n')
}
},
series: [
{
name: '',
type: 'pie',
radius: ['40%', '60%'],
center: ['20%', '50%'],//饼状图位置
avoidLabelOverlap: false,
label: {
show: false,
position: 'center',
fontSize: 12,
textStyle: {
fontWeight: '500',
rich: {
valueStyle: {
fontSize: 22
},
nameStyle: {
fontSize: 12,
color: '#666666'
}
}
},
formatter: (row) => {
return `{valueStyle|${row.value}}\n{nameStyle|${row.name}}`
}
},
emphasis: {
label: {
show: true,
fontSize: 12,
fontWeight: 'bold'
}
},
labelLine: {
show: false
},
data: data
}
]
}
export let optionBarData = {
tooltip: {
trigger: 'axis'
// axisPointer: {
// type: 'shadow'
// }
},
grid: {
top: 8,
left: 10,
right: 10,
bottom: 35,
containLabel: true
},
xAxis: [
{
type: 'category',
// data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun']
}
],
yAxis: [
{
type: 'value'
}
],
//series: [
// {
// name: 'Email',
// type: 'bar',
// stack: 'Ad',
// emphasis: {
// focus: 'series'
// },
// data: [120, 132, 101, 134, 90, 230, 210],
// barMaxWidth:80,
// },
// {
// name: 'Union Ads',
// type: 'bar',
// stack: 'Ad',
// emphasis: {
// focus: 'series'
// },
// data: [220, 182, 191, 234, 290, 330, 310],
// barMaxWidth:80,
// },
// {
// name: 'Video Ads',
// type: 'bar',
// stack: 'Ad',
// emphasis: {
// focus: 'series'
// },
// barMaxWidth:80,
// data: [150, 232, 201, 154, 190, 330, 410]
// }
//]
}
const lineData = {
data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'],
seriesData: [120, 132, 101, 134, 90, 230, 210]
}
export let optionlLineData = {
tooltip: {
trigger: 'axis'
// axisPointer: {
// type: 'shadow'
// }
},
legend: {},
grid: {
top: 8,
left: 10,
right: 10,
bottom: 60,
containLabel: true
},
xAxis: [
{
type: 'category',
data: []
}
],
yAxis: [
{
type: 'value'
}
],
series: []
// series: [
// {
// name: 'Email',
// type: 'line',
// data: lineData.seriesData
// },
// {
// name: 'Union Ads',
// type: 'line',
// data: lineData.seriesData
// }
// ]
}
\ No newline at end of file
<template>
<div>每一行的内容</div>
</template>
<script>
export default {
name: 'item-component',
props: {
index: { // 每一行的索引
type: Number
},
source: { // 每一行的内容
type: Object,
default() {
return {}
}
}
}
}
</script>
<template>
<div>
<virtual-list style="height: 360px; overflow-y: auto;"
:data-key="'id'"
:data-sources="items"
:data-component="itemComponent"
/>
</div>
</template>
<script>
import Item from './Item'
import VirtualList from 'vue-virtual-scroll-list'
function createData(len) {
const arr = []
for (let index = 0; index < len; index++) {
const obj = { id: index, text: Math.random() }
arr.push(obj)
}
return arr
}
export default {
name: 'root',
data () {
return {
itemComponent: Item,
items: createData(200)
}
},
components: { 'virtual-list': VirtualList }
}
</script>
......@@ -203,6 +203,15 @@ export default [
},
component: '/views/chart/configuration.vue',
},
{
path: '/list',
name: 'list',
title: '虚拟列表',
meta: {
title: '虚拟列表',
},
component: '/views/list/index.vue',
},
]
},
{
......
<template>
<div class="wrapper" ref="wrapper" @scroll="wrapperScroll($event)">
<div class="wrapper-scroll" :style="{ height: containerHeight + 'px' }" style="position: relative;">
<div :style="{ transform: `translateY(${scrollTopWrapper}px)` }" style="position: absolute; width: 100%;">
<div v-for="(item, key) in showItem" :key="key" style="height:40px;line-height:40px">
{{item}}
</div>
</div>
</div>
</div>
<multiseriate></multiseriate>
</template>
<script setup>
import multiseriate from './multiseriate'
import {ref, computed, nextTick} from "vue";
//设置10W条模拟数据
const count = ref(103);
let arr = ref([]);
for (let index = 0; index < count.value; index++) {
arr.value.push(index);
}
//容器真实高度
let containerHeight = ref(arr.value.length * 40);
//当前状态的索引
let startKey = ref(0);
//视窗内应该显示的 DOM 数量
let showItemNum = ref(0);
//容器dom节点
const wrapper = ref(null);
//容器高度
let wrapperHeight = ref(0);
nextTick(() => {
//获取容器高度
wrapperHeight.value = wrapper.value.clientHeight;
//运算出应该显示的 DOM 数量
showItemNum.value = Math.ceil(wrapperHeight.value / 40);
});
//片段容器偏移量
let scrollTopWrapper = ref(0);
//滚动事件
const wrapperScroll = (e) => {
console.log('e', e);
//计算当前状态的索引
let tempNum = Math.floor(e.target.scrollTop / 40);
console.log('tempNum', tempNum);
//当前状态的索引发生变化才触发视图层刷新
if (tempNum !== startKey.value) {
startKey.value = tempNum
scrollTopWrapper.value = e.target.scrollTop;
}
};
//对数据进行切片处理方法
const showItem = computed(() => {
return [...arr.value.slice(startKey.value, showItemNum.value + startKey.value + 3)];
});
</script>
<script>
import {defineComponent} from 'vue'
export default defineComponent({
name: 'scrollList'
})
</script>
<style scoped>
.wrapper {
position: relative;
width: 200px;
height: 200px;
overflow: auto;
border: 1px solid #ccc;
}
</style>
<template>
<virtual-scroll :data="arr" :column="columnNum" @scroll="scroll">
<template v-slot="{Items}">
<a-row :gutter="16">
<a-col :span="8" v-for="(item, key) in Items" :key="key"
style="height: 40px;box-sizing: border-box;border: 1px solid red">
{{item.name}}--{{item.id}}
</a-col>
</a-row>
</template>
</virtual-scroll>
</template>
<script setup>
import virtualScroll from '@/components/virtualScroll/virtualScroll'
import {ref, computed, nextTick} from "vue";
import {mock} from "mockjs";
let data = {
'rows|33': [{
// 属性 id 是一个自增数,起始值为 1,每次增 1
'id|+1': 0,
'name': '@cname()',
"age|1-30": 18,
"address": '@county(true)',
"tags": '@shuffle([\'LOSER\', \'TEACHER\', \'DEVELOPER\', \'NICE\', \'COOL\'], 3)'
}]
}
//设置10W条模拟数据
const count = ref(100);
let arr = ref(mock(data).rows);
// 列高
let columnHeight = ref(40)
// 列数
let columnNum = ref(3)
const scroll = (e, list) => {
console.log(e, list);
}
</script>
<script>
import {defineComponent} from 'vue'
export default defineComponent({
name: 'multiseriate'
})
</script>
<style lang="less" scoped>
.multiseriate {
.wrapper {
box-sizing: border-box;
position: relative;
width: 100%;
height: 200px;
overflow: auto;
border: 1px solid #ccc;
overflow-x: hidden;
}
.tags {
display: flex;
justify-content: space-between;
}
}
</style>
此差异已折叠。
<template>
<div>
<div>welcome</div>
<demo></demo>
</div>
</template>
<script>
import demo from './demo.vue'
export default {
name: "index",
components:{
demo
}
}
</script>
<style scoped>
</style>
\ No newline at end of file
</style>
......@@ -45,6 +45,7 @@ export default defineConfig({
'@c': path.resolve(__dirname, './src/components'), // 配置组件
// '@img': path.resolve(__dirname, './src/assets') // 配置图片
},
// extensions: ['.js', '.ts', '.jsx', '.tsx', '.json', '.vue', '.mjs']
// 忽略后缀
extensions: ['.js', '.ts', '.jsx', '.tsx', '.json', '.vue', '.mjs']
}
})