officialblock 1.0.0 → 1.0.1
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 +115 -4
- package/dist/official-block.cjs.js +1 -1
- package/dist/official-block.es.js +69 -58
- package/dist/official-block.umd.js +1 -1
- package/dist/style.css +1 -1
- package/package.json +1 -1
- package/src/components/ArticleList/index.vue +5 -0
- package/src/components/HeroSlide/index.ts +1 -0
- package/src/components/HeroSlide/index.vue +21 -3
- package/src/components/HeroSlide/type.ts +19 -0
- package/src/components/index.ts +11 -0
- package/src/index.ts +15 -8
- package/src/types.ts +8 -0
package/README.md
CHANGED
|
@@ -21,13 +21,29 @@ const app = createApp(App)
|
|
|
21
21
|
app.use(OfficialBlock)
|
|
22
22
|
|
|
23
23
|
// 现在可以在任何组件中使用
|
|
24
|
-
// <ArticleList />
|
|
24
|
+
// <ArticleList model-value="test" />
|
|
25
25
|
// <HeroSlide />
|
|
26
26
|
```
|
|
27
27
|
|
|
28
28
|
### 方式二:按需引入组件
|
|
29
29
|
|
|
30
30
|
```javascript
|
|
31
|
+
// Vue 3 Composition API
|
|
32
|
+
<template>
|
|
33
|
+
<div>
|
|
34
|
+
<ArticleList model-value="Hello" />
|
|
35
|
+
<HeroSlide />
|
|
36
|
+
</div>
|
|
37
|
+
</template>
|
|
38
|
+
|
|
39
|
+
<script setup>
|
|
40
|
+
import { ArticleList, HeroSlide } from 'officialblock'
|
|
41
|
+
import 'officialblock/style.css'
|
|
42
|
+
</script>
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
```javascript
|
|
46
|
+
// Vue 3 Options API
|
|
31
47
|
import { ArticleList, HeroSlide } from 'officialblock'
|
|
32
48
|
import 'officialblock/style.css'
|
|
33
49
|
|
|
@@ -35,6 +51,11 @@ export default {
|
|
|
35
51
|
components: {
|
|
36
52
|
ArticleList,
|
|
37
53
|
HeroSlide
|
|
54
|
+
},
|
|
55
|
+
data() {
|
|
56
|
+
return {
|
|
57
|
+
articleValue: 'Hello World'
|
|
58
|
+
}
|
|
38
59
|
}
|
|
39
60
|
}
|
|
40
61
|
```
|
|
@@ -56,13 +77,103 @@ app.use(HeroSlidePlugin) // 只注册 HeroSlide 组件
|
|
|
56
77
|
This package includes TypeScript definitions.
|
|
57
78
|
|
|
58
79
|
```typescript
|
|
59
|
-
import type {
|
|
80
|
+
import type {
|
|
81
|
+
ComponentProps,
|
|
82
|
+
ComponentEmits,
|
|
83
|
+
ComponentSlots,
|
|
84
|
+
HeroSlideProps,
|
|
85
|
+
HeroSlideEmits,
|
|
86
|
+
SlideItem
|
|
87
|
+
} from 'officialblock'
|
|
88
|
+
|
|
89
|
+
// 使用类型
|
|
90
|
+
const articleProps: ComponentProps = {
|
|
91
|
+
modelValue: 'Hello',
|
|
92
|
+
size: 'medium',
|
|
93
|
+
disabled: false
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
const heroProps: HeroSlideProps = {
|
|
97
|
+
autoPlayInterval: 5000,
|
|
98
|
+
showIndicators: true,
|
|
99
|
+
autoPlay: true
|
|
100
|
+
}
|
|
60
101
|
```
|
|
61
102
|
|
|
62
103
|
## Components
|
|
63
104
|
|
|
64
|
-
|
|
65
|
-
|
|
105
|
+
### ArticleList 文章列表组件
|
|
106
|
+
|
|
107
|
+
```vue
|
|
108
|
+
<template>
|
|
109
|
+
<ArticleList
|
|
110
|
+
v-model="articleValue"
|
|
111
|
+
size="medium"
|
|
112
|
+
:disabled="false"
|
|
113
|
+
@change="handleChange"
|
|
114
|
+
>
|
|
115
|
+
<template #header="{ title }">
|
|
116
|
+
<h3>{{ title }}</h3>
|
|
117
|
+
</template>
|
|
118
|
+
<template #default="{ value }">
|
|
119
|
+
<p>当前值: {{ value }}</p>
|
|
120
|
+
</template>
|
|
121
|
+
</ArticleList>
|
|
122
|
+
</template>
|
|
123
|
+
|
|
124
|
+
<script setup>
|
|
125
|
+
import { ref } from 'vue'
|
|
126
|
+
import { ArticleList } from 'officialblock'
|
|
127
|
+
|
|
128
|
+
const articleValue = ref('Hello World')
|
|
129
|
+
|
|
130
|
+
const handleChange = (value) => {
|
|
131
|
+
console.log('值改变了:', value)
|
|
132
|
+
}
|
|
133
|
+
</script>
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
**Props:**
|
|
137
|
+
- `modelValue`: 双向绑定的值
|
|
138
|
+
- `size`: 组件尺寸 (`'small' | 'medium' | 'large'`)
|
|
139
|
+
- `disabled`: 是否禁用
|
|
140
|
+
|
|
141
|
+
**Events:**
|
|
142
|
+
- `change`: 值改变时触发
|
|
143
|
+
- `update:modelValue`: v-model 更新事件
|
|
144
|
+
|
|
145
|
+
**Slots:**
|
|
146
|
+
- `default`: 默认内容插槽
|
|
147
|
+
- `header`: 头部内容插槽
|
|
148
|
+
|
|
149
|
+
### HeroSlide 轮播图组件
|
|
150
|
+
|
|
151
|
+
```vue
|
|
152
|
+
<template>
|
|
153
|
+
<HeroSlide
|
|
154
|
+
:auto-play-interval="5000"
|
|
155
|
+
:show-indicators="true"
|
|
156
|
+
:auto-play="true"
|
|
157
|
+
@change="handleSlideChange"
|
|
158
|
+
/>
|
|
159
|
+
</template>
|
|
160
|
+
|
|
161
|
+
<script setup>
|
|
162
|
+
import { HeroSlide } from 'officialblock'
|
|
163
|
+
|
|
164
|
+
const handleSlideChange = (index) => {
|
|
165
|
+
console.log('切换到第', index + 1, '张')
|
|
166
|
+
}
|
|
167
|
+
</script>
|
|
168
|
+
```
|
|
169
|
+
|
|
170
|
+
**Props:**
|
|
171
|
+
- `autoPlayInterval`: 自动播放间隔时间(毫秒),默认 3000
|
|
172
|
+
- `showIndicators`: 是否显示指示器,默认 true
|
|
173
|
+
- `autoPlay`: 是否启用自动播放,默认 true
|
|
174
|
+
|
|
175
|
+
**Events:**
|
|
176
|
+
- `change`: 幻灯片切换时触发
|
|
66
177
|
|
|
67
178
|
## Development
|
|
68
179
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";Object.defineProperties(exports,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}});const e=require("vue"),
|
|
1
|
+
"use strict";Object.defineProperties(exports,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}});const e=require("vue"),h={class:"content"},y=e.defineComponent({name:"ArticleList",__name:"index",props:{size:{default:"medium"},disabled:{type:Boolean,default:!1},modelValue:{}},emits:["update:modelValue","change","focus"],setup(t,{emit:i}){const n=t,a=i,o=e.computed(()=>`Current value: ${n.modelValue}`);function c(){n.disabled||a("change",n.modelValue)}return(l,p)=>(e.openBlock(),e.createElementBlock("div",{class:e.normalizeClass(["your-component",[`size-${l.size}`,{"is-disabled":l.disabled}]]),onClick:c},[e.renderSlot(l.$slots,"header",{title:o.value},void 0,!0),e.createElementVNode("div",h,[e.renderSlot(l.$slots,"default",{value:l.modelValue},()=>[e.createTextVNode(e.toDisplayString(l.modelValue),1)],!0)])],2))}}),v=(t,i)=>{const n=t.__vccOpts||t;for(const[a,o]of i)n[a]=o;return n},u=v(y,[["__scopeId","data-v-03506405"]]),B={class:"hero-slide"},g={class:"slide-container"},S={key:0,class:"slide-indicators"},V=["onClick"],C=e.defineComponent({name:"HeroSlide",__name:"index",props:{autoPlayInterval:{default:3e3},showIndicators:{type:Boolean,default:!0},autoPlay:{type:Boolean,default:!0}},emits:["change","click"],setup(t,{emit:i}){const n=t,a=i,o=e.ref(0),c=e.ref([{title:"轮播图标题 1",description:"这是第一张轮播图的描述内容"},{title:"轮播图标题 2",description:"这是第二张轮播图的描述内容"},{title:"轮播图标题 3",description:"这是第三张轮播图的描述内容"}]);let l=null;const p=r=>{o.value=r,a("change",r)},_=()=>{o.value=(o.value+1)%c.value.length,a("change",o.value)},f=()=>{n.autoPlay&&(l=window.setInterval(_,n.autoPlayInterval))},k=()=>{l&&(clearInterval(l),l=null)};return e.onMounted(()=>{f()}),e.onUnmounted(()=>{k()}),(r,I)=>(e.openBlock(),e.createElementBlock("div",B,[e.createElementVNode("div",g,[(e.openBlock(!0),e.createElementBlock(e.Fragment,null,e.renderList(c.value,(d,s)=>(e.openBlock(),e.createElementBlock("div",{key:s,class:e.normalizeClass(["slide-item",{active:o.value===s}])},[e.createElementVNode("h2",null,e.toDisplayString(d.title),1),e.createElementVNode("p",null,e.toDisplayString(d.description),1)],2))),128))]),r.showIndicators?(e.openBlock(),e.createElementBlock("div",S,[(e.openBlock(!0),e.createElementBlock(e.Fragment,null,e.renderList(c.value,(d,s)=>(e.openBlock(),e.createElementBlock("span",{key:s,class:e.normalizeClass(["indicator",{active:o.value===s}]),onClick:L=>p(s)},null,10,V))),128))])):e.createCommentVNode("",!0)]))}}),m=v(C,[["__scopeId","data-v-4198d280"]]),E={install:t=>{t.component("ArticleList",u)}},P={install:t=>{t.component("HeroSlide",m)}},A={install:t=>{t.component("ArticleList",u),t.component("HeroSlide",m)}};exports.ArticleList=u;exports.ArticleListPlugin=E;exports.HeroSlide=m;exports.HeroSlidePlugin=P;exports.default=A;
|
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
import { defineComponent as k, computed as
|
|
2
|
-
const
|
|
1
|
+
import { defineComponent as k, computed as A, createElementBlock as n, openBlock as s, normalizeClass as p, renderSlot as f, createElementVNode as u, createTextVNode as B, toDisplayString as v, ref as h, onMounted as L, onUnmounted as H, createCommentVNode as b, Fragment as y, renderList as g } from "vue";
|
|
2
|
+
const w = { class: "content" }, z = /* @__PURE__ */ k({
|
|
3
|
+
name: "ArticleList",
|
|
3
4
|
__name: "index",
|
|
4
5
|
props: {
|
|
5
6
|
size: { default: "medium" },
|
|
@@ -7,86 +8,96 @@ const L = { class: "content" }, b = /* @__PURE__ */ k({
|
|
|
7
8
|
modelValue: {}
|
|
8
9
|
},
|
|
9
10
|
emits: ["update:modelValue", "change", "focus"],
|
|
10
|
-
setup(e, { emit:
|
|
11
|
-
const
|
|
11
|
+
setup(e, { emit: c }) {
|
|
12
|
+
const o = e, a = c, l = A(() => `Current value: ${o.modelValue}`);
|
|
12
13
|
function r() {
|
|
13
|
-
|
|
14
|
+
o.disabled || a("change", o.modelValue);
|
|
14
15
|
}
|
|
15
|
-
return (
|
|
16
|
-
class:
|
|
16
|
+
return (t, _) => (s(), n("div", {
|
|
17
|
+
class: p(["your-component", [`size-${t.size}`, { "is-disabled": t.disabled }]]),
|
|
17
18
|
onClick: r
|
|
18
19
|
}, [
|
|
19
|
-
f(
|
|
20
|
-
|
|
21
|
-
f(
|
|
22
|
-
|
|
20
|
+
f(t.$slots, "header", { title: l.value }, void 0, !0),
|
|
21
|
+
u("div", w, [
|
|
22
|
+
f(t.$slots, "default", { value: t.modelValue }, () => [
|
|
23
|
+
B(v(t.modelValue), 1)
|
|
23
24
|
], !0)
|
|
24
25
|
])
|
|
25
26
|
], 2));
|
|
26
27
|
}
|
|
27
|
-
}),
|
|
28
|
-
const
|
|
29
|
-
for (const [
|
|
30
|
-
|
|
31
|
-
return
|
|
32
|
-
},
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
28
|
+
}), S = (e, c) => {
|
|
29
|
+
const o = e.__vccOpts || e;
|
|
30
|
+
for (const [a, l] of c)
|
|
31
|
+
o[a] = l;
|
|
32
|
+
return o;
|
|
33
|
+
}, P = /* @__PURE__ */ S(z, [["__scopeId", "data-v-03506405"]]), N = { class: "hero-slide" }, T = { class: "slide-container" }, E = {
|
|
34
|
+
key: 0,
|
|
35
|
+
class: "slide-indicators"
|
|
36
|
+
}, O = ["onClick"], D = /* @__PURE__ */ k({
|
|
37
|
+
name: "HeroSlide",
|
|
37
38
|
__name: "index",
|
|
38
|
-
|
|
39
|
-
|
|
39
|
+
props: {
|
|
40
|
+
autoPlayInterval: { default: 3e3 },
|
|
41
|
+
showIndicators: { type: Boolean, default: !0 },
|
|
42
|
+
autoPlay: { type: Boolean, default: !0 }
|
|
43
|
+
},
|
|
44
|
+
emits: ["change", "click"],
|
|
45
|
+
setup(e, { emit: c }) {
|
|
46
|
+
const o = e, a = c, l = h(0), r = h([
|
|
40
47
|
{ title: "轮播图标题 1", description: "这是第一张轮播图的描述内容" },
|
|
41
48
|
{ title: "轮播图标题 2", description: "这是第二张轮播图的描述内容" },
|
|
42
49
|
{ title: "轮播图标题 3", description: "这是第三张轮播图的描述内容" }
|
|
43
50
|
]);
|
|
44
|
-
let
|
|
45
|
-
const
|
|
46
|
-
l.value =
|
|
47
|
-
},
|
|
48
|
-
l.value = (l.value + 1) %
|
|
49
|
-
},
|
|
50
|
-
o = window.setInterval(
|
|
51
|
-
},
|
|
52
|
-
|
|
51
|
+
let t = null;
|
|
52
|
+
const _ = (d) => {
|
|
53
|
+
l.value = d, a("change", d);
|
|
54
|
+
}, C = () => {
|
|
55
|
+
l.value = (l.value + 1) % r.value.length, a("change", l.value);
|
|
56
|
+
}, I = () => {
|
|
57
|
+
o.autoPlay && (t = window.setInterval(C, o.autoPlayInterval));
|
|
58
|
+
}, $ = () => {
|
|
59
|
+
t && (clearInterval(t), t = null);
|
|
53
60
|
};
|
|
54
|
-
return
|
|
55
|
-
|
|
56
|
-
}),
|
|
57
|
-
|
|
58
|
-
}), (
|
|
59
|
-
|
|
60
|
-
(
|
|
61
|
-
key:
|
|
62
|
-
class:
|
|
61
|
+
return L(() => {
|
|
62
|
+
I();
|
|
63
|
+
}), H(() => {
|
|
64
|
+
$();
|
|
65
|
+
}), (d, F) => (s(), n("div", N, [
|
|
66
|
+
u("div", T, [
|
|
67
|
+
(s(!0), n(y, null, g(r.value, (m, i) => (s(), n("div", {
|
|
68
|
+
key: i,
|
|
69
|
+
class: p(["slide-item", { active: l.value === i }])
|
|
63
70
|
}, [
|
|
64
|
-
|
|
65
|
-
|
|
71
|
+
u("h2", null, v(m.title), 1),
|
|
72
|
+
u("p", null, v(m.description), 1)
|
|
66
73
|
], 2))), 128))
|
|
67
74
|
]),
|
|
68
|
-
d("div",
|
|
69
|
-
(
|
|
70
|
-
key:
|
|
71
|
-
class:
|
|
72
|
-
onClick: (
|
|
73
|
-
}, null, 10,
|
|
74
|
-
])
|
|
75
|
+
d.showIndicators ? (s(), n("div", E, [
|
|
76
|
+
(s(!0), n(y, null, g(r.value, (m, i) => (s(), n("span", {
|
|
77
|
+
key: i,
|
|
78
|
+
class: p(["indicator", { active: l.value === i }]),
|
|
79
|
+
onClick: (M) => _(i)
|
|
80
|
+
}, null, 10, O))), 128))
|
|
81
|
+
])) : b("", !0)
|
|
75
82
|
]));
|
|
76
83
|
}
|
|
77
|
-
}),
|
|
84
|
+
}), V = /* @__PURE__ */ S(D, [["__scopeId", "data-v-4198d280"]]), j = {
|
|
85
|
+
install: (e) => {
|
|
86
|
+
e.component("ArticleList", P);
|
|
87
|
+
}
|
|
88
|
+
}, q = {
|
|
78
89
|
install: (e) => {
|
|
79
|
-
e.component("HeroSlide",
|
|
90
|
+
e.component("HeroSlide", V);
|
|
80
91
|
}
|
|
81
|
-
},
|
|
92
|
+
}, G = {
|
|
82
93
|
install: (e) => {
|
|
83
|
-
e.component("ArticleList", P), e.component("HeroSlide",
|
|
94
|
+
e.component("ArticleList", P), e.component("HeroSlide", V);
|
|
84
95
|
}
|
|
85
96
|
};
|
|
86
97
|
export {
|
|
87
98
|
P as ArticleList,
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
99
|
+
j as ArticleListPlugin,
|
|
100
|
+
V as HeroSlide,
|
|
101
|
+
q as HeroSlidePlugin,
|
|
102
|
+
G as default
|
|
92
103
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
(function(l,e){typeof exports=="object"&&typeof module<"u"?e(exports,require("vue")):typeof define=="function"&&define.amd?define(["exports","vue"],e):(l=typeof globalThis<"u"?globalThis:l||self,e(l.OfficialBlock={},l.Vue))})(this,function(l,e){"use strict";const k={class:"content"},h=e.defineComponent({__name:"index",props:{size:{default:"medium"},disabled:{type:Boolean,default:!1},modelValue:{}},emits:["update:modelValue","change","focus"],setup(t,{emit:
|
|
1
|
+
(function(l,e){typeof exports=="object"&&typeof module<"u"?e(exports,require("vue")):typeof define=="function"&&define.amd?define(["exports","vue"],e):(l=typeof globalThis<"u"?globalThis:l||self,e(l.OfficialBlock={},l.Vue))})(this,function(l,e){"use strict";const k={class:"content"},h=e.defineComponent({name:"ArticleList",__name:"index",props:{size:{default:"medium"},disabled:{type:Boolean,default:!1},modelValue:{}},emits:["update:modelValue","change","focus"],setup(t,{emit:c}){const i=t,a=c,n=e.computed(()=>`Current value: ${i.modelValue}`);function r(){i.disabled||a("change",i.modelValue)}return(o,_)=>(e.openBlock(),e.createElementBlock("div",{class:e.normalizeClass(["your-component",[`size-${o.size}`,{"is-disabled":o.disabled}]]),onClick:r},[e.renderSlot(o.$slots,"header",{title:n.value},void 0,!0),e.createElementVNode("div",k,[e.renderSlot(o.$slots,"default",{value:o.modelValue},()=>[e.createTextVNode(e.toDisplayString(o.modelValue),1)],!0)])],2))}}),f=(t,c)=>{const i=t.__vccOpts||t;for(const[a,n]of c)i[a]=n;return i},m=f(h,[["__scopeId","data-v-03506405"]]),y={class:"hero-slide"},B={class:"slide-container"},g={key:0,class:"slide-indicators"},S=["onClick"],u=f(e.defineComponent({name:"HeroSlide",__name:"index",props:{autoPlayInterval:{default:3e3},showIndicators:{type:Boolean,default:!0},autoPlay:{type:Boolean,default:!0}},emits:["change","click"],setup(t,{emit:c}){const i=t,a=c,n=e.ref(0),r=e.ref([{title:"轮播图标题 1",description:"这是第一张轮播图的描述内容"},{title:"轮播图标题 2",description:"这是第二张轮播图的描述内容"},{title:"轮播图标题 3",description:"这是第三张轮播图的描述内容"}]);let o=null;const _=d=>{n.value=d,a("change",d)},P=()=>{n.value=(n.value+1)%r.value.length,a("change",n.value)},A=()=>{i.autoPlay&&(o=window.setInterval(P,i.autoPlayInterval))},I=()=>{o&&(clearInterval(o),o=null)};return e.onMounted(()=>{A()}),e.onUnmounted(()=>{I()}),(d,$)=>(e.openBlock(),e.createElementBlock("div",y,[e.createElementVNode("div",B,[(e.openBlock(!0),e.createElementBlock(e.Fragment,null,e.renderList(r.value,(p,s)=>(e.openBlock(),e.createElementBlock("div",{key:s,class:e.normalizeClass(["slide-item",{active:n.value===s}])},[e.createElementVNode("h2",null,e.toDisplayString(p.title),1),e.createElementVNode("p",null,e.toDisplayString(p.description),1)],2))),128))]),d.showIndicators?(e.openBlock(),e.createElementBlock("div",g,[(e.openBlock(!0),e.createElementBlock(e.Fragment,null,e.renderList(r.value,(p,s)=>(e.openBlock(),e.createElementBlock("span",{key:s,class:e.normalizeClass(["indicator",{active:n.value===s}]),onClick:b=>_(s)},null,10,S))),128))])):e.createCommentVNode("",!0)]))}}),[["__scopeId","data-v-4198d280"]]),V={install:t=>{t.component("ArticleList",m)}},C={install:t=>{t.component("HeroSlide",u)}},E={install:t=>{t.component("ArticleList",m),t.component("HeroSlide",u)}};l.ArticleList=m,l.ArticleListPlugin=V,l.HeroSlide=u,l.HeroSlidePlugin=C,l.default=E,Object.defineProperties(l,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}})});
|
package/dist/style.css
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
.your-component[data-v-
|
|
1
|
+
.your-component[data-v-03506405]{padding:16px;border:1px solid #ddd;border-radius:8px;background:#fff;transition:all .3s ease}.your-component[data-v-03506405]:hover{border-color:#409eff;box-shadow:0 2px 8px #409eff33}.your-component.is-disabled[data-v-03506405]{opacity:.6;cursor:not-allowed;background:#f5f5f5}.your-component.size-small[data-v-03506405]{padding:8px;font-size:12px}.your-component.size-medium[data-v-03506405]{padding:16px;font-size:14px}.your-component.size-large[data-v-03506405]{padding:24px;font-size:16px}.content[data-v-03506405]{margin-top:8px}.hero-slide[data-v-4198d280]{position:relative;width:100%;height:300px;overflow:hidden;border-radius:12px;box-shadow:0 4px 12px #0000001a}.slide-container[data-v-4198d280]{position:relative;width:100%;height:100%}.slide-item[data-v-4198d280]{position:absolute;top:0;left:0;width:100%;height:100%;display:flex;flex-direction:column;justify-content:center;align-items:center;background:linear-gradient(135deg,#667eea,#764ba2);color:#fff;opacity:0;transition:opacity .5s ease-in-out;text-align:center;padding:20px;box-sizing:border-box}.slide-item.active[data-v-4198d280]{opacity:1}.slide-item h2[data-v-4198d280]{margin:0 0 16px;font-size:2rem;font-weight:600}.slide-item p[data-v-4198d280]{margin:0;font-size:1.1rem;opacity:.9;max-width:600px}.slide-indicators[data-v-4198d280]{position:absolute;bottom:20px;left:50%;transform:translate(-50%);display:flex;gap:8px}.indicator[data-v-4198d280]{width:12px;height:12px;border-radius:50%;background:#ffffff80;cursor:pointer;transition:background .3s ease}.indicator.active[data-v-4198d280]{background:#fff}.indicator[data-v-4198d280]:hover{background:#fffc}
|
package/package.json
CHANGED
|
@@ -15,6 +15,11 @@
|
|
|
15
15
|
import { computed } from 'vue'
|
|
16
16
|
import type { ComponentProps, ComponentEmits, ComponentSlots } from './type'
|
|
17
17
|
|
|
18
|
+
// 定义组件名称
|
|
19
|
+
defineOptions({
|
|
20
|
+
name: 'ArticleList'
|
|
21
|
+
})
|
|
22
|
+
|
|
18
23
|
const props = withDefaults(defineProps<ComponentProps>(), {
|
|
19
24
|
size: 'medium',
|
|
20
25
|
disabled: false
|
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
<p>{{ slide.description }}</p>
|
|
12
12
|
</div>
|
|
13
13
|
</div>
|
|
14
|
-
<div class="slide-indicators">
|
|
14
|
+
<div v-if="showIndicators" class="slide-indicators">
|
|
15
15
|
<span
|
|
16
16
|
v-for="(_, index) in slides"
|
|
17
17
|
:key="index"
|
|
@@ -25,9 +25,23 @@
|
|
|
25
25
|
|
|
26
26
|
<script setup lang="ts">
|
|
27
27
|
import { ref, onMounted, onUnmounted } from 'vue'
|
|
28
|
+
import type { HeroSlideProps, HeroSlideEmits, SlideItem } from './type'
|
|
29
|
+
|
|
30
|
+
// 定义组件名称
|
|
31
|
+
defineOptions({
|
|
32
|
+
name: 'HeroSlide'
|
|
33
|
+
})
|
|
34
|
+
|
|
35
|
+
const props = withDefaults(defineProps<HeroSlideProps>(), {
|
|
36
|
+
autoPlayInterval: 3000,
|
|
37
|
+
showIndicators: true,
|
|
38
|
+
autoPlay: true
|
|
39
|
+
})
|
|
40
|
+
|
|
41
|
+
const emit = defineEmits<HeroSlideEmits>()
|
|
28
42
|
|
|
29
43
|
const currentSlide = ref(0)
|
|
30
|
-
const slides = ref([
|
|
44
|
+
const slides = ref<SlideItem[]>([
|
|
31
45
|
{ title: '轮播图标题 1', description: '这是第一张轮播图的描述内容' },
|
|
32
46
|
{ title: '轮播图标题 2', description: '这是第二张轮播图的描述内容' },
|
|
33
47
|
{ title: '轮播图标题 3', description: '这是第三张轮播图的描述内容' }
|
|
@@ -37,14 +51,18 @@ let autoPlayTimer: number | null = null
|
|
|
37
51
|
|
|
38
52
|
const goToSlide = (index: number) => {
|
|
39
53
|
currentSlide.value = index
|
|
54
|
+
emit('change', index)
|
|
40
55
|
}
|
|
41
56
|
|
|
42
57
|
const nextSlide = () => {
|
|
43
58
|
currentSlide.value = (currentSlide.value + 1) % slides.value.length
|
|
59
|
+
emit('change', currentSlide.value)
|
|
44
60
|
}
|
|
45
61
|
|
|
46
62
|
const startAutoPlay = () => {
|
|
47
|
-
|
|
63
|
+
if (props.autoPlay) {
|
|
64
|
+
autoPlayTimer = window.setInterval(nextSlide, props.autoPlayInterval)
|
|
65
|
+
}
|
|
48
66
|
}
|
|
49
67
|
|
|
50
68
|
const stopAutoPlay = () => {
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
export interface HeroSlideProps {
|
|
2
|
+
/** 自动播放间隔时间(毫秒) */
|
|
3
|
+
autoPlayInterval?: number
|
|
4
|
+
/** 是否显示指示器 */
|
|
5
|
+
showIndicators?: boolean
|
|
6
|
+
/** 是否启用自动播放 */
|
|
7
|
+
autoPlay?: boolean
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
export interface HeroSlideEmits {
|
|
11
|
+
(e: 'change', index: number): void
|
|
12
|
+
(e: 'click', index: number): void
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export interface SlideItem {
|
|
16
|
+
title: string
|
|
17
|
+
description: string
|
|
18
|
+
image?: string
|
|
19
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
// 导出所有组件
|
|
2
|
+
export { default as ArticleList } from './ArticleList/index.vue'
|
|
3
|
+
export { default as HeroSlide } from './HeroSlide/index.vue'
|
|
4
|
+
|
|
5
|
+
// 导出组件插件
|
|
6
|
+
export { default as ArticleListPlugin } from './ArticleList/index'
|
|
7
|
+
export { default as HeroSlidePlugin } from './HeroSlide/index'
|
|
8
|
+
|
|
9
|
+
// 导出类型定义
|
|
10
|
+
export type { ComponentProps, ComponentEmits, ComponentSlots } from './ArticleList/type'
|
|
11
|
+
export type { HeroSlideProps, HeroSlideEmits, SlideItem } from './HeroSlide/type'
|
package/src/index.ts
CHANGED
|
@@ -1,22 +1,29 @@
|
|
|
1
1
|
import type { App, Plugin } from 'vue'
|
|
2
|
-
import ArticleList from './components
|
|
3
|
-
import HeroSlide from './components/HeroSlide'
|
|
2
|
+
import { ArticleList, HeroSlide } from './components'
|
|
4
3
|
|
|
5
4
|
// 全部引入插件
|
|
6
|
-
|
|
5
|
+
const OfficialBlock = {
|
|
7
6
|
install: (app: App) => {
|
|
8
7
|
app.component('ArticleList', ArticleList)
|
|
9
8
|
app.component('HeroSlide', HeroSlide)
|
|
10
9
|
},
|
|
11
10
|
} satisfies Plugin
|
|
12
11
|
|
|
12
|
+
// 默认导出插件
|
|
13
|
+
export default OfficialBlock
|
|
14
|
+
|
|
13
15
|
// 按需引入 - 导出组件
|
|
14
|
-
export { ArticleList }
|
|
15
|
-
export { HeroSlide }
|
|
16
|
+
export { ArticleList, HeroSlide }
|
|
16
17
|
|
|
17
18
|
// 按需引入 - 导出单个组件的插件
|
|
18
|
-
export {
|
|
19
|
-
export { default as HeroSlidePlugin } from './components/HeroSlide'
|
|
19
|
+
export { ArticleListPlugin, HeroSlidePlugin } from './components'
|
|
20
20
|
|
|
21
21
|
// 导出类型定义
|
|
22
|
-
export type {
|
|
22
|
+
export type {
|
|
23
|
+
ComponentProps,
|
|
24
|
+
ComponentEmits,
|
|
25
|
+
ComponentSlots,
|
|
26
|
+
HeroSlideProps,
|
|
27
|
+
HeroSlideEmits,
|
|
28
|
+
SlideItem
|
|
29
|
+
} from './components'
|
package/src/types.ts
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
// 重新导出所有类型定义,确保类型能够正确生成
|
|
2
|
+
export type { ComponentProps, ComponentEmits, ComponentSlots } from './components/ArticleList/type'
|
|
3
|
+
export type { HeroSlideProps, HeroSlideEmits, SlideItem } from './components/HeroSlide/type'
|
|
4
|
+
|
|
5
|
+
// 插件类型
|
|
6
|
+
export interface OfficialBlockPlugin {
|
|
7
|
+
install: (app: any) => void
|
|
8
|
+
}
|