完善表单样式

This commit is contained in:
ghusermoon 2020-09-28 16:42:50 +08:00
parent 2df67c06c7
commit 5e2a70b1ad
7 changed files with 201 additions and 41 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

BIN
src/static/images/link.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

BIN
src/static/images/smile.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

View File

@ -0,0 +1,20 @@
/**
* Base64
*/
function getBase64(file: File): Promise<string | ArrayBuffer | null> {
return new Promise((resolve, reject) => {
const reader = new FileReader();
reader.readAsDataURL(file);
reader.onload = () => resolve(reader.result);
reader.onerror = error => reject(error);
});
}
/**
*
*/
export async function previewCover(file: any): Promise<string> {
if (!file.url && !file.preview) {
file.preview = await getBase64(file.originFileObj);
}
return file.url || file.preview || '';
}

View File

@ -107,7 +107,7 @@
</div> </div>
<div class="input-box introduce"> <div class="input-box introduce">
<div class="label">自我介绍</div> <div class="label">自我介绍</div>
<a-textarea v-model:value="formData.introduce" /> <a-textarea v-model:value="formData.introduce" class="introduce-textarea" />
</div> </div>
</div> </div>
</div> </div>
@ -322,7 +322,7 @@ export default defineComponent({
} }
.main-container { .main-container {
margin-left: 17px; margin-left: 17px;
.input-box { ::v-deep .input-box {
display: flex; display: flex;
align-items: center; align-items: center;
margin-bottom: 28px; margin-bottom: 28px;
@ -341,12 +341,16 @@ export default defineComponent({
border-radius: 3px; border-radius: 3px;
border: 1px solid #DCDFE0; border: 1px solid #DCDFE0;
font-size: 11px; font-size: 11px;
color: #3F3F3F;
} }
.ant-select { .ant-select {
font-size: 12px; font-size: 12px;
color: #3F3F3F;
} }
.ant-select-dropdown { .ant-select-dropdown {
font-size: 12px; .ant-select-dropdown-menu-item {
font-size: 12px;
}
} }
} }
.speak-lang { .speak-lang {
@ -403,6 +407,11 @@ export default defineComponent({
.ant-input { .ant-input {
width: 359px; width: 359px;
} }
.introduce-textarea {
height: 85px;
min-height: 85px;
max-height: 85px;
}
} }
.phone-box { .phone-box {
.phone { .phone {

View File

@ -5,26 +5,32 @@
<a-form-item label="视频标题"> <a-form-item label="视频标题">
<a-input size="small" v-model:value="form.title" placeholder="请输入您的视频标题" /> <a-input size="small" v-model:value="form.title" placeholder="请输入您的视频标题" />
</a-form-item> </a-form-item>
<a-form-item label="视频封面"> <a-form-item label="视频封面" class="video-cover">
<a-upload <a-upload
list-type="picture" list-type="picture"
action="//jsonplaceholder.typicode.com/posts/" @change="coverChange"
> >
<div class="upload-image"> <div class="upload-image" v-if="!viewCover">
<PlusOutlined style="fontSize: 22px;" /> <PlusOutlined style="fontSize: 22px;" />
</div> </div>
<div class="preview-image" v-else>
<img style="width: 100%" :src="previewImage" />
</div>
</a-upload> </a-upload>
</a-form-item> </a-form-item>
<a-form-item label="选择视频" class="video-introduction"> <a-form-item label="选择视频" class="video-introduction">
<div class="upload-container"> <div class="upload-container">
<a-upload <a-upload :beforeUpload="beforeVideoUpload">
:beforeUpload="beforeUpload"
>
<div class="upload-image"> <div class="upload-image">
<PlaySquareOutlined style="fontSize: 22px;" /> <PlaySquareOutlined style="fontSize: 22px;" />
</div> </div>
</a-upload> </a-upload>
<div v-for="(item, index) in form.video" :key="index">{{ item.name }}</div> <!-- 文件列表 -->
<div v-for="(item, index) in form.video" :key="index" class="video-list">
<img src="@/static/images/link.png" class="link" />
<span class="one-line-hide">{{ item.name }}</span>
<img src="@/static/images/delete.png" @click="removeFile(index)" class="del" />
</div>
</div> </div>
<div class="demand"> <div class="demand">
<p class="one-line-hide">视频要求</p> <p class="one-line-hide">视频要求</p>
@ -32,7 +38,8 @@
</div> </div>
</a-form-item> </a-form-item>
<a-form-item label="视频简介" class="brief"> <a-form-item label="视频简介" class="brief">
<a-textarea v-model:value="form.brief" :maxlength="200" placeholder="请输入您的视频简介" /> <a-textarea v-model:value="form.brief" :autoSize="true" class="brief-textarea" :maxlength="200" placeholder="请输入您的视频简介" />
<span class="words-number">{{ form.brief.length }}/200</span>
</a-form-item> </a-form-item>
<a-form-item :wrapper-col="{ span: 4, offset: 0 }"> <a-form-item :wrapper-col="{ span: 4, offset: 0 }">
<a-button @click="onSubmit">上传视频</a-button> <a-button @click="onSubmit">上传视频</a-button>
@ -42,9 +49,10 @@
</div> </div>
</template> </template>
<script lang="ts"> <script lang="ts">
import { defineComponent, reactive } from 'vue'; import { defineComponent, reactive, Ref, ref } from 'vue';
import { PlaySquareOutlined, PlusOutlined } from '@ant-design/icons-vue'; import { PlaySquareOutlined, PlusOutlined } from '@ant-design/icons-vue';
import NavBottom from '@/components/NavBottom.vue'; import NavBottom from '@/components/NavBottom.vue';
import { previewCover } from '@/static/js/common';
export default defineComponent({ export default defineComponent({
name: 'ReleaseWebcast', name: 'ReleaseWebcast',
@ -59,7 +67,6 @@ export default defineComponent({
name: string; name: string;
} }
const fileList: Array<FileItem> = []; const fileList: Array<FileItem> = [];
console.log(fileList);
// //
const form = reactive({ const form = reactive({
@ -68,12 +75,48 @@ export default defineComponent({
brief: '', brief: '',
video: fileList, video: fileList,
}); });
//
const viewCover: Ref<boolean> = ref(false),
previewImage: Ref<string> = ref('');
/**
* 封面改变触发事件
*/
function coverChange(info: any): void {
// console.log(info);
//
previewCover(info.file).then(url => previewImage.value = url);
viewCover.value = true;
// form.cover = fileList;
}
/**
* 删除视频列表
* @param index 删除文件的索引
*/
function removeFile(index: number): void {
const newFileList = form.video.slice();
newFileList.splice(index, 1);
form.video = newFileList;
}
/**
* 上传封面之前的钩子
* @param file 上传的文件
*/
const beforeCoverUpload = (file: File): boolean => {
console.log(file);
return false;
}
/**
* 删除封面
*/
function cancelCover(file: any): void {
console.log(file);
}
/** /**
* 上传文件之前的钩子 * 上传文件之前的钩子
* @param file 上传的文件 * @param file 上传的文件
*/ */
const beforeUpload = (file: any): boolean => { const beforeVideoUpload = (file: any): boolean => {
// console.log(file); // console.log(file);
if(file.type != '') { if(file.type != '') {
// handleRemove(file); // handleRemove(file);
@ -87,14 +130,19 @@ export default defineComponent({
const onSubmit = (e: any) => { const onSubmit = (e: any) => {
e.preventDefault(); e.preventDefault();
}; };
console.log(form.video);
return { return {
labelCol: { span: 4 }, labelCol: { span: 4 },
wrapperCol: { span: 14 }, wrapperCol: { span: 14 },
form, form,
fileList, viewCover,
beforeUpload, previewImage,
removeFile,
previewCover,
coverChange,
cancelCover,
beforeCoverUpload,
beforeVideoUpload,
onSubmit, onSubmit,
} }
} }
@ -108,7 +156,7 @@ export default defineComponent({
padding: 46px; padding: 46px;
border-radius: 17px; border-radius: 17px;
position: relative; position: relative;
/deep/ .ant-form { ::v-deep .ant-form {
.title { .title {
font-size: 12px; font-size: 12px;
font-weight: bold; font-weight: bold;
@ -144,6 +192,7 @@ export default defineComponent({
border-radius: 3px; border-radius: 3px;
border: 1px solid #DCDFE0; border: 1px solid #DCDFE0;
font-size: 11px; font-size: 11px;
color: #3F3F3F;
&::-webkit-input-placeholder{ &::-webkit-input-placeholder{
font-size: 12px; font-size: 12px;
color: #808080; color: #808080;
@ -151,25 +200,13 @@ export default defineComponent({
} }
.ant-select { .ant-select {
font-size: 12px; font-size: 12px;
color: #3F3F3F;
} }
.ant-select-dropdown { .ant-select-dropdown {
font-size: 12px; font-size: 12px;
} }
.ant-upload-list { .ant-upload-list {
display: none; display: none;
color: #08AE98;
&:hover {
background-color: #ffffff;
}
.ant-upload-list-item {
opacity: 1;
.ant-upload-list-item-info {
background-color: #ffffff;
.anticon-paper-clip {
color: #08AE98;
}
}
}
} }
.ant-btn { .ant-btn {
padding: 0; padding: 0;
@ -182,23 +219,54 @@ export default defineComponent({
color: #FFFFFF; color: #FFFFFF;
} }
} }
.video-cover {
.preview-image {
width: 171px;
height: 96px;
}
}
.video-introduction { .video-introduction {
.ant-form-item-control-wrapper { .ant-form-item-control-wrapper {
.ant-form-item-children { .ant-form-item-children {
display: flex; display: flex;
align-items: center; // align-items: center;
.demand { .demand {
line-height: 17px; height: 94px;
font-size: 10px; font-size: 10px;
font-weight: 500; font-weight: 500;
color: #808080; color: #808080;
width: 134px; width: 134px;
display: flex;
flex-direction: column;
justify-content: center;
> p { > p {
line-height: 17px;
margin: 0; margin: 0;
} }
} }
} }
} }
.video-list {
display: flex;
align-items: center;
.link {
width: 11px;
height: 11px;
margin-right: 4px;
}
> span {
font-size: 9px;
font-weight: 500;
color: #07AD97;
max-width: 150px;
}
.del {
width: 11px;
height: 11px;
margin-left: auto;
cursor: pointer;
}
}
} }
.duration { .duration {
.unit { .unit {
@ -209,9 +277,23 @@ export default defineComponent({
} }
} }
.brief { .brief {
position: relative;
.ant-input { .ant-input {
width: 359px; width: 359px;
} }
.brief-textarea {
min-height: 85px;
padding-bottom: 30px;
}
.words-number {
position: absolute;
right: 11px;
bottom: -11px;
font-size: 11px;
font-weight: 500;
color: #7F7F7F;
user-select: none;
}
} }
} }
} }

View File

@ -5,14 +5,18 @@
<a-form-item label="直播标题"> <a-form-item label="直播标题">
<a-input size="small" v-model:value="form.title" placeholder="请输入您的直播标题" /> <a-input size="small" v-model:value="form.title" placeholder="请输入您的直播标题" />
</a-form-item> </a-form-item>
<a-form-item label="直播封面"> <a-form-item label="直播封面" class="item-cover">
<a-upload <a-upload
list-type="picture" list-type="picture"
@change="coverChange"
action="//jsonplaceholder.typicode.com/posts/" action="//jsonplaceholder.typicode.com/posts/"
> >
<div class="upload-image"> <div class="upload-image" v-if="!viewCover">
<PlusOutlined style="fontSize: 22px;" /> <PlusOutlined style="fontSize: 22px;" />
</div> </div>
<div class="preview-image" v-else>
<img style="width: 100%" :src="previewImage" />
</div>
</a-upload> </a-upload>
</a-form-item> </a-form-item>
<a-form-item label="视频介绍" class="video-introduction"> <a-form-item label="视频介绍" class="video-introduction">
@ -42,7 +46,8 @@
<a-input size="small" v-model:value="form.number" placeholder="请输入直播人数" /> <a-input size="small" v-model:value="form.number" placeholder="请输入直播人数" />
</a-form-item> </a-form-item>
<a-form-item label="直播简介" class="brief"> <a-form-item label="直播简介" class="brief">
<a-textarea v-model:value="form.brief" maxlength="200" placeholder="请输入您的直播简介" /> <a-textarea v-model:value="form.brief" :autosize="true" class="brief-textarea" maxlength="200" placeholder="请输入您的直播简介" />
<span class="words-number">{{ form.brief.length }}/200</span>
</a-form-item> </a-form-item>
<a-form-item :wrapper-col="{ span: 4, offset: 0 }"> <a-form-item :wrapper-col="{ span: 4, offset: 0 }">
<a-button @click="onSubmit">发布直播</a-button> <a-button @click="onSubmit">发布直播</a-button>
@ -52,10 +57,11 @@
</div> </div>
</template> </template>
<script lang="ts"> <script lang="ts">
import { defineComponent, reactive, toRaw } from 'vue'; import { defineComponent, reactive, Ref, ref, toRaw } from 'vue';
import { PlaySquareOutlined, PlusOutlined } from '@ant-design/icons-vue'; import { PlaySquareOutlined, PlusOutlined } from '@ant-design/icons-vue';
import { useForm } from '@ant-design-vue/use'; import { useForm } from '@ant-design-vue/use';
import NavBottom from '@/components/NavBottom.vue'; import NavBottom from '@/components/NavBottom.vue';
import { previewCover } from '@/static/js/common';
export default defineComponent({ export default defineComponent({
name: 'ReleaseWebcast', name: 'ReleaseWebcast',
@ -78,13 +84,13 @@ export default defineComponent({
/** /**
* 验证直播时间 * 验证直播时间
*/ */
const validateDuration = async (rule: object, value: number): Promise<string | void> => { async function validateDuration (rule: object, value: number): Promise<string | void> {
if (value < 30 || value > 120) { if (value < 30 || value > 120) {
return Promise.reject('*最短30min 最长120min'); return Promise.reject('*最短30min 最长120min');
} else { } else {
return Promise.resolve(); return Promise.resolve();
} }
}; }
/** /**
* 验证直播人数 * 验证直播人数
*/ */
@ -110,6 +116,22 @@ export default defineComponent({
}, },
], ],
}); });
//
const viewCover: Ref<boolean> = ref(false),
previewImage: Ref<string> = ref('');
/**
* 封面改变触发事件
*/
function coverChange(info: any): void {
// console.log(info);
//
previewCover(info.file).then(url => previewImage.value = url);
viewCover.value = true;
// form.cover = fileList;
}
const { resetFields, validate, validateInfos } = useForm(form, rules); const { resetFields, validate, validateInfos } = useForm(form, rules);
/** /**
* 表单提交 * 表单提交
@ -127,6 +149,9 @@ export default defineComponent({
wrapperCol: { span: 14 }, wrapperCol: { span: 14 },
validateInfos, validateInfos,
resetFields, resetFields,
viewCover,
previewImage,
coverChange,
form, form,
onSubmit, onSubmit,
} }
@ -141,7 +166,7 @@ export default defineComponent({
padding: 46px; padding: 46px;
border-radius: 17px; border-radius: 17px;
position: relative; position: relative;
/deep/ .ant-form { ::v-deep .ant-form {
.title { .title {
font-size: 12px; font-size: 12px;
font-weight: bold; font-weight: bold;
@ -177,6 +202,7 @@ export default defineComponent({
border-radius: 3px; border-radius: 3px;
border: 1px solid #DCDFE0; border: 1px solid #DCDFE0;
font-size: 11px; font-size: 11px;
color: #3F3F3F;
&::-webkit-input-placeholder{ &::-webkit-input-placeholder{
font-size: 12px; font-size: 12px;
color: #808080; color: #808080;
@ -193,6 +219,9 @@ export default defineComponent({
font-weight: 500; font-weight: 500;
color: #D22D2E; color: #D22D2E;
} }
.ant-upload-list {
display: none;
}
.ant-btn { .ant-btn {
padding: 0; padding: 0;
width: 63px; width: 63px;
@ -204,6 +233,12 @@ export default defineComponent({
color: #FFFFFF; color: #FFFFFF;
} }
} }
.item-cover {
.preview-image {
width: 171px;
height: 96px;
}
}
.video-introduction { .video-introduction {
.ant-form-item-control-wrapper { .ant-form-item-control-wrapper {
.ant-form-item-children { .ant-form-item-children {
@ -231,9 +266,23 @@ export default defineComponent({
} }
} }
.brief { .brief {
position: relative;
.ant-input { .ant-input {
width: 359px; width: 359px;
} }
.brief-textarea {
min-height: 85px;
padding-bottom: 30px;
}
.words-number {
position: absolute;
right: 11px;
bottom: -11px;
font-size: 11px;
font-weight: 500;
color: #7F7F7F;
user-select: none;
}
} }
} }
} }