Browse Source

Complete TagSelect component

pull/9/head
johnniang 6 years ago
parent
commit
937b461374
  1. 10
      src/api/tag.js
  2. 75
      src/views/post/PostEdit.vue
  3. 103
      src/views/post/components/TagSelect.vue

10
src/api/tag.js

@ -14,6 +14,16 @@ tagApi.listAll = (more = false) => {
}) })
} }
tagApi.createWithName = name => {
return service({
url: baseUrl,
data: {
name: name
},
method: 'post'
})
}
tagApi.create = tag => { tagApi.create = tag => {
return service({ return service({
url: baseUrl, url: baseUrl,

75
src/views/post/PostEdit.vue

@ -1,7 +1,13 @@
<template> <template>
<div class="page-header-index-wide"> <div class="page-header-index-wide">
<a-row :gutter="12"> <a-row :gutter="12">
<a-col :xl="24" :lg="24" :md="24" :sm="24" :xs="24"> <a-col
:xl="24"
:lg="24"
:md="24"
:sm="24"
:xs="24"
>
<div style="margin-bottom: 16px"> <div style="margin-bottom: 16px">
<a-input <a-input
v-model="postToStage.title" v-model="postToStage.title"
@ -12,11 +18,21 @@
</div> </div>
<div id="editor"> <div id="editor">
<mavon-editor v-model="postToStage.originalContent" :boxShadow="false" :ishljs="true"/> <mavon-editor
v-model="postToStage.originalContent"
:boxShadow="false"
:ishljs="true"
/>
</div> </div>
</a-col> </a-col>
<a-col :xl="24" :lg="24" :md="24" :sm="24" :xs="24"> <a-col
:xl="24"
:lg="24"
:md="24"
:sm="24"
:xs="24"
>
<a-drawer <a-drawer
title="文章设置" title="文章设置"
:width="isMobile()?'100%':'460'" :width="isMobile()?'100%':'460'"
@ -36,10 +52,16 @@
<a-input v-model="postToStage.url" /> <a-input v-model="postToStage.url" />
</a-form-item> </a-form-item>
<a-form-item label="文章密码:"> <a-form-item label="文章密码:">
<a-input type="password" v-model="postToStage.password"/> <a-input
type="password"
v-model="postToStage.password"
/>
</a-form-item> </a-form-item>
<a-form-item label="是否关闭评论:"> <a-form-item label="是否关闭评论:">
<a-radio-group v-model="postToStage.disallowComment" :defaultValue="false"> <a-radio-group
v-model="postToStage.disallowComment"
:defaultValue="false"
>
<a-radio :value="false">开启</a-radio> <a-radio :value="false">开启</a-radio>
<a-radio :value="true">关闭</a-radio> <a-radio :value="true">关闭</a-radio>
</a-radio-group> </a-radio-group>
@ -52,7 +74,10 @@
<div :style="{ marginBottom: '16px' }"> <div :style="{ marginBottom: '16px' }">
<h3 class="post-setting-drawer-title">分类目录</h3> <h3 class="post-setting-drawer-title">分类目录</h3>
<div class="post-setting-drawer-item"> <div class="post-setting-drawer-item">
<category-tree v-model="selectedCategoryIds" :categories="categories"/> <category-tree
v-model="selectedCategoryIds"
:categories="categories"
/>
</div> </div>
</div> </div>
<a-divider /> <a-divider />
@ -62,7 +87,8 @@
<div class="post-setting-drawer-item"> <div class="post-setting-drawer-item">
<a-form layout="vertical"> <a-form layout="vertical">
<a-form-item> <a-form-item>
<a-select <TagSelect v-model="selectedTagIds" />
<!-- <a-select
v-model="selectedTagIds" v-model="selectedTagIds"
allowClear allowClear
mode="multiple" mode="multiple"
@ -73,7 +99,7 @@
:key="tag.id" :key="tag.id"
:value="tag.id" :value="tag.id"
>{{ tag.name }}</a-select-option> >{{ tag.name }}</a-select-option>
</a-select> </a-select> -->
</a-form-item> </a-form-item>
</a-form> </a-form>
</div> </div>
@ -94,11 +120,21 @@
</div> </div>
<a-divider /> <a-divider />
</div> </div>
<AttachmentSelectDrawer v-model="childDrawerVisible" @listenToSelect="selectPostThumb" :drawerWidth="460"/> <AttachmentSelectDrawer
v-model="childDrawerVisible"
@listenToSelect="selectPostThumb"
:drawerWidth="460"
/>
<a-divider /> <a-divider />
<div class="bottom-control"> <div class="bottom-control">
<a-button style="marginRight: 8px" @click="handleDraftClick">保存草稿</a-button> <a-button
<a-button @click="handlePublishClick" type="primary">{{ publishText }}</a-button> style="marginRight: 8px"
@click="handleDraftClick"
>保存草稿</a-button>
<a-button
@click="handlePublishClick"
type="primary"
>{{ publishText }}</a-button>
</div> </div>
</a-drawer> </a-drawer>
</a-col> </a-col>
@ -106,17 +142,23 @@
<AttachmentDrawer v-model="attachmentDrawerVisible" /> <AttachmentDrawer v-model="attachmentDrawerVisible" />
<footer-tool-bar <footer-tool-bar :style="{ width: isSideMenu() && isDesktop() ? `calc(100% - ${sidebarOpened ? 256 : 80}px)` : '100%'}">
:style="{ width: isSideMenu() && isDesktop() ? `calc(100% - ${sidebarOpened ? 256 : 80}px)` : '100%'}" <a-button
> type="primary"
<a-button type="primary" @click="showDrawer">发布</a-button> @click="showDrawer"
<a-button type="dashed" @click="showAttachDrawer" style="margin-left: 8px;">附件库</a-button> >发布</a-button>
<a-button
type="dashed"
@click="showAttachDrawer"
style="margin-left: 8px;"
>附件库</a-button>
</footer-tool-bar> </footer-tool-bar>
</div> </div>
</template> </template>
<script> <script>
import CategoryTree from './components/CategoryTree' import CategoryTree from './components/CategoryTree'
import TagSelect from './components/TagSelect'
import { mavonEditor } from 'mavon-editor' import { mavonEditor } from 'mavon-editor'
import FooterToolBar from '@/components/FooterToolbar' import FooterToolBar from '@/components/FooterToolbar'
import { mixin, mixinDevice } from '@/utils/mixin.js' import { mixin, mixinDevice } from '@/utils/mixin.js'
@ -150,6 +192,7 @@ const toolbars = {
export default { export default {
name: 'Editor', name: 'Editor',
components: { components: {
TagSelect,
mavonEditor, mavonEditor,
CategoryTree, CategoryTree,
FooterToolBar, FooterToolBar,

103
src/views/post/components/TagSelect.vue

@ -0,0 +1,103 @@
<template>
<div>
<a-select
v-model="selectedTagNames"
style="width: 100%"
allowClear
mode="tags"
placeholder="选择或输入标签"
@blur="handleBlur"
>
<a-select-option
v-for="tag in tags"
:key="tag.id"
:value="tag.name"
>{{ tag.name }}</a-select-option>
</a-select>
</div>
</template>
<script>
import tagApi from '@/api/tag'
import axios from 'axios'
export default {
name: 'TagSelect',
model: {
prop: 'tagIds',
event: 'change'
},
props: {
tagIds: {
type: Array,
required: false,
default: () => []
}
},
data() {
return {
tags: [],
selectedTagNames: []
}
},
created() {
this.loadTags()
this.selectedTagNames = this.tagIds.map(tagId => this.tagIdMap[tagId].name)
},
computed: {
tagIdMap() {
const tagIdMap = {}
this.tags.forEach(tag => {
tagIdMap[tag.id] = tag
})
return tagIdMap
},
tagNameMap() {
const tagNameMap = {}
this.tags.forEach(tag => {
tagNameMap[tag.name] = tag
})
return tagNameMap
}
},
methods: {
loadTags(callback) {
tagApi.listAll(true).then(response => {
this.tags = response.data.data
if (callback) {
callback()
}
})
},
handleBlur() {
this.$log.debug('Blured')
const tagNamesToCreate = this.selectedTagNames.filter(tagName => !this.tagNameMap[tagName])
this.$log.debug('Tag names to create', tagNamesToCreate)
if (tagNamesToCreate === []) {
const tagIds = this.selectedTagNames.map(tagName => this.tagNameMap[tagName].id)
// If empty
this.$emit('change', tagIds)
return
}
const createPromises = tagNamesToCreate.map(tagName => tagApi.createWithName(tagName))
axios.all(createPromises).then(
axios.spread(() => {
this.loadTags(() => {
this.$log.debug('Tag name map', this.tagNameMap)
// Get all tag id
const tagIds = this.selectedTagNames.map(tagName => this.tagNameMap[tagName].id)
this.$emit('change', tagIds)
})
})
)
}
}
}
</script>
<style>
</style>
Loading…
Cancel
Save