Commit 0101b742 by yuyang

fix: 组件集合

parent 0280e06e
......@@ -13,6 +13,7 @@
"deploy:production": "npm run lint && npm run build && node scripts/deploy.js"
},
"dependencies": {
"ant-design-vue": "^1.7.4",
"axios": "^0.19.2",
"change-case": "^4.1.1",
"core-js": "^3.6.5",
......
<script lang="ts">
import { Component, Vue, Prop } from 'vue-property-decorator';
@Component
export default class BadgeText extends Vue {
@Prop({ type: Number }) private count!: number;
}
</script>
<template lang="pug">
.badge-text(v-if="count")
| {{ count > 99 ? '99+' : count }}
</template>
<style lang="stylus" scoped>
.badge-text
font-size 12px
color #ffffff
background #e50114
display inline-block
padding 2px 6px
line-height 16px
align-self center
border-radius 20px
margin 0 6px
</style>
<template lang="pug">
.cell
.key {{ label }}
.value
slot(name="value")
span(v-if="isPrice") ¥{{ value }}
span(v-else) {{value}}
</template>
<script lang="ts">
import { Component, Vue, Prop, Watch, Emit } from 'vue-property-decorator';
@Component({
components: {},
})
export default class ComCell extends Vue {
@Prop({ type: String, default: '' }) private label!: string;
@Prop({ default: '' }) private value!: string;
@Prop({ type: Boolean, default: false }) private isPrice!: boolean;
}
</script>
<style lang="stylus" scoped>
.cell
display flex
padding 8px 0px
font-size 14px
line-height 22px
.key
min-width 100px
color #808080
.value
color #383838
@media print
.cell
padding 0px
</style>
<script lang="ts">
import { Component, Vue, Prop, Model } from 'vue-property-decorator';
@Component({
components: {},
})
export default class ComCurrencyInput extends Vue {
@Model('change', { type: [Number, String] }) value!: number;
@Prop({ type: Boolean, default: false }) disabled!: boolean;
@Prop({ type: Number, default: Infinity }) max!: number;
@Prop({ type: Number, default: 0 }) min!: number;
@Prop({ type: Number, default: 2 }) precision!: number;
@Prop({ type: [Number, String], default: 1 }) step!: number;
@Prop({ type: String }) placeholder!: string;
@Prop({ type: String }) name!: string;
set number(value: number) {
const val = Number(value);
if (val) {
if (val <= this.min) {
this.$emit('change', this.min);
} else if (val >= this.max) {
this.$emit('change', this.max);
} else {
this.$emit('change', val);
}
} else {
this.$emit('change', null);
}
}
get number() {
return this.value;
}
blur() {
(this.$refs.input as any).blur();
}
focus() {
(this.$refs.input as any).focus();
}
parseInput(value: any) {
return value.replace(/\$\s?|(,*)/g, '');
}
formatInput(value: any) {
const val = Number(value);
if (val) {
if (val <= this.min) {
return `${this.min}`.replace(/\B(?=(\d{3})+(?!\d))/g, ',');
} else if (val >= this.max) {
return `${this.max}`.replace(/\B(?=(\d{3})+(?!\d))/g, ',');
}
return `${value}`.replace(/\B(?=(\d{3})+(?!\d))/g, ',');
}
return null;
}
}
</script>
<template lang="pug">
a-input-number(
ref="input"
v-model.number="number"
:name="name"
:max="max"
:min="min"
:disabled="disabled"
:placeholder="placeholder"
:formatter="formatInput"
:parser="parseInput")
</template>
<style lang="stylus" scoped></style>
<template lang="pug">
.empty-placeholder
img(v-if="type === 'school'" src="@/assets/icons/empty/school.png" width="80" height="80")
img(v-else-if="type === 'table'" src="@/assets/icons/empty/table.png" width="80" height="80")
img(v-else-if="type === 'survey'" src="@/assets/icons/empty/survey.png" width="80" height="80")
img(v-else src="@/assets/icons/empty/empty.png" width="80" height="80")
.desc {{ desc }}
.tips {{ tips }}
.action
slot
</template>
<script lang="ts">
import { Component, Vue, Prop, Watch, Emit } from 'vue-property-decorator';
@Component({
components: {},
})
export default class ComEmpty extends Vue {
// prop
@Prop({ type: String, default: '暂无相应内容' }) private desc!: string;
@Prop({ type: String, default: '' }) private tips!: string;
@Prop({ type: String, default: 'table' }) private type!: string; // personnel、school、table、survey
}
</script>
<style lang="stylus" scoped>
.empty-placeholder
padding 60px 0px
width 100%
text-align center
line-height 1
img
margin-bottom 10px
.desc
margin-bottom 12px
color #808080
font-weight 500
font-size 16px
.tips
margin-bottom 22px
color #A6A6A6
font-size 14px
.action
button
min-width 100px
height 40px
</style>
<script lang="ts">
import { Component, Vue, Prop } from 'vue-property-decorator';
@Component
export default class ComFileInput extends Vue {
@Prop({ type: String }) accept!: string;
@Prop({ type: Boolean, default: false }) multiple!: boolean;
@Prop({ type: Boolean, default: false }) disabled!: boolean;
@Prop({ type: Boolean, default: false }) loading!: boolean;
handleFileInputChange(e: any) {
this.$emit('change', [...e.target.files]);
}
clickFileInput(e: any) {
if (this.loading) return;
if (e.target && e.target.tagName === 'BUTTON') {
(this.$refs.fileInput as any).click();
e.stopPropagation();
} else {
const path: HTMLDivElement[] = e.path;
const triggerIndex = path.findIndex(o => o.classList && o.classList.contains('file-input-wrapper'));
const triggerElement = path[triggerIndex - 1];
if (triggerElement && triggerElement.tagName === 'BUTTON') {
(this.$refs.fileInput as any).click();
}
e.stopPropagation();
}
}
}
</script>
<template lang="pug">
.file-input-wrapper(@click="clickFileInput")
input.file-input(
ref="fileInput"
type="file"
:value="[]"
:accept="accept"
:multiple="multiple"
:disabled="disabled"
@click.stop=""
@change="handleFileInputChange")
slot
a-button(type="primary" icon="upload" :disabled="disabled" :loading="loading")
| 选择文件
</template>
<style lang="stylus" scoped>
.file-input-wrapper
position relative
display inline-block
.file-input
position absolute
top 0
left 0
display inline
margin 0
padding 0
width 0px
height 0px
outline none
border none
opacity 0
button
*
pointer-events none
</style>
<script lang="ts">
import { Component, Vue, Prop } from 'vue-property-decorator';
@Component({
components: {},
})
export default class ComGlobal extends Vue {
@Prop({ type: String, default: '' }) prop!: string;
state = '';
number = 8;
}
</script>
<template lang="pug">
.container
ComGlobalTable(name="组件名")
div 样式
ComGlobalTable(name="BadgeText")
BadgeText(:count="2")
BadgeText(:count="100")
ComGlobalTable(name="ComCell")
ComCell(label="商品价格",value='9.99',:isPrice="true")
ComGlobalTable(name="ComCurrencyInput")
ComCurrencyInput(
v-model="number",
:disabled="false"
:max="10",
:min="0",
:precision='20'
placeholder="请输入金额",
name="费用"
)
ComGlobalTable(name="ComEmpty")
ComEmpty(
tips="副标题"
)
ComGlobalTable(name="ComFileInput")
ComFileInput(
accept="副标题",
:multiple="true",
:disabled="true",
:loading="true",
)
ComFileInput(
accept="副标题",
:multiple="false",
:disabled="false",
:loading="false",
)
</template>
<style lang="stylus" scoped></style>
<script lang="ts">
import { Component, Vue, Prop } from 'vue-property-decorator';
@Component({
components: {},
})
export default class ComGlobalTable extends Vue {
@Prop({ type: String, default: '' }) name!: string;
}
</script>
<template lang="pug">
.table
.name
| {{name}}
.components
slot
</template>
<style lang="stylus" scoped>
.table
display flex
align-items center
border-bottom 1px solid #e3e3e3
line-height 40px
.name
text-align center
width 200px
.components
display flex
align-items center
justify-content center
width 100px
flex 1
border-left 1px solid #e3e3e3
</style>
<template lang="pug">
h3.hello
| {{ msg }}
| {{ msg }}213
ComGlobal
</template>
<script lang="ts">
......
......@@ -7,13 +7,15 @@ import store from './store';
import utils from './utils';
import moment from 'moment';
import '@/components/global';
import 'ant-design-vue/dist/antd.css';
import Antd from 'ant-design-vue';
moment.locale('zh-cn');
Vue.config.productionTip = false;
Vue.prototype.$moment = moment;
Vue.prototype.$utils = utils;
Vue.use(Antd);
new Vue({
router,
store,
......
<script lang="ts">
import { Component, Vue, Prop } from 'vue-property-decorator';
@Component({
components: {},
})
export default class About extends Vue {
@Prop({ type: String, default: '' }) prop!: string;
state = '';
}
</script>
<template lang="pug">
.about
h1 This is an about page
.container
ComGlobal
</template>
<style lang="stylus" scoped></style>
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment