Browse Source

refactor: 移除 watch, 改善代码逻辑

main
刘凯 1 year ago
parent
commit
9fedc0caea
  1. 4
      src/views/device-manage/device/components/DeviceInfo.vue
  2. 2
      src/views/device-manage/device/detail.vue
  3. 24
      src/views/device-manage/group/components/GroupList.vue
  4. 5
      src/views/device-manage/group/index.vue
  5. 6
      src/views/product/components/Model.vue
  6. 8
      src/views/product/components/TopicManage.vue
  7. 16
      src/views/product/components/composables/useModelAttribute.ts
  8. 21
      src/views/product/components/composables/useModelService.ts

4
src/views/device-manage/device/components/DeviceInfo.vue

@ -10,7 +10,7 @@ import { usePermission } from '@/hooks/web/usePermission'
import { ProductTabEnums } from '@/views/product/data'
import type { Device } from '@/api/device-manage/device/types'
const props = defineProps<{ data?: Device }>()
const props = defineProps<{ data: Device }>()
const { scheam } = useDeviceInfo(toRef(props, 'data'))
@ -18,7 +18,7 @@ const {
modelServiceList,
selectedModelId,
setSelectedModelId,
} = useModelService(() => props.data?.productId)
} = useModelService(props.data.productId)
const {
isLoading,

2
src/views/device-manage/device/detail.vue

@ -19,7 +19,7 @@ const { hasPermission } = usePermission()
<Card title="设备详情">
<Tabs>
<Tabs.TabPane key="1" tab="设备信息">
<DeviceInfo :data="data" />
<DeviceInfo v-if="data" :data="data" />
</Tabs.TabPane>
<Tabs.TabPane v-if="hasPermission('device_topic_view')" key="2" tab="已订阅 Topic">
<TopicList />

24
src/views/device-manage/group/components/GroupList.vue

@ -1,8 +1,9 @@
<script lang="ts" setup>
import { ref, watch } from 'vue'
import { ref } from 'vue'
import { PlusOutlined, SyncOutlined } from '@ant-design/icons-vue'
import { useAsyncState } from '@vueuse/core'
import { Empty, Popconfirm, Space, Tree } from 'ant-design-vue'
import type { EventDataNode } from 'ant-design-vue/es/tree'
import GroupFormModal from './GroupFormModal.vue'
import { useModal } from '@/components/Modal'
import { deleteDevicegroup, getDeviceGroupTree } from '@/api/device-manage/group'
@ -10,7 +11,7 @@ import { useMessage } from '@/hooks/web/useMessage'
import { usePermission } from '@/hooks/web/usePermission'
defineProps<{ selectedGroupId: string | undefined }>()
const emit = defineEmits(['update:selectedGroupId'])
const emit = defineEmits(['update:selectedGroupId', 'change'])
const [registerModal, { openModal }] = useModal<{ id: string } | { parentId: string }>()
@ -26,16 +27,15 @@ async function handleDelete(id: string) {
}
const selectedKeys = ref<string[]>([])
watch(selectedKeys, (keys, oldKeys) => {
const value = keys[0]
if (!value) {
// can't unselect
selectedKeys.value = oldKeys
return
}
emit('update:selectedGroupId', value)
})
function onSelectNode(_, { selected, node }: { selected: boolean, node: EventDataNode }) {
// can't unselect
if (!selected)
return selectedKeys.value = [node.key as string]
emit('update:selectedGroupId', node.key)
emit('change')
}
const { hasPermission } = usePermission()
</script>
@ -57,7 +57,7 @@ const { hasPermission } = usePermission()
</div>
<div mt="20px">
<Tree v-model:selected-keys="selectedKeys" :tree-data="state" :field-names="{ key: 'id' }">
<Tree v-model:selected-keys="selectedKeys" :tree-data="state" :field-names="{ key: 'id' }" @select="onSelectNode">
<template #title="{ title, data }">
<div flex="~ items-center justify-between" py="8px" px="5px" box-border>
<div flex="1" width="0" truncate :title="title">

5
src/views/device-manage/group/index.vue

@ -1,5 +1,5 @@
<script lang="ts" setup>
import { ref, watch } from 'vue'
import { ref } from 'vue'
import { Space } from 'ant-design-vue'
import { DisconnectOutlined, LinkOutlined } from '@ant-design/icons-vue'
import { BindingDeviceDrawer, GroupList } from './components'
@ -44,7 +44,6 @@ const [register, { getSelectRowKeys, reload }] = useTable({
const [registerBindingDeviceDrawer, { openDrawer }] = useDrawer()
const selectedGroupId = ref<string | undefined>()
watch(selectedGroupId, reload)
const message = useMessage()
function handleBindingDivice() {
@ -81,7 +80,7 @@ function handleUnbindingDivice(id?: string) {
<template>
<div flex="~">
<GroupList v-model:selectedGroupId="selectedGroupId" my="12px" ml="12px" />
<GroupList v-model:selectedGroupId="selectedGroupId" my="12px" ml="12px" @change="reload" />
<BasicTable flex="1" @register="register">
<template v-if="hasPermission(['device_group_binding', 'device_group_unbinding'])" #tableTitle>
<Space>

6
src/views/product/components/Model.vue

@ -62,7 +62,7 @@ const { hasPermission } = usePermission()
class="box-border h-60px cursor-pointer pl-10px hover:bg-gray-100 hover:dark:bg-white hover:dark:bg-opacity-5"
border="0 b-1 solid gray-50 dark:white dark:opacity-5"
:class="selectedModelId === item.id ? 'bg-gray-100 dark:bg-white dark:bg-opacity-5' : ''"
@click="setSelectedModelId(item.id)"
@click="setSelectedModelId(item.id); reloadModalAttribute(true)"
>
<div w-0 flex-1>
<div truncate>
@ -95,7 +95,7 @@ const { hasPermission } = usePermission()
</template>
<template #toolbar>
<a-button size="small" @click="reloadModalAttribute">
<a-button size="small" @click="reloadModalAttribute()">
<template #icon>
<SyncOutlined />
</template>
@ -133,6 +133,6 @@ const { hasPermission } = usePermission()
</div>
<ModelServiceFormModal @register="registerModelServiceModal" @success="reloadModelService" />
<ModelAttributeFormModal :model-id="selectedModelId || ''" @register="registerModelAttributeModal" @success="reloadModalAttribute" />
<ModelAttributeFormModal :model-id="selectedModelId || ''" @register="registerModelAttributeModal" @success="reloadModalAttribute()" />
</div>
</template>

8
src/views/product/components/TopicManage.vue

@ -1,6 +1,6 @@
<script setup lang="ts">
import { Alert, Segmented } from 'ant-design-vue'
import { computed, ref, watch } from 'vue'
import { computed, ref } from 'vue'
import { useRoute } from 'vue-router'
import { PlusOutlined, SyncOutlined } from '@ant-design/icons-vue'
import TopicFormModal from './TopicFormModal.vue'
@ -68,10 +68,11 @@ const [register, { reload, setTableData }] = useTable({
auth: ['product_topic_edit', 'product_topic_delete'],
},
})
watch(topicType, () => {
function onChangeTopicType() {
setTableData([])
reload()
})
}
async function handleDelete(id: string) {
try {
@ -90,6 +91,7 @@ async function handleDelete(id: string) {
<Segmented
v-model:value="topicType"
:options="[{ label: '系统 Topic', value: TopicType.System }, { label: '自定义 Topic', value: TopicType.Custom }]"
@change="onChangeTopicType"
/>
<a-button v-if="isCustomTopic && hasPermission('product_topic_add')" type="primary" @click="openModal">

16
src/views/product/components/composables/useModelAttribute.ts

@ -1,4 +1,4 @@
import { unref, watch } from 'vue'
import { unref } from 'vue'
import type { MaybeRef, Ref } from 'vue'
import { useTable } from '@/components/Table'
import { deleteModelAttribute, getModelAttributeList } from '@/api/product/model'
@ -48,10 +48,6 @@ export function useModelAttribute(productId: MaybeRef<string>, modelId: Ref<stri
auth: ['product_model_attr_delete', 'product_model_attr_edit'],
},
})
watch(modelId, () => {
setPagination({ current: 1 })
reload()
})
const [registerModelAttributeModal, { openModal: openModelAttributeModal }] = useModal<ModelAttribute>()
@ -68,7 +64,15 @@ export function useModelAttribute(productId: MaybeRef<string>, modelId: Ref<stri
registerModelAttributeTable,
registerModelAttributeModal,
openModelAttributeModal,
reloadModalAttribute: reload,
/**
* @param resetPageCurrent
*/
reloadModalAttribute(resetPageCurrent = false) {
if (resetPageCurrent)
setPagination({ current: 1 })
reload()
},
handleDeleteModelAttribute,
}
}

21
src/views/product/components/composables/useModelService.ts

@ -1,25 +1,18 @@
import { toValue, useAsyncState, watchOnce } from '@vueuse/core'
import type { MaybeRefOrGetter } from 'vue'
import { ref, watch } from 'vue'
import { ref } from 'vue'
import { useAsyncState, watchOnce } from '@vueuse/core'
import { deleteModelService, getAllModelServices } from '@/api/product/model'
import { useMessage } from '@/hooks/web/useMessage'
import { useModal } from '@/components/Modal'
import type { ModelService } from '@/api/product/types'
export function useModelService(productId: MaybeRefOrGetter<string | undefined>, defaultModelId?: string) {
export function useModelService(productId: string, defaultModelId?: string) {
const selectedModelId = ref<string>()
const { state, execute } = useAsyncState(
() => getAllModelServices(toValue(productId) as string),
[],
{
resetOnExecute: false,
immediate: toValue(productId) !== undefined,
},
)
watch(() => toValue(productId), () => execute())
const { state, execute } = useAsyncState(() => getAllModelServices(productId), [], {
resetOnExecute: false,
})
// 默认选择的 ModelId, 如果没有 defaultModelId 则是第一个元素的 Id
watchOnce(state, () => {
if (state.value.length > 0)
selectedModelId.value = defaultModelId || state.value[0].id

Loading…
Cancel
Save