refactor: 💡 综合实例查看详情重构

This commit is contained in:
chenkl 2020-12-28 09:50:04 +08:00
parent e77a931ef2
commit 9c26edd5d5
16 changed files with 340 additions and 34 deletions

View File

@ -37,7 +37,7 @@
<template v-else>{{ item.label }}</template> <template v-else>{{ item.label }}</template>
</div> </div>
<div class="content__item--message" :style="messageStyleObj"> <div class="content__item--message" :style="messageStyleObj">
<slot v-if="item.slots && item.slots.default" :name="item.slots.default" :row="item" /> <slot v-if="item.slots && item.slots.default" :name="item.slots.default" :row="data" />
<template v-else>{{ data[item.field] }}</template> <template v-else>{{ data[item.field] }}</template>
</div> </div>
</div> </div>
@ -195,12 +195,15 @@ export default defineComponent({
height: 100%; height: 100%;
} }
.content__item--label { .content__item--label {
font-size: 14px;
padding: 8px 16px; padding: 8px 16px;
} }
.content__item--message { .content__item--message {
flex: 1; flex: 1;
font-size: 14px;
padding: 8px 16px; padding: 8px 16px;
line-height: 20px; line-height: 20px;
color: #606266;
} }
} }
} }

View File

@ -40,6 +40,9 @@ export default defineComponent({
<style lang="less" scoped> <style lang="less" scoped>
.com-dialog__content { .com-dialog__content {
height: 600px; @{deep}(.el-scrollbar__wrap ) {
max-height: 600px; //
overflow-x: hidden; //
}
} }
</style> </style>

View File

@ -39,6 +39,9 @@ export function useExample() {
// 弹窗标题 // 弹窗标题
const title = ref<string>('') const title = ref<string>('')
// 组件名称
const comName = ref<string>('')
// 表格展示条目改变时候重置基本参数 // 表格展示条目改变时候重置基本参数
function sizeChange(val: number) { function sizeChange(val: number) {
loading.value = true loading.value = true
@ -72,6 +75,11 @@ export function useExample() {
selectionData.value = selection selectionData.value = selection
} }
// 改变弹窗dialogVisible
function toggleVisible(val = false) {
dialogVisible.value = val
}
return { return {
defalutParams, defalutParams,
tableData, tableData,
@ -80,9 +88,11 @@ export function useExample() {
total, total,
dialogVisible, dialogVisible,
title, title,
comName,
sizeChange, sizeChange,
currentChange, currentChange,
delData, delData,
handleSelectionChange handleSelectionChange,
toggleVisible
} }
} }

View File

@ -557,6 +557,19 @@ export const asyncRouterMap: AppRouteRecordRaw[] = [
showMainRoute: true, showMainRoute: true,
activeMenu: '/example-demo/example-page' activeMenu: '/example-demo/example-page'
} }
},
{
path: 'example-detail',
component: () => import('_p/index/views/example-demo/example-page/example-detail.vue'),
name: 'ExampleDetail',
meta: {
title: '列表综合实例-详情',
noTagsView: true,
noCache: true,
hidden: true,
showMainRoute: true,
activeMenu: '/example-demo/example-page'
}
} }
] ]
} }

View File

@ -13,7 +13,7 @@ export const delsExampApi = ({ data }: PropsData): any => {
return fetch({ url: '/example/delete', method: 'post', data }) return fetch({ url: '/example/delete', method: 'post', data })
} }
export const saveExampApi = ({ data }: PropsData): any => { export const setExampApi = ({ data }: PropsData): any => {
return fetch({ url: '/example/save', method: 'post', data }) return fetch({ url: '/example/save', method: 'post', data })
} }

View File

@ -0,0 +1,115 @@
<template>
<div>
<com-detail
:data="form"
:schema="fromSchema"
:collapsed="false"
title="文章详情"
>
<template #content="scope">
<div v-html="scope.row.content" />
</template>
</com-detail>
<div class="dialong__button--wrap">
<el-button @click="close">取消</el-button>
</div>
</div>
</template>
<script lang="ts">
import { defineComponent, reactive, PropType } from 'vue'
import { InfoWriteParams } from './types'
import { getExampDetApi } from '../api'
const fromSchema: any[] = [
{
field: 'title',
label: '标题',
span: 24
},
{
field: 'author',
label: '作者'
},
{
field: 'display_time',
label: '创建时间'
},
{
field: 'importance',
label: '重要性'
},
{
field: 'pageviews',
label: '阅读数'
},
{
field: 'content',
label: '内容',
span: 24,
slots: {
default: 'content'
}
}
]
export default defineComponent({
name: 'Detail',
props: {
info: {
type: Object as PropType<any>,
default: () => null
}
},
emits: ['close'],
setup(props, { emit }) {
const form = reactive<InfoWriteParams>({
id: '', // id
author: '', //
title: '', //
content: '', //
importance: '', //
display_time: '', //
pageviews: 0 //
})
async function getDet() {
if (props.info) {
const id = (props.info as any).id
try {
const res = await getExampDetApi({
params: {
id: id
}
})
if (res.code === '0000') {
for (const key in form) {
if (key === 'importance') {
form[key] = res.data[key].toString()
} else {
form[key] = res.data[key]
}
}
}
} catch (e) {
console.log(e)
}
}
}
getDet()
function close() {
emit('close')
}
return {
form,
fromSchema,
close
}
}
})
</script>
<style>
</style>

View File

@ -66,7 +66,7 @@ import Editor from '_c/Editor/index.vue'
import { Message } from '_c/Message' import { Message } from '_c/Message'
import { formatTime } from '@/utils' import { formatTime } from '@/utils'
import { InfoWriteParams, InfoWriteRules } from './types' import { InfoWriteParams, InfoWriteRules } from './types'
import { saveExampApi, getExampDetApi } from '../api' import { setExampApi, getExampDetApi } from '../api'
const requiredRule = { const requiredRule = {
required: true, required: true,
@ -145,7 +145,7 @@ export default defineComponent({
if (valid) { if (valid) {
const formData = unref(form) const formData = unref(form)
formData.display_time = formatTime(formData.display_time, 'yyyy-MM-dd HH:mm:ss') formData.display_time = formatTime(formData.display_time, 'yyyy-MM-dd HH:mm:ss')
const res = await saveExampApi({ const res = await setExampApi({
data: formData data: formData
}) })
if (res.code === '0000') { if (res.code === '0000') {

View File

@ -9,7 +9,7 @@
</div> </div>
<div class="button__example--wrap"> <div class="button__example--wrap">
<el-button type="primary" icon="el-icon-circle-plus-outline" @click="open(false)">新增</el-button> <el-button type="primary" icon="el-icon-circle-plus-outline" @click="open(false, 'InfoWrite')">新增</el-button>
<el-button <el-button
type="danger" type="danger"
icon="el-icon-delete" icon="el-icon-delete"
@ -45,20 +45,32 @@
</el-tag> </el-tag>
</template> </template>
<template #action="scope"> <template #action="scope">
<el-button type="primary" size="mini" @click="open(scope.row)">编辑</el-button> <el-button type="primary" size="mini" @click="open(scope.row, 'InfoWrite')">编辑</el-button>
<el-button type="success" size="mini" @click="open(scope.row, 'Detail')">查看</el-button>
<el-button type="danger" size="mini" @click="dels(scope.row)">删除</el-button> <el-button type="danger" size="mini" @click="dels(scope.row)">删除</el-button>
</template> </template>
</com-table> </com-table>
<com-dialog v-model="dialogVisible" :title="title"> <com-dialog v-model="dialogVisible" :title="title">
<ifno-write :info="info" @close="close" @success="success" /> <info-write
v-if="comName === 'InfoWrite'"
:info="info"
@close="toggleVisible"
@success="success"
/>
<detail
v-if="comName === 'Detail'"
:info="info"
@close="toggleVisible"
/>
</com-dialog> </com-dialog>
</div> </div>
</template> </template>
<script lang="ts"> <script lang="ts">
import { defineComponent, ref } from 'vue' import { defineComponent, ref } from 'vue'
import IfnoWrite from './components/IfnoWrite.vue' import InfoWrite from './components/InfoWrite.vue'
import Detail from './components/Detail.vue'
import { useExample } from '@/hooks/useExample' import { useExample } from '@/hooks/useExample'
import { Message } from '_c/Message' import { Message } from '_c/Message'
@ -104,7 +116,7 @@ const columns = [
{ {
field: 'action', field: 'action',
label: '操作', label: '操作',
width: '150px', width: '220px',
slots: { slots: {
default: 'action' default: 'action'
} }
@ -114,7 +126,8 @@ const columns = [
export default defineComponent({ export default defineComponent({
// name: 'ExampleDialog', // name: 'ExampleDialog',
components: { components: {
IfnoWrite InfoWrite,
Detail
}, },
setup() { setup() {
const info = ref<any>(null) const info = ref<any>(null)
@ -130,7 +143,9 @@ export default defineComponent({
sizeChange, sizeChange,
handleSelectionChange, handleSelectionChange,
selectionData, selectionData,
delData delData,
comName,
toggleVisible
} = useExample() } = useExample()
// //
@ -198,15 +213,11 @@ export default defineComponent({
} }
// //
function open(row: any) { function open(row: any, component: string) {
title.value = row ? '编辑' : '新增' comName.value = component
title.value = !row ? '新增' : (component === 'Detail' ? '详情' : '编辑')
info.value = row || null info.value = row || null
dialogVisible.value = true toggleVisible(true)
}
//
function close() {
dialogVisible.value = false
} }
// //
@ -234,7 +245,9 @@ export default defineComponent({
handleCurrentChange, handleCurrentChange,
handleSelectionChange, handleSelectionChange,
dels, dels,
close, success close, success,
comName,
toggleVisible
} }
} }
}) })

View File

@ -13,7 +13,7 @@ export const delsExampApi = ({ data }: PropsData): any => {
return fetch({ url: '/example/delete', method: 'post', data }) return fetch({ url: '/example/delete', method: 'post', data })
} }
export const saveExampApi = ({ data }: PropsData): any => { export const setExampApi = ({ data }: PropsData): any => {
return fetch({ url: '/example/save', method: 'post', data }) return fetch({ url: '/example/save', method: 'post', data })
} }

View File

@ -0,0 +1,117 @@
<template>
<div>
<com-detail
:data="form"
:schema="fromSchema"
:collapsed="false"
title="文章详情"
>
<template #content="scope">
<div v-html="scope.row.content" />
</template>
</com-detail>
<div class="dialong__button--wrap">
<el-button @click="close">取消</el-button>
</div>
</div>
</template>
<script lang="ts">
import { defineComponent, reactive, PropType } from 'vue'
import { useRouter } from 'vue-router'
import { InfoWriteParams } from './types'
import { getExampDetApi } from '../api'
const fromSchema: any[] = [
{
field: 'title',
label: '标题',
span: 24
},
{
field: 'author',
label: '作者'
},
{
field: 'display_time',
label: '创建时间'
},
{
field: 'importance',
label: '重要性'
},
{
field: 'pageviews',
label: '阅读数'
},
{
field: 'content',
label: '内容',
span: 24,
slots: {
default: 'content'
}
}
]
export default defineComponent({
name: 'Detail',
props: {
id: {
type: String as PropType<string>,
default: ''
}
},
setup(props) {
const { push } = useRouter()
const form = reactive<InfoWriteParams>({
id: '', // id
author: '', //
title: '', //
content: '', //
importance: '', //
display_time: '', //
pageviews: 0 //
})
async function getDet() {
if (props.id) {
const id = props.id
try {
const res = await getExampDetApi({
params: {
id: id
}
})
if (res.code === '0000') {
for (const key in form) {
if (key === 'importance') {
form[key] = res.data[key].toString()
} else {
form[key] = res.data[key]
}
}
}
} catch (e) {
console.log(e)
}
}
}
getDet()
function close() {
push('/example-demo/example-page')
}
return {
form,
fromSchema,
close
}
}
})
</script>
<style>
</style>

View File

@ -67,7 +67,7 @@ import Editor from '_c/Editor/index.vue'
import { Message } from '_c/Message' import { Message } from '_c/Message'
import { formatTime } from '@/utils' import { formatTime } from '@/utils'
import { InfoWriteParams, InfoWriteRules } from './types' import { InfoWriteParams, InfoWriteRules } from './types'
import { saveExampApi, getExampDetApi } from '../api' import { setExampApi, getExampDetApi } from '../api'
const requiredRule = { const requiredRule = {
required: true, required: true,
@ -148,7 +148,7 @@ export default defineComponent({
if (valid) { if (valid) {
const formData = unref(form) const formData = unref(form)
formData.display_time = formatTime(formData.display_time, 'yyyy-MM-dd HH:mm:ss') formData.display_time = formatTime(formData.display_time, 'yyyy-MM-dd HH:mm:ss')
const res = await saveExampApi({ const res = await setExampApi({
data: formData data: formData
}) })
if (res.code === '0000') { if (res.code === '0000') {

View File

@ -1,16 +1,16 @@
<template> <template>
<ifno-write @success="success" /> <info-write @success="success" />
</template> </template>
<script lang="ts"> <script lang="ts">
import { defineComponent } from 'vue' import { defineComponent } from 'vue'
import IfnoWrite from './components/IfnoWrite.vue' import InfoWrite from './components/InfoWrite.vue'
import vueBus from '@/vue-bus' import vueBus from '@/vue-bus'
export default defineComponent({ export default defineComponent({
// name: 'ExampleAdd', // name: 'ExampleAdd',
components: { components: {
IfnoWrite InfoWrite
}, },
setup() { setup() {
// //

View File

@ -0,0 +1,26 @@
<template>
<detail :id="id" />
</template>
<script lang="ts">
import { defineComponent } from 'vue'
import Detail from './components/Detail.vue'
import { useRoute } from 'vue-router'
export default defineComponent({
// name: 'ExampleDetail',
components: {
Detail
},
setup() {
const { query } = useRoute()
return {
id: query.id
}
}
})
</script>
<style>
</style>

View File

@ -1,17 +1,17 @@
<template> <template>
<ifno-write :id="id" @success="success" /> <info-write :id="id" @success="success" />
</template> </template>
<script lang="ts"> <script lang="ts">
import { defineComponent } from 'vue' import { defineComponent } from 'vue'
import IfnoWrite from './components/IfnoWrite.vue' import InfoWrite from './components/InfoWrite.vue'
import vueBus from '@/vue-bus' import vueBus from '@/vue-bus'
import { useRoute } from 'vue-router' import { useRoute } from 'vue-router'
export default defineComponent({ export default defineComponent({
// name: 'ExampleEdit', // name: 'ExampleEdit',
components: { components: {
IfnoWrite InfoWrite
}, },
setup() { setup() {
const { query } = useRoute() const { query } = useRoute()

View File

@ -46,6 +46,7 @@
</template> </template>
<template #action="scope"> <template #action="scope">
<el-button type="primary" size="mini" @click="open(scope.row)">编辑</el-button> <el-button type="primary" size="mini" @click="open(scope.row)">编辑</el-button>
<el-button type="success" size="mini" @click="open(scope.row, 'Detail')">查看</el-button>
<el-button type="danger" size="mini" @click="dels(scope.row)">删除</el-button> <el-button type="danger" size="mini" @click="dels(scope.row)">删除</el-button>
</template> </template>
</com-table> </com-table>
@ -100,7 +101,7 @@ const columns = [
{ {
field: 'action', field: 'action',
label: '操作', label: '操作',
width: '150px', width: '220px',
slots: { slots: {
default: 'action' default: 'action'
} }
@ -189,8 +190,12 @@ export default defineComponent({
} }
// //
function open(row: any) { function open(row: any, component?: string) {
push(row ? `/example-demo/example-edit?id=${row.id}` : `/example-demo/example-add`) push(!row
? `/example-demo/example-add`
: (component
? `/example-demo/example-detail?id=${row.id}`
: `/example-demo/example-edit?id=${row.id}`))
} }
getExampleList() getExampleList()

View File

@ -28,5 +28,6 @@
} }
.dialong__button--wrap { .dialong__button--wrap {
text-align: center; text-align: center;
margin-top: 20px;
} }
// 综合实例样式 // 综合实例样式