我是靠谱客的博主 忐忑毛豆,这篇文章主要介绍Vue3.2 + ts + vben admin + ant design 的Card二次封装声明:Vue3.2 + ts + vben admin +ant design 这些都有在继续往下看哈 ----单页面使用的效果  就是一个页面有效果    上代码正经的封装使用·················来了效果图展示,现在分享给大家,希望可以做个参考。

首先你得有vben admin 的代码 可以去官网拉取 ,然后在开始更改

声明:Vue3.2 + ts + vben admin +ant design 这些都有在继续往下看哈 ----

没有可以看看借鉴一下   

------------------------------------------------------------------------------------------------------------------------------

单页面使用的效果  就是一个页面有效果  

背景描述:

  1. Card里边保留了原有的功能,
  2. 增加了拖拽功能,
  3. 增加了父子传值功能,
  4. 还添加了Card的显隐功能(点击显示),
  5. 以及更改了原有的关闭按钮功能(点击关闭),

功能概括:

1,可以点击 { 弹出弹框添加 } 弹出 Card框 进行随意拖动,点击{ 关闭 } 关闭弹框 回到父页面。

                         

  1. 因为实现了父子相传,可以在子页面定义数据以及方法,然后通过emit和按钮进行传值,方法需要在父组件重新定义。

  上代码

 父页面代码

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
<template> <div> {{ parentValue }} <br> {{ kl }} <br> <Button type="primary" @click="isShow = true">弹出弹窗并添加</Button> <Button type="primary" @click="onParentClick()">添加</Button> <Button type="primary" @click="kls()">修改</Button> <!-- 子组件 --> <Card v-show="isShow" @close="close" :kl="kl" @add="onParentClick" :isShow="isShow"></Card> <!-- v-show="isShow" 控制Card显隐 @close="close" 删除方法 :kl="kl" 父给子传值 @add="onParentClick" 子给父传递方法 :isShow="isShow" 父给子传递显隐 --> </div> </template> <script setup lang='ts'> import { Button } from '/@/components/Button'; import Card from '../dept/Card.vue' import { ref } from 'vue' import { any } from 'vue-types' //定义初始值 父给子传值 const kl = ref<String>('kl值') // 定义初始值 const parentValue = ref(0) // 定义方法 function onParentClick(childValue: number) { //进行一个三元判断 父页面加1 子页面加200(子页面定义200了) childValue ? (parentValue.value += childValue) : parentValue.value++ // 点击添加 每次加一 // childValue = parentValue.value++ } // 定义显隐 const isShow = ref<boolean>(false) // 删除按钮 function close(value: any) { // console.log(value); isShow.value = value } // 修改值 function kls(value: any) { value = '修改值11111' kl.value = value } </script> <style> </style>

子页面代码

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
<template> <div v-move class="box" > <Card style="width: 100%" title="Card title" :tab-list="customTab" :active-tab-key="key" @tabChange="key => onTabChange(key, 'key')" > <template #customRender="item"> <span> <home-outlined /> {{ item.key }} </span> </template> <template #extra> <span class="close" @click="close">关闭</span> </template> {{ contentList[key] }} </Card> <!-- 挂载 点击触发变化 --> <Button type="primary" @click="onChildClick">子传值200</Button> <p>{{ kl }}</p> </div> </template> <script setup lang='ts'> import Card from "ant-design-vue/lib/card/Card"; import { Directive, ref } from "vue"; import { HomeOutlined } from '@ant-design/icons-vue'; import { any, string } from "vue-types"; import { Button } from '/@/components/Button'; // 传递值 赋值 const emit = defineEmits(["key", "noTitleKey", 'add', 'onTabChange', "vMove", 'close']) //定义方法 并且传值 挂载在按钮上边 200就是携带值 function onChildClick() { emit('add', 200) } // 定义传值关闭按钮 function close() { emit('close', false) } // 接收 const props: any = defineProps({ // 父传子 接收值 kl: { type: string, default: "boolean" }, }) const customTab: any = [ { key: 'tab1', slots: { tab: 'customRender', }, }, { key: 'tab2', tab: 'tab2', }, ]; const contentList: any = { tab1: 'content1', tab2: 'content2', }; const key = ref<String>('tab1'); const noTitleKey = ref<String>('app'); const onTabChange: any = (value: any, type: any) => { console.log(value, type); if (type === 'key') { key.value = value; } else if (type === 'noTitleKey') { noTitleKey.value = value; } emit('onTabChange', onTabChange) }; // 定义 x轴 和 y轴 的一些基本值 {初始化} let positionX = ref<number>(1110) // console.log(positionX,'ajsaja') let positionY = ref<number>(0) // 定义 VMove VMove定义的是方法 {移动的基本逻辑} const vMove: Directive = { mounted(el: HTMLElement) { // let moveEl = el.firstElementChild as HTMLElement; // 进行赋值 let moveEl = el as HTMLElement // 定义物体移动位置 距离 const mouseDown = (e: MouseEvent) => { //鼠标点击物体那一刻相对于物体左侧边框的距离=点击时的位置相对于浏览器最左边的距离-物体左边框相对于浏览器最左边的距离 // console.log(e.clientX, e.clientY, "-----起始", el.offsetLeft); // clientX:当鼠标事件发生时, 鼠标相对于浏览器(这里说的是浏览器的有效区域)X轴的位置; // clientY:当鼠标事件发生时,鼠标相对于浏览器(这里说的是浏览器的有效区域)y轴的位置; // screenX:当鼠标事件发生时,鼠标相对于显示器屏幕x轴的位置; // screenY:当鼠标事件发生时,鼠标相对于显示器屏幕y轴的位置; // offsetX:当鼠标事件发生时,鼠标相对于事件源x轴的位置 // offsetY:当鼠标事件发生时,鼠标相对于事件源y轴的位置 // offsetLeft : 向左偏移,严格来说他是内边距 物体到边界的距离 // offsetTop : 向上偏移,严格来说他是内边距 物体到边界的距离 // x y是浏览器的宽度减去 用移动的位置 let X = e.clientX - el.offsetLeft; let Y = e.clientY - el.offsetTop; // console.log(X,'kkk') // 获取拖拽位置 const move = (e: MouseEvent) => { // 获取拖拽元素的位置 let left = e.clientX - X; let top = e.clientY - Y; // console.log(left,'kkk') //positionX.value 就是移动的位置 {在进行赋值} positionX.value = left positionY.value = top // console.log(positionX.value,'kkk') // console.log(positionX,'kkk22') // clientWidth 客户端宽度 el.offsetWidth 偏移宽度 // 进行判断 if (left <= 0) { left = 0 } else if (left >= document.documentElement.clientWidth - el.offsetWidth) { left = document.documentElement.clientWidth - el.offsetWidth } if (top <= 0) { top = 0 } else if (top >= document.documentElement.clientHeight - el.offsetHeight) { top = document.documentElement.clientHeight - el.offsetHeight } el.style.left = left + "px"; el.style.top = top + "px"; }; // addEventListener 添加事件侦听器 监听mousemove move document.addEventListener("mousemove", move); //清除 mousemove移动事件 document.addEventListener("mouseup", () => { document.removeEventListener("mousemove", move); }); }; // addEventListener 添加事件侦听器 监听"mousedown", mouseDown moveEl.addEventListener("mousedown", mouseDown); }, } // 暴露方法 defineExpose({ onTabChange, vMove, key, noTitleKey, positionX, positionY, onChildClick }); </script> <style lang='less' scoped> .box { position: fixed; // width: 400px; } </style>

-----------------------------------------------------------------------------------------------------------------------------

正经的封装使用·················来了

                                VCard  二次封装Card组件

 功能:添加移动效果,保留基本属性 添加删除效果

上代码

子组件

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
{{{VCard组件}}} <template> <div v-move class="box" > <Card class="box-card" v-bind="$attrs" v-on="$listeners"> <template #extra> <p class="close" @click="close">关闭</p> </template> <template #[slotName] v-for="(slot, slotName) in $slots"> <slot :name="slotName" /> </template> </Card> </div> </template> <script setup lang='ts'> import Card from "ant-design-vue/lib/card/Card"; import { Directive, ref } from "vue"; import { any } from "vue-types"; function defineOptions(_arg0: { name: string; }) { } defineOptions({ name: 'VCard', }); // 传递值 赋值 const emit = defineEmits(['close']) // 接收 const props: any = defineProps({}) // 定义传值关闭按钮 const isShow = ref<boolean>(false) // 定义传值关闭按钮 function close() { emit('close', false) } let positionX = ref<number>(1110) let positionY = ref<number>(0) const vMove: Directive = { mounted(el: HTMLElement) { let moveEl = el as HTMLElement const mouseDown = (e: MouseEvent) => { let X = e.clientX - el.offsetLeft; let Y = e.clientY - el.offsetTop; const move = (e: MouseEvent) => { let left = e.clientX - X; let top = e.clientY - Y; positionX.value = left positionY.value = top if (left <= 0) { left = 0 } else if (left >= document.documentElement.clientWidth - el.offsetWidth) { left = document.documentElement.clientWidth - el.offsetWidth } if (top <= 0) { top = 0 } else if (top >= document.documentElement.clientHeight - el.offsetHeight) { top = document.documentElement.clientHeight - el.offsetHeight } el.style.left = left + "px"; el.style.top = top + "px"; }; document.addEventListener("mousemove", move); document.addEventListener("mouseup", () => { document.removeEventListener("mousemove", move); }); }; moveEl.addEventListener("mousedown", mouseDown); }, } // 暴露方法 defineExpose({ vMove, }); </script> <style lang='less' scoped> .box, .box-card { position: fixed; width: 300px; height: 300px; } </style>

父组件

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
<template> <div> <Button type="primary" @click="isShow = true">弹出弹窗并添加</Button> <VCard class="klkl" title="nihao" v-show="isShow" :isShow="isShow" @close="close" > <p>娇嫩的小公主</p> 欢迎来到-{{ kl }} </VCard> </div> </template> <script setup lang='ts'> import VCard from '/@/views/demo/system/dept/VCard.vue' import { Button } from '/@/components/Button'; import { ref } from 'vue' function defineOptions(_arg0: { name: string; }) { } defineOptions({ name: 'index', }); // 删除按钮 function close(value: any) { isShow.value = value } const kl = ref('暴徒世界') // 显示状态 const isShow = ref<boolean>(false) </script> <style> .klkl{ background-color: rgb(102, 100, 90); width: 200px; height: 200px; } </style>

效果图展示

 

 不足求指教  ~~~~~~

最后

以上就是忐忑毛豆最近收集整理的关于Vue3.2 + ts + vben admin + ant design 的Card二次封装声明:Vue3.2 + ts + vben admin +ant design 这些都有在继续往下看哈 ----单页面使用的效果  就是一个页面有效果    上代码正经的封装使用·················来了效果图展示的全部内容,更多相关Vue3.2内容请搜索靠谱客的其他文章。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(63)

评论列表共有 0 条评论

立即
投稿
返回
顶部