component_ryl_v3 1.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +134 -0
- package/dist/component_ryl_v3.css +1 -0
- package/dist/component_ryl_v3.js +1240 -0
- package/dist/vite.svg +1 -0
- package/package.json +48 -0
- package/src/App.vue +215 -0
- package/src/assets/img/hide.png +0 -0
- package/src/assets/img/noData.png +0 -0
- package/src/assets/img/portrait.jpg +0 -0
- package/src/assets/styles/common.scss +239 -0
- package/src/assets/styles/dialog.scss +45 -0
- package/src/assets/styles/element-plus-theme.scss +15 -0
- package/src/assets/styles/index.scss +93 -0
- package/src/index.js +33 -0
- package/src/main.js +11 -0
- package/src/packages/directives/copy/index.js +47 -0
- package/src/packages/directives/debounce/index.js +17 -0
- package/src/packages/directives/index.js +18 -0
- package/src/packages/directives/money/index.js +84 -0
- package/src/packages/directives/throttle/index.js +29 -0
- package/src/packages/handConfirmNew/index.js +79 -0
- package/src/packages/handDialog/handDialog.vue +204 -0
- package/src/packages/handHeader/handHeader.vue +572 -0
- package/src/packages/handHeader/sidebarItem.vue +173 -0
- package/src/packages/handNoData/handNoData.vue +45 -0
- package/src/packages/handPaging/handPaging.vue +137 -0
- package/src/packages/handSeeImg/handSeeImg.vue +80 -0
- package/src/packages/handTab/handTab.vue +108 -0
|
@@ -0,0 +1,173 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<!-- 没有子菜单的菜单项 -->
|
|
3
|
+
<template v-if="!item.children">
|
|
4
|
+
<ElMenuItem :index="item.path">
|
|
5
|
+
<i :class="['iconfont', item.meta.icon]" v-if="item.meta.icon"></i>
|
|
6
|
+
<template #title>
|
|
7
|
+
<div class="mainMenu">
|
|
8
|
+
<span>{{ item.meta.title }}</span>
|
|
9
|
+
<em class="elbadge hot" v-if="item.tips && item.tips.name === 'hot'"></em>
|
|
10
|
+
<em class="elbadge new" v-if="item.tips && item.tips.name === 'new'"></em>
|
|
11
|
+
<em class="elbadge run" v-if="item.tips && item.tips.name === 'run'">{{ item.tips.value }}</em>
|
|
12
|
+
<em class="elbadge num" v-if="item.tips && item.tips.name === 'num' && Number(item.tips.value) < 100">
|
|
13
|
+
{{ item.tips.value }}
|
|
14
|
+
</em>
|
|
15
|
+
<em class="elbadge num nine" v-if="item.tips && item.tips.name === 'num' && Number(item.tips.value) >= 100">
|
|
16
|
+
99<em>+</em>
|
|
17
|
+
</em>
|
|
18
|
+
</div>
|
|
19
|
+
</template>
|
|
20
|
+
</ElMenuItem>
|
|
21
|
+
</template>
|
|
22
|
+
|
|
23
|
+
<!-- 有子菜单的菜单项 -->
|
|
24
|
+
<ElSubMenu v-else :index="item.path">
|
|
25
|
+
<!-- 这是二级菜单的标题 -->
|
|
26
|
+
<template #title>
|
|
27
|
+
<i :class="['iconfont', item.meta.icon]" v-if="item.meta.icon"></i>
|
|
28
|
+
<template v-if="!hideMenu">
|
|
29
|
+
<div class="mainMenu">
|
|
30
|
+
<span>{{ item.meta.title }}</span>
|
|
31
|
+
<em class="elbadge hot" v-if="item.tips && item.tips.name === 'hot'"></em>
|
|
32
|
+
<em class="elbadge new" v-if="item.tips && item.tips.name === 'new'"></em>
|
|
33
|
+
<em class="elbadge run" v-if="item.tips && item.tips.name === 'run'">{{ item.tips.value }}</em>
|
|
34
|
+
<em class="elbadge num" v-if="item.tips && item.tips.name === 'num' && Number(item.tips.value) < 100">
|
|
35
|
+
{{ item.tips.value }}
|
|
36
|
+
</em>
|
|
37
|
+
<em class="elbadge num nine" v-if="item.tips && item.tips.name === 'num' && Number(item.tips.value) >= 100">
|
|
38
|
+
99<em>+</em>
|
|
39
|
+
</em>
|
|
40
|
+
</div>
|
|
41
|
+
</template>
|
|
42
|
+
<template v-else>
|
|
43
|
+
<span>{{ item.meta.title }}</span>
|
|
44
|
+
</template>
|
|
45
|
+
</template>
|
|
46
|
+
|
|
47
|
+
<!-- 递归渲染子菜单 -- 这是二级菜单的子菜单 -->
|
|
48
|
+
<template v-if="item.children">
|
|
49
|
+
<template v-for="child in item.children" :key="child.path">
|
|
50
|
+
<!-- 如果有子菜单,递归调用自身 -->
|
|
51
|
+
<sidebar-item
|
|
52
|
+
v-if="child.children && child.children.length"
|
|
53
|
+
:item="child"
|
|
54
|
+
:hideMenu="hideMenu"
|
|
55
|
+
/>
|
|
56
|
+
<!-- 子菜单项 -->
|
|
57
|
+
<ElMenuItem v-else :index="child.path">
|
|
58
|
+
<template #title>
|
|
59
|
+
<i :class="['iconfont', child.meta.icon]" v-if="child.meta.icon"></i>
|
|
60
|
+
<template v-if="!hideMenu">
|
|
61
|
+
<div class="mainMenu">
|
|
62
|
+
<span>{{ child.meta.title }}</span>
|
|
63
|
+
<em class="elbadge hot" v-if="child.tips && child.tips.name === 'hot'"></em>
|
|
64
|
+
<em class="elbadge new" v-if="child.tips && child.tips.name === 'new'"></em>
|
|
65
|
+
<em class="elbadge run" v-if="child.tips && child.tips.name === 'run'">{{ child.tips.value }}</em>
|
|
66
|
+
<em class="elbadge num" v-if="child.tips && child.tips.name === 'num' && Number(child.tips.value) < 100">
|
|
67
|
+
{{ child.tips.value }}
|
|
68
|
+
</em>
|
|
69
|
+
<em class="elbadge num nine" v-if="child.tips && child.tips.name === 'num' && Number(child.tips.value) >= 100">
|
|
70
|
+
99<em>+</em>
|
|
71
|
+
</em>
|
|
72
|
+
</div>
|
|
73
|
+
</template>
|
|
74
|
+
<template v-else>
|
|
75
|
+
<span>{{ child.meta.title }}</span>
|
|
76
|
+
</template>
|
|
77
|
+
</template>
|
|
78
|
+
</ElMenuItem>
|
|
79
|
+
</template>
|
|
80
|
+
</template>
|
|
81
|
+
</ElSubMenu>
|
|
82
|
+
</template>
|
|
83
|
+
|
|
84
|
+
<script setup>
|
|
85
|
+
/**
|
|
86
|
+
* 侧边栏菜单项组件
|
|
87
|
+
*/
|
|
88
|
+
import { ElMenuItem, ElSubMenu } from 'element-plus'
|
|
89
|
+
|
|
90
|
+
defineProps({
|
|
91
|
+
item: {
|
|
92
|
+
type: Object,
|
|
93
|
+
default: () => ({})
|
|
94
|
+
},
|
|
95
|
+
hideMenu: {
|
|
96
|
+
type: Boolean,
|
|
97
|
+
default: false
|
|
98
|
+
}
|
|
99
|
+
})
|
|
100
|
+
</script>
|
|
101
|
+
|
|
102
|
+
<style scoped lang="scss">
|
|
103
|
+
.mainMenu{
|
|
104
|
+
display: inline-block;
|
|
105
|
+
position: relative;
|
|
106
|
+
.elbadge{
|
|
107
|
+
color: #ff0000;
|
|
108
|
+
font-style: normal;
|
|
109
|
+
&.hot::after{
|
|
110
|
+
display: inline-block;
|
|
111
|
+
content: '';
|
|
112
|
+
width: 8px;
|
|
113
|
+
height: 8px;
|
|
114
|
+
background-color: #ff0000;
|
|
115
|
+
border-radius: 100%;
|
|
116
|
+
transform: scale(.9);
|
|
117
|
+
position: absolute;
|
|
118
|
+
top:10px;
|
|
119
|
+
right: -10px;
|
|
120
|
+
}
|
|
121
|
+
&.new::after{
|
|
122
|
+
display: inline-block;
|
|
123
|
+
content: 'new';
|
|
124
|
+
background-color: #ff0000;
|
|
125
|
+
color: #fff;
|
|
126
|
+
padding: 0 4px 1px 4px;
|
|
127
|
+
line-height: 16px;
|
|
128
|
+
border-radius: 4px;
|
|
129
|
+
transform: scale(.9);
|
|
130
|
+
position: absolute;
|
|
131
|
+
top: 6px;
|
|
132
|
+
right: -32px;
|
|
133
|
+
}
|
|
134
|
+
&.run{
|
|
135
|
+
display: inline-block;
|
|
136
|
+
color: #fff;
|
|
137
|
+
background-color: #ff0000;
|
|
138
|
+
min-width: 20px;
|
|
139
|
+
padding: 0 2px;
|
|
140
|
+
text-align: center;
|
|
141
|
+
height: 16px;
|
|
142
|
+
line-height: 16px;
|
|
143
|
+
border-radius: 4px;
|
|
144
|
+
animation: changeRun 1.5s ease-in-out 0s infinite;
|
|
145
|
+
}
|
|
146
|
+
&.num{
|
|
147
|
+
display: inline-block;
|
|
148
|
+
background-color: #ff0000;
|
|
149
|
+
color: #fff;
|
|
150
|
+
width: 20px;
|
|
151
|
+
text-align: center;
|
|
152
|
+
height: 16px;
|
|
153
|
+
line-height: 16px;
|
|
154
|
+
border-radius: 4px;
|
|
155
|
+
transform: scale(.9);
|
|
156
|
+
position: absolute;
|
|
157
|
+
top: 6px;
|
|
158
|
+
right: -22px;
|
|
159
|
+
&.nine{
|
|
160
|
+
width: 26px;
|
|
161
|
+
right: -28px;
|
|
162
|
+
em{
|
|
163
|
+
position: relative;
|
|
164
|
+
top:-4px;
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
.el-menu-item span,.el-sub-menu__title span{
|
|
171
|
+
font-size: 14px;
|
|
172
|
+
}
|
|
173
|
+
</style>
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<!-- 空数据提示组件 -->
|
|
3
|
+
<div class="initNoData flex flex_row">
|
|
4
|
+
<div class="inner">
|
|
5
|
+
<img :src="noDataImg" alt="暂无数据">
|
|
6
|
+
<p>{{title}}</p>
|
|
7
|
+
</div>
|
|
8
|
+
</div>
|
|
9
|
+
</template>
|
|
10
|
+
|
|
11
|
+
<script setup>
|
|
12
|
+
/**
|
|
13
|
+
* 空数据提示组件
|
|
14
|
+
* 功能:当列表数据为空时显示友好的提示信息
|
|
15
|
+
*/
|
|
16
|
+
import noDataImg from '@/assets/img/noData.png'
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* 组件属性定义
|
|
20
|
+
* @property {string} title - 提示文本,默认"暂无数据"
|
|
21
|
+
*/
|
|
22
|
+
defineProps({
|
|
23
|
+
title: {
|
|
24
|
+
type: String,
|
|
25
|
+
default: '暂无数据'
|
|
26
|
+
}
|
|
27
|
+
})
|
|
28
|
+
</script>
|
|
29
|
+
|
|
30
|
+
<style lang="scss" scoped>
|
|
31
|
+
/* 空数据容器样式 */
|
|
32
|
+
.initNoData{
|
|
33
|
+
width: 100%;
|
|
34
|
+
align-items: center;
|
|
35
|
+
justify-content: center;
|
|
36
|
+
.inner{
|
|
37
|
+
text-align: center;
|
|
38
|
+
p{
|
|
39
|
+
color: #666;
|
|
40
|
+
margin-top: 12px;
|
|
41
|
+
line-height: normal;
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
</style>
|
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<!-- 分页组件 -->
|
|
3
|
+
<div class="initPaging">
|
|
4
|
+
<!-- 使用ConfigProvider设置中文locale -->
|
|
5
|
+
<ElConfigProvider :locale="zhCn">
|
|
6
|
+
<ElPagination
|
|
7
|
+
background
|
|
8
|
+
v-model:current-page="currentPage"
|
|
9
|
+
v-model:page-size="pageSize"
|
|
10
|
+
:total="total"
|
|
11
|
+
:page-sizes="[10, 15, 20, 50, 100]"
|
|
12
|
+
:disabled="disabled"
|
|
13
|
+
:hide-on-single-page="hideOnSingle"
|
|
14
|
+
:size="size"
|
|
15
|
+
:layout="layout"
|
|
16
|
+
@size-change="handleSizeChange"
|
|
17
|
+
@current-change="handleCurrentChange"
|
|
18
|
+
/>
|
|
19
|
+
</ElConfigProvider>
|
|
20
|
+
</div>
|
|
21
|
+
</template>
|
|
22
|
+
|
|
23
|
+
<script setup>
|
|
24
|
+
/**
|
|
25
|
+
* 分页组件
|
|
26
|
+
* 功能:封装Element Plus分页组件,提供统一的分页交互和事件处理
|
|
27
|
+
*/
|
|
28
|
+
|
|
29
|
+
// 导入Vue响应式API
|
|
30
|
+
import { ref, watch } from 'vue'
|
|
31
|
+
// 导入Element Plus组件和中文语言包
|
|
32
|
+
import { ElPagination, ElConfigProvider } from 'element-plus'
|
|
33
|
+
import zhCn from 'element-plus/dist/locale/zh-cn.mjs'
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* 组件属性定义
|
|
37
|
+
* @property {number} currentPage - 当前页码
|
|
38
|
+
* @property {number} pageSize - 每页条数
|
|
39
|
+
* @property {number} total - 总记录数
|
|
40
|
+
* @property {boolean} disabled - 是否禁用分页
|
|
41
|
+
* @property {boolean} hideOnSingle - 只有一页时是否隐藏
|
|
42
|
+
* @property {string} layout - 分页布局('total,sizes,prev, pager, next')
|
|
43
|
+
* @property {string} size - 分页大小('small' | 'default' | 'large') 默认'small'
|
|
44
|
+
*
|
|
45
|
+
* 注意:组件内部已使用 ElConfigProvider 配置中文语言包,分页文案会自动显示为中文
|
|
46
|
+
* 显示效果:"共 X 条"、"X条/页"、"上一页"、"下一页"
|
|
47
|
+
*/
|
|
48
|
+
const props = defineProps({
|
|
49
|
+
currentPage: {
|
|
50
|
+
type: Number,
|
|
51
|
+
default: 1
|
|
52
|
+
},
|
|
53
|
+
pageSize: {
|
|
54
|
+
type: Number,
|
|
55
|
+
default: 10
|
|
56
|
+
},
|
|
57
|
+
total: {
|
|
58
|
+
type: Number,
|
|
59
|
+
default: 0
|
|
60
|
+
},
|
|
61
|
+
layout: {
|
|
62
|
+
type: String,
|
|
63
|
+
default: 'total,sizes,prev, pager, next'
|
|
64
|
+
},
|
|
65
|
+
disabled: {
|
|
66
|
+
type: Boolean,
|
|
67
|
+
default: false
|
|
68
|
+
},
|
|
69
|
+
hideOnSingle: {
|
|
70
|
+
type: Boolean,
|
|
71
|
+
default: true
|
|
72
|
+
},
|
|
73
|
+
size: {
|
|
74
|
+
type: String,
|
|
75
|
+
default: 'small'
|
|
76
|
+
}
|
|
77
|
+
})
|
|
78
|
+
|
|
79
|
+
/**
|
|
80
|
+
* 事件定义
|
|
81
|
+
* @event page-change - 页码改变事件(包含当前页和每页条数)
|
|
82
|
+
*/
|
|
83
|
+
const emit = defineEmits(['page-change'])
|
|
84
|
+
|
|
85
|
+
/**
|
|
86
|
+
* 当前页码(响应式)
|
|
87
|
+
* @type {import('vue').Ref<number>}
|
|
88
|
+
*/
|
|
89
|
+
const currentPage = ref(props.currentPage)
|
|
90
|
+
|
|
91
|
+
/**
|
|
92
|
+
* 每页条数(响应式)
|
|
93
|
+
* @type {import('vue').Ref<number>}
|
|
94
|
+
*/
|
|
95
|
+
const pageSize = ref(props.pageSize)
|
|
96
|
+
|
|
97
|
+
/**
|
|
98
|
+
* 监听props中的currentPage变化,同步到本地响应式数据
|
|
99
|
+
*/
|
|
100
|
+
watch(() => props.currentPage, (val) => {
|
|
101
|
+
currentPage.value = val
|
|
102
|
+
})
|
|
103
|
+
|
|
104
|
+
/**
|
|
105
|
+
* 监听props中的pageSize变化,同步到本地响应式数据
|
|
106
|
+
*/
|
|
107
|
+
watch(() => props.pageSize, (val) => {
|
|
108
|
+
pageSize.value = val
|
|
109
|
+
})
|
|
110
|
+
|
|
111
|
+
/**
|
|
112
|
+
* 处理每页条数改变
|
|
113
|
+
* @param {number} val - 新的每页条数
|
|
114
|
+
*/
|
|
115
|
+
const handleSizeChange = (val) => {
|
|
116
|
+
pageSize.value = val
|
|
117
|
+
emit('page-change', { page: currentPage.value, pageSize: val })
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
/**
|
|
121
|
+
* 处理当前页码改变
|
|
122
|
+
* @param {number} val - 新的页码
|
|
123
|
+
*/
|
|
124
|
+
const handleCurrentChange = (val) => {
|
|
125
|
+
currentPage.value = val
|
|
126
|
+
emit('page-change', { page: val, pageSize: pageSize.value })
|
|
127
|
+
}
|
|
128
|
+
</script>
|
|
129
|
+
|
|
130
|
+
<style lang="scss" scoped>
|
|
131
|
+
/* 分页组件容器样式 */
|
|
132
|
+
.initPaging{
|
|
133
|
+
:deep(.el-select__placeholder){
|
|
134
|
+
text-align: center;
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
</style>
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<!-- 图片预览遮罩层 -->
|
|
3
|
+
<div class="previewFix" v-if="show" @click="exitPreview($event)">
|
|
4
|
+
<img :src="src" />
|
|
5
|
+
</div>
|
|
6
|
+
</template>
|
|
7
|
+
|
|
8
|
+
<script setup>
|
|
9
|
+
/**
|
|
10
|
+
* 图片预览组件
|
|
11
|
+
* 功能:提供点击放大查看图片的功能,支持点击遮罩层关闭预览
|
|
12
|
+
*/
|
|
13
|
+
|
|
14
|
+
// 导入Vue响应式API
|
|
15
|
+
import { ref } from 'vue'
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* 预览遮罩层显示状态
|
|
19
|
+
* @type {import('vue').Ref<boolean>}
|
|
20
|
+
*/
|
|
21
|
+
const show = ref(false)
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* 当前预览图片的URL
|
|
25
|
+
* @type {import('vue').Ref<string>}
|
|
26
|
+
*/
|
|
27
|
+
const src = ref('')
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* 退出预览
|
|
31
|
+
* 点击遮罩层(非图片区域)时关闭预览
|
|
32
|
+
* @param {Event} e - 点击事件对象
|
|
33
|
+
*/
|
|
34
|
+
const exitPreview = (e) => {
|
|
35
|
+
// 判断点击的是否是图片元素,如果不是则关闭预览
|
|
36
|
+
if (e.target.nodeName !== "IMG") {
|
|
37
|
+
show.value = false
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* 打开图片预览
|
|
43
|
+
* @param {string} imageSrc - 图片URL
|
|
44
|
+
*/
|
|
45
|
+
const openPreview = (imageSrc) => {
|
|
46
|
+
// 设置预览图片地址
|
|
47
|
+
src.value = imageSrc
|
|
48
|
+
// 显示预览遮罩层
|
|
49
|
+
show.value = true
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* 暴露方法给父组件调用
|
|
54
|
+
* @method openPreview - 打开图片预览
|
|
55
|
+
*/
|
|
56
|
+
defineExpose({
|
|
57
|
+
openPreview
|
|
58
|
+
})
|
|
59
|
+
</script>
|
|
60
|
+
|
|
61
|
+
<style lang="scss" scoped>
|
|
62
|
+
/* 预览遮罩层样式 */
|
|
63
|
+
.previewFix{
|
|
64
|
+
width: 100%;
|
|
65
|
+
height: 100%;
|
|
66
|
+
position: fixed;
|
|
67
|
+
top: 0;
|
|
68
|
+
left: 0;
|
|
69
|
+
z-index: 9999;
|
|
70
|
+
background-color: rgba(0, 0, 0, .5);
|
|
71
|
+
display: flex;
|
|
72
|
+
justify-content: center;
|
|
73
|
+
align-items: center;
|
|
74
|
+
|
|
75
|
+
img{
|
|
76
|
+
max-width: 98%;
|
|
77
|
+
max-height: 98%;
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
</style>
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<!-- 标签切换组件 -->
|
|
3
|
+
<div class="status_search">
|
|
4
|
+
<span
|
|
5
|
+
v-for="(item, index) in list"
|
|
6
|
+
:key="index"
|
|
7
|
+
:class="{ active: currentIndex == index }"
|
|
8
|
+
@click="clickStatus(index, item)"
|
|
9
|
+
>{{ item.label }}</span
|
|
10
|
+
>
|
|
11
|
+
</div>
|
|
12
|
+
</template>
|
|
13
|
+
|
|
14
|
+
<script setup>
|
|
15
|
+
/**
|
|
16
|
+
* 标签切换组件
|
|
17
|
+
* 功能:提供一组可点击的标签,用于切换不同状态或分类
|
|
18
|
+
*/
|
|
19
|
+
|
|
20
|
+
// 导入Vue响应式API
|
|
21
|
+
import { ref } from 'vue'
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* 组件属性定义
|
|
25
|
+
* @property {Array<Object>} list - 标签列表数据
|
|
26
|
+
* @property {string} list[].label - 标签显示文本
|
|
27
|
+
*/
|
|
28
|
+
defineProps({
|
|
29
|
+
list: {
|
|
30
|
+
type: Array,
|
|
31
|
+
default: () => []
|
|
32
|
+
}
|
|
33
|
+
})
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* 事件定义
|
|
37
|
+
* @event getStatus - 标签点击事件,返回选中的索引和项数据
|
|
38
|
+
*/
|
|
39
|
+
const emit = defineEmits(['getStatus'])
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* 当前选中的标签索引
|
|
43
|
+
* @type {import('vue').Ref<number>}
|
|
44
|
+
*/
|
|
45
|
+
const currentIndex = ref(0)
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* 处理标签点击事件
|
|
49
|
+
* @param {number} i - 点击的标签索引
|
|
50
|
+
* @param {Object} v - 点击的标签数据
|
|
51
|
+
*/
|
|
52
|
+
const clickStatus = (i, v) => {
|
|
53
|
+
// 更新当前选中索引
|
|
54
|
+
currentIndex.value = i
|
|
55
|
+
// 触发事件,传递索引和标签数据
|
|
56
|
+
emit('getStatus', { index: i, ...v })
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* 设置当前选中的标签索引(供父组件调用)
|
|
61
|
+
* @param {number} index - 要选中的标签索引
|
|
62
|
+
*/
|
|
63
|
+
const setIndex = (index) => {
|
|
64
|
+
currentIndex.value = index
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
/**
|
|
68
|
+
* 暴露方法给父组件调用
|
|
69
|
+
* @method setIndex - 设置当前选中的标签索引
|
|
70
|
+
*/
|
|
71
|
+
defineExpose({
|
|
72
|
+
setIndex
|
|
73
|
+
})
|
|
74
|
+
</script>
|
|
75
|
+
|
|
76
|
+
<style lang="scss" scoped>
|
|
77
|
+
/* 标签容器样式 */
|
|
78
|
+
.status_search {
|
|
79
|
+
display: inline-block;
|
|
80
|
+
|
|
81
|
+
span {
|
|
82
|
+
min-width: 40px;
|
|
83
|
+
height: 30px;
|
|
84
|
+
padding: 0 10px;
|
|
85
|
+
display: inline-block;
|
|
86
|
+
text-align: center;
|
|
87
|
+
line-height: 30px;
|
|
88
|
+
border: 1px solid #d9d9d9;
|
|
89
|
+
border-right: 1px solid transparent;
|
|
90
|
+
cursor: pointer;
|
|
91
|
+
|
|
92
|
+
&:first-child {
|
|
93
|
+
border-radius: 2px 0px 0px 2px;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
&:last-child {
|
|
97
|
+
border-radius: 0px 2px 2px 0px;
|
|
98
|
+
border-right: 1px solid #d9d9d9;
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
.active {
|
|
103
|
+
background: #06f;
|
|
104
|
+
color: #fff;
|
|
105
|
+
border-color: #06f;
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
</style>
|