فهرست منبع

【功能完善】IoT: 场景联动执行器配置

puhui999 1 سال پیش
والد
کامیت
c06f7f9ebd

+ 37 - 26
src/views/iot/rule/scene/components/action/ActionExecutor.vue

@@ -22,7 +22,7 @@
         class="flex items-center mr-60px"
       >
         <span class="mr-10px">产品</span>
-        <el-button type="primary" @click="productTableSelectRef?.open()" size="small" plain>
+        <el-button type="primary" @click="handleSelectProduct" size="small" plain>
           {{ product ? product.name : '选择产品' }}
         </el-button>
       </div>
@@ -31,8 +31,8 @@
         class="flex items-center mr-60px"
       >
         <span class="mr-10px">设备</span>
-        <el-button type="primary" @click="openDeviceSelect" size="small" plain>
-          {{ isEmpty(deviceList) ? '选择设备' : actionConfig.deviceControl?.deviceNames.join(',') }}
+        <el-button type="primary" @click="handleSelectDevice" size="small" plain>
+          {{ isEmpty(deviceList) ? '选择设备' : deviceList.map(d => d.deviceName).join(',') }}
         </el-button>
       </div>
       <!-- 删除执行器 -->
@@ -47,6 +47,7 @@
     <DeviceControlAction
       v-if="actionConfig.type === IotRuleSceneActionTypeEnum.DEVICE_CONTROL"
       :model-value="actionConfig.deviceControl"
+      :product-id="product?.id"
       @update:model-value="(val) => (actionConfig.deviceControl = val)"
     />
 
@@ -86,12 +87,13 @@ import AlertAction from './AlertAction.vue'
 import DataBridgeAction from './DataBridgeAction.vue'
 import { ProductVO } from '@/api/iot/product/product'
 import { DeviceVO } from '@/api/iot/device/device'
-import { ThingModelApi } from '@/api/iot/thingmodel'
 import {
   ActionAlert,
   ActionConfig,
   ActionDeviceControl,
-  IotRuleSceneActionTypeEnum
+  IotRuleSceneActionTypeEnum,
+  IotDeviceMessageTypeEnum,
+  IotDeviceMessageIdentifierEnum
 } from '@/api/iot/rule/scene/scene.types'
 
 /** 场景联动之执行器组件 */
@@ -114,7 +116,13 @@ const initActionConfig = () => {
     actionConfig.value.type === IotRuleSceneActionTypeEnum.DEVICE_CONTROL &&
     !actionConfig.value.deviceControl
   ) {
-    actionConfig.value.deviceControl = {} as ActionDeviceControl
+    actionConfig.value.deviceControl = {
+      productKey: '',
+      deviceNames: [],
+      type: IotDeviceMessageTypeEnum.PROPERTY,
+      identifier: IotDeviceMessageIdentifierEnum.PROPERTY_SET,
+      data: {}
+    } as ActionDeviceControl
   }
 
   // 告警执行器初始化
@@ -146,22 +154,13 @@ const deviceTableSelectRef = ref<InstanceType<typeof DeviceTableSelect>>()
 const product = ref<ProductVO>()
 const deviceList = ref<DeviceVO[]>([])
 
-/** 处理产品选择 */
-const handleProductSelect = (val: ProductVO) => {
-  product.value = val
-  actionConfig.value.deviceControl!.productKey = val.productKey
-  deviceList.value = []
-  getThingModelTSL()
+/** 处理选择产品 */
+const handleSelectProduct = () => {
+  productTableSelectRef.value?.open()
 }
 
-/** 处理设备选择 */
-const handleDeviceSelect = (val: DeviceVO[]) => {
-  deviceList.value = val
-  actionConfig.value.deviceControl!.deviceNames = val.map((item) => item.deviceName)
-}
-
-/** 打开设备选择器 */
-const openDeviceSelect = () => {
+/** 处理选择设备 */
+const handleSelectDevice = () => {
   if (!product.value) {
     message.warning('请先选择一个产品')
     return
@@ -169,12 +168,24 @@ const openDeviceSelect = () => {
   deviceTableSelectRef.value?.open()
 }
 
-/** 获取产品物模型 */
-const thingModelTSL = ref<any>()
-const getThingModelTSL = async () => {
-  if (!product.value) {
-    return
+/** 处理产品选择成功 */
+const handleProductSelect = (val: ProductVO) => {
+  product.value = val
+  if (actionConfig.value.deviceControl) {
+    actionConfig.value.deviceControl.productKey = val.productKey
+  }
+  // 重置设备选择
+  deviceList.value = []
+  if (actionConfig.value.deviceControl) {
+    actionConfig.value.deviceControl.deviceNames = []
+  }
+}
+
+/** 处理设备选择成功 */
+const handleDeviceSelect = (val: DeviceVO[]) => {
+  deviceList.value = val
+  if (actionConfig.value.deviceControl) {
+    actionConfig.value.deviceControl.deviceNames = val.map((item) => item.deviceName)
   }
-  thingModelTSL.value = await ThingModelApi.getThingModelTSLByProductId(product.value.id)
 }
 </script>

+ 0 - 95
src/views/iot/rule/scene/components/action/DeviceActionControl.vue

@@ -1,95 +0,0 @@
-<template>
-  <div class="device-action-control">
-    <!-- 属性设置 -->
-    <template v-if="messageType === IotDeviceMessageTypeEnum.PROPERTY">
-      <div class="flex flex-wrap gap-10px">
-        <div v-for="model in thingModels" :key="model.identifier" class="flex items-center mb-10px">
-          <span class="mr-10px inline-block min-w-80px">{{ model.name }}</span>
-          <!-- 根据属性类型渲染不同的输入控件 -->
-          <PropertyValueInput
-            :model-value="propertyData[model.identifier]"
-            :data-specs="model.dataSpecs"
-            @update:model-value="(val) => updatePropertyValue(model.identifier, val)"
-          />
-        </div>
-      </div>
-    </template>
-
-    <!-- 服务调用 -->
-    <template v-else-if="messageType === IotDeviceMessageTypeEnum.SERVICE">
-      <div class="flex flex-wrap gap-10px">
-        <template v-if="thingModels && thingModels.inputParams">
-          <div 
-            v-for="param in thingModels.inputParams" 
-            :key="param.identifier" 
-            class="flex items-center mb-10px"
-          >
-            <span class="mr-10px inline-block min-w-80px">{{ param.name }}</span>
-            <!-- 根据服务输入参数类型渲染不同的输入控件 -->
-            <PropertyValueInput
-              :model-value="serviceData[param.identifier]"
-              :data-specs="param.dataSpecs"
-              @update:model-value="(val) => updateServiceValue(param.identifier, val)"
-            />
-          </div>
-        </template>
-        <div v-else class="text-gray-500">该服务没有输入参数</div>
-      </div>
-    </template>
-  </div>
-</template>
-
-<script setup lang="ts">
-import { useVModel } from '@vueuse/core'
-import PropertyValueInput from './PropertyValueInput.vue'
-import { IotDeviceMessageTypeEnum } from '@/api/iot/rule/scene/scene.types'
-
-/** 设备控制执行器的参数配置组件 */
-defineOptions({ name: 'DeviceActionControl' })
-
-const props = defineProps<{
-  modelValue: any
-  thingModels: any
-  messageType: string
-  identifier: string
-}>()
-
-const emits = defineEmits(['update:modelValue'])
-const actionData = useVModel(props, 'modelValue', emits)
-
-// 属性数据
-const propertyData = computed({
-  get: () => {
-    return actionData.value || {}
-  },
-  set: (value) => {
-    actionData.value = value
-  }
-})
-
-// 服务数据
-const serviceData = computed({
-  get: () => {
-    return actionData.value || {}
-  },
-  set: (value) => {
-    actionData.value = value
-  }
-})
-
-// 更新属性值
-const updatePropertyValue = (identifier: string, value: any) => {
-  const newData = { ...propertyData.value }
-  newData[identifier] = value
-  propertyData.value = newData
-}
-
-// 更新服务参数值
-const updateServiceValue = (identifier: string, value: any) => {
-  const newData = { ...serviceData.value }
-  newData[identifier] = value
-  serviceData.value = newData
-}
-</script>
-
-<style scoped lang="scss"></style> 

+ 124 - 95
src/views/iot/rule/scene/components/action/DeviceControlAction.vue

@@ -1,78 +1,61 @@
 <template>
-  <div class="bg-[#dbe5f6] p-10px">
-    <div class="flex items-center mb-10px">
-      <span class="mr-10px w-60px">产品</span>
-      <el-button type="primary" @click="productTableSelectRef?.open()" size="small" plain>
-        {{ product ? product.name : '选择产品' }}
-      </el-button>
-    </div>
-    <div class="flex items-center mb-10px">
-      <span class="mr-10px w-60px">设备</span>
-      <el-button type="primary" @click="openDeviceSelect" size="small" plain>
-        {{ isEmpty(deviceList) ? '选择设备' : deviceControlConfig.deviceNames.join(',') }}
-      </el-button>
-    </div>
-    <div class="flex items-center mb-10px">
-      <span class="mr-10px w-60px">消息类型</span>
+  <div class="bg-[#dbe5f6] flex p-10px">
+    <div class="flex flex-col items-center justify-center mr-10px h-a">
       <el-select
         v-model="deviceControlConfig.type"
+        @change="deviceControlConfig.data = {}"
         class="!w-160px"
         clearable
-        placeholder="选择消息类型"
+        placeholder=""
       >
         <el-option label="属性" :value="IotDeviceMessageTypeEnum.PROPERTY" />
         <el-option label="服务" :value="IotDeviceMessageTypeEnum.SERVICE" />
       </el-select>
     </div>
-    <div v-if="deviceControlConfig.type" class="flex items-center mb-10px">
-      <span class="mr-10px w-60px">具体操作</span>
-      <el-select
-        v-model="deviceControlConfig.identifier"
-        class="!w-240px"
-        clearable
-        placeholder="选择操作项"
+    <div class="">
+      <div
+        class="flex items-center justify-around mb-10px last:mb-0"
+        v-for="(parameter, index) in parameters"
+        :key="index"
       >
-        <template v-if="deviceControlConfig.type === IotDeviceMessageTypeEnum.PROPERTY">
-          <el-option :value="IotDeviceMessageIdentifierEnum.PROPERTY_SET" label="属性设置" />
-        </template>
-        <template v-else-if="deviceControlConfig.type === IotDeviceMessageTypeEnum.SERVICE">
+        <el-select
+          v-model="parameter.identifier"
+          class="!w-240px mr-10px"
+          clearable
+          placeholder="请选择物模型"
+        >
           <el-option
-            v-for="model in thingModelTSL?.services"
-            :key="model.identifier"
-            :label="model.name"
-            :value="model.identifier"
+            v-for="thingModel in thingModels"
+            :key="thingModel.identifier"
+            :label="thingModel.name"
+            :value="thingModel.identifier"
           />
-        </template>
-      </el-select>
+        </el-select>
+        <el-input v-model="parameter.value" class="!w-240px mr-10px" placeholder="请输入值">
+          <template v-if="getUnitName(parameter.identifier)" #append>
+            {{ getUnitName(parameter.identifier) }}
+          </template>
+        </el-input>
+        <el-tooltip content="删除参数" placement="top">
+          <el-button type="danger" circle size="small" @click="removeParameter(index)">
+            <Icon icon="ep:delete" />
+          </el-button>
+        </el-tooltip>
+      </div>
+    </div>
+    <!-- 添加参数 -->
+    <div class="flex flex-1 flex-col items-center justify-center w-60px h-a">
+      <el-tooltip content="添加参数" placement="top">
+        <el-button type="primary" circle size="small" @click="addParameter">
+          <Icon icon="ep:plus" />
+        </el-button>
+      </el-tooltip>
     </div>
-    <DeviceActionControl
-      v-if="deviceControlConfig.identifier && deviceControlConfig.type"
-      :model-value="deviceControlConfig.data"
-      :thing-models="getThingModels()"
-      :message-type="deviceControlConfig.type"
-      :identifier="deviceControlConfig.identifier"
-      @update:model-value="(val) => (deviceControlConfig.data = val)"
-    />
   </div>
-
-  <!-- 产品、设备的选择 -->
-  <ProductTableSelect ref="productTableSelectRef" @success="handleProductSelect" />
-  <DeviceTableSelect
-    ref="deviceTableSelectRef"
-    multiple
-    :product-id="product?.id"
-    @success="handleDeviceSelect"
-  />
 </template>
 
 <script setup lang="ts">
 import { useVModel } from '@vueuse/core'
-import { isEmpty } from '@/utils/is'
-import ProductTableSelect from '@/views/iot/product/product/components/ProductTableSelect.vue'
-import DeviceTableSelect from '@/views/iot/device/device/components/DeviceTableSelect.vue'
-import DeviceActionControl from './DeviceActionControl.vue'
-import { ProductVO } from '@/api/iot/product/product'
-import { DeviceVO } from '@/api/iot/device/device'
 import { ThingModelApi } from '@/api/iot/thingmodel'
 import {
   ActionDeviceControl,
@@ -83,12 +66,27 @@ import {
 /** 设备控制执行器组件 */
 defineOptions({ name: 'DeviceControlAction' })
 
-const props = defineProps<{ modelValue: any }>()
+const props = defineProps<{
+  modelValue: any
+  productId?: number
+}>()
 const emits = defineEmits(['update:modelValue'])
 const deviceControlConfig = useVModel(props, 'modelValue', emits) as Ref<ActionDeviceControl>
 
 const message = useMessage()
 
+/** 执行器参数 */
+const parameters = ref<{ identifier: string; value: any }[]>([])
+const addParameter = () => {
+  if (parameters.value.length >= thingModels.value.length) {
+    message.warning(`该产品只有${thingModels.value.length}个物模型!!!`)
+    return
+  }
+  parameters.value.push({ identifier: '', value: undefined })
+}
+const removeParameter = (index: number) => {
+  parameters.value.splice(index, 1)
+}
 // 初始化设备控制执行器结构
 const initDeviceControlConfig = () => {
   if (!deviceControlConfig.value) {
@@ -100,63 +98,94 @@ const initDeviceControlConfig = () => {
       data: {}
     } as ActionDeviceControl
   }
+
+  // 确保data对象存在
+  if (!deviceControlConfig.value.data) {
+    deviceControlConfig.value.data = {}
+  }
 }
 
 // 初始化
 onMounted(() => {
   initDeviceControlConfig()
+  if (props.productId) {
+    getThingModelTSL()
+  }
 })
 
-// 产品和设备选择
-const productTableSelectRef = ref<InstanceType<typeof ProductTableSelect>>()
-const deviceTableSelectRef = ref<InstanceType<typeof DeviceTableSelect>>()
-const product = ref<ProductVO>()
-const deviceList = ref<DeviceVO[]>([])
-
-/** 处理产品选择 */
-const handleProductSelect = (val: ProductVO) => {
-  product.value = val
-  deviceControlConfig.value.productKey = val.productKey
-  deviceList.value = []
-  getThingModelTSL()
-}
+// 监听productId变化
+watch(
+  () => props.productId,
+  (newVal) => {
+    if (newVal) {
+      getThingModelTSL()
+      // 当产品ID变化时,清空原有数据
+      deviceControlConfig.value.data = {}
+    } else {
+      thingModelTSL.value = undefined
+    }
+  }
+)
 
-/** 处理设备选择 */
-const handleDeviceSelect = (val: DeviceVO[]) => {
-  deviceList.value = val
-  deviceControlConfig.value.deviceNames = val.map((item) => item.deviceName)
-}
+// 监听消息类型变化
+watch(
+  () => deviceControlConfig.value.type,
+  () => {
+    // 切换消息类型时清空参数
+    deviceControlConfig.value.data = {}
+    if (deviceControlConfig.value.type === IotDeviceMessageTypeEnum.PROPERTY) {
+      deviceControlConfig.value.identifier = IotDeviceMessageIdentifierEnum.PROPERTY_SET
+    } else {
+      deviceControlConfig.value.identifier = ''
+    }
+  }
+)
 
-/** 打开设备选择器 */
-const openDeviceSelect = () => {
-  if (!product.value) {
-    message.warning('请先选择一个产品')
-    return
+// 监听identifier变化
+watch(
+  () => deviceControlConfig.value.identifier,
+  () => {
+    // 切换identifier时清空参数
+    deviceControlConfig.value.data = {}
   }
-  deviceTableSelectRef.value?.open()
-}
+)
 
 /** 获取产品物模型 */
 const thingModelTSL = ref<any>()
 const getThingModelTSL = async () => {
-  if (!product.value) {
+  if (!props.productId) {
     return
   }
-  thingModelTSL.value = await ThingModelApi.getThingModelTSLByProductId(product.value.id)
+  try {
+    thingModelTSL.value = await ThingModelApi.getThingModelTSLByProductId(props.productId)
+  } catch (error) {
+    console.error('获取物模型失败', error)
+  }
 }
-
-/** 根据消息类型和标识符获取对应的物模型 */
-const getThingModels = () => {
-  if (!deviceControlConfig.value) return []
-  
+const thingModels = computed((): any[] => {
   switch (deviceControlConfig.value.type) {
     case IotDeviceMessageTypeEnum.PROPERTY:
-      return thingModelTSL.value?.properties || []
+      return thingModelTSL.value.properties
+    // TODO puhui999: 服务和事件后续考虑
     case IotDeviceMessageTypeEnum.SERVICE:
-      return thingModelTSL.value?.services.find(
-        (s: any) => s.identifier === deviceControlConfig.value.identifier
-      ) || {}
+      return thingModelTSL.value.services
+    case IotDeviceMessageTypeEnum.EVENT:
+      return thingModelTSL.value.events
   }
   return []
-}
-</script> 
+})
+/** 获得属性单位 */
+const getUnitName = computed(() => (identifier: string) => {
+  const model = thingModels.value?.find((item: any) => item.identifier === identifier)
+  // 属性
+  if (model?.dataSpecs) {
+    return model.dataSpecs.unitName
+  }
+  // TODO puhui999: 先不考虑服务和事件的情况
+  // 服务和事件
+  // if (model?.outputParams) {
+  //   return model.dataSpecs.unitName
+  // }
+  return ''
+})
+</script>

+ 0 - 238
src/views/iot/rule/scene/components/action/PropertyValueInput.vue

@@ -1,238 +0,0 @@
-<template>
-  <div class="property-value-input">
-    <!-- 文本类型 -->
-    <template v-if="dataType === 'text'">
-      <el-input
-        v-model="inputValue"
-        class="!w-240px"
-        :placeholder="`请输入${dataSpecs?.name || '值'}`"
-      >
-        <template v-if="dataSpecs?.unitName" #append>{{ dataSpecs.unitName }}</template>
-      </el-input>
-    </template>
-
-    <!-- 数值类型 -->
-    <template v-else-if="['int', 'float', 'double'].includes(dataType)">
-      <el-input-number
-        v-model="inputValue"
-        class="!w-240px"
-        :min="dataSpecs?.min"
-        :max="dataSpecs?.max"
-        :precision="dataType === 'int' ? 0 : 2"
-        :step="dataType === 'int' ? 1 : 0.1"
-        :placeholder="`请输入${dataSpecs?.name || '值'}`"
-      />
-      <span v-if="dataSpecs?.unitName" class="ml-5px">{{ dataSpecs.unitName }}</span>
-    </template>
-
-    <!-- 枚举类型 -->
-    <template v-else-if="dataType === 'enum'">
-      <el-select
-        v-model="inputValue"
-        class="!w-240px"
-        clearable
-        :placeholder="`请选择${dataSpecs?.name || '值'}`"
-      >
-        <el-option
-          v-for="item in dataSpecs?.enumList"
-          :key="item.value"
-          :label="item.text"
-          :value="item.value"
-        />
-      </el-select>
-    </template>
-
-    <!-- 布尔类型 -->
-    <template v-else-if="dataType === 'bool'">
-      <el-radio-group v-model="inputValue">
-        <el-radio
-          v-for="item in [
-            { value: true, label: dataSpecs?.trueText || '是' },
-            { value: false, label: dataSpecs?.falseText || '否' }
-          ]"
-          :key="String(item.value)"
-          :label="item.value"
-        >
-          {{ item.label }}
-        </el-radio>
-      </el-radio-group>
-    </template>
-
-    <!-- 日期类型 -->
-    <template v-else-if="dataType === 'date'">
-      <el-date-picker
-        v-model="inputValue"
-        class="!w-240px"
-        type="datetime"
-        :placeholder="`请选择${dataSpecs?.name || '日期'}`"
-      />
-    </template>
-
-    <!-- 结构体类型 -->
-    <template v-else-if="dataType === 'struct'">
-      <el-collapse class="w-full">
-        <el-collapse-item title="结构体参数">
-          <div
-            v-for="field in dataSpecs?.specs"
-            :key="field.identifier"
-            class="flex items-center mb-10px"
-          >
-            <span class="mr-10px inline-block min-w-80px">{{ field.name }}</span>
-            <PropertyValueInput
-              :model-value="getStructFieldValue(field.identifier)"
-              :data-specs="field"
-              @update:model-value="(val) => updateStructField(field.identifier, val)"
-            />
-          </div>
-        </el-collapse-item>
-      </el-collapse>
-    </template>
-
-    <!-- 数组类型 -->
-    <template v-else-if="dataType === 'array'">
-      <div class="flex flex-col w-full">
-        <div v-for="(item, index) in arrayValue" :key="index" class="flex items-center mb-10px">
-          <PropertyValueInput
-            :model-value="item"
-            :data-specs="dataSpecs?.arrayInfo"
-            @update:model-value="(val) => updateArrayItem(index, val)"
-          />
-          <el-button
-            type="danger"
-            size="small"
-            circle
-            class="ml-10px"
-            @click="removeArrayItem(index)"
-          >
-            <Icon icon="ep:delete" />
-          </el-button>
-        </div>
-        <el-button type="primary" size="small" plain @click="addArrayItem">添加项</el-button>
-      </div>
-    </template>
-
-    <!-- 默认文本输入 -->
-    <template v-else>
-      <el-input
-        v-model="inputValue"
-        class="!w-240px"
-        :placeholder="`请输入${dataSpecs?.name || '值'}`"
-      />
-    </template>
-  </div>
-</template>
-
-<script setup lang="ts">
-import { useVModel } from '@vueuse/core'
-
-/** 属性值输入组件 */
-defineOptions({ name: 'PropertyValueInput' })
-
-const props = defineProps<{
-  modelValue: any
-  dataSpecs: any
-}>()
-
-const emits = defineEmits(['update:modelValue'])
-
-// 获取数据类型
-const dataType = computed(() => {
-  return props.dataSpecs?.dataType
-})
-
-// 基本类型的输入值
-const inputValue = computed({
-  get: () => {
-    // 对于日期类型,如果是字符串需要转换为日期对象
-    if (dataType.value === 'date' && typeof props.modelValue === 'string') {
-      return new Date(props.modelValue)
-    }
-    return props.modelValue
-  },
-  set: (value) => {
-    // 对于日期类型,需要转换为ISO字符串
-    if (dataType.value === 'date' && value instanceof Date) {
-      emits('update:modelValue', value.toISOString())
-      return
-    }
-    emits('update:modelValue', value)
-  }
-})
-
-// 结构体类型处理
-const structValue = computed({
-  get: () => {
-    return props.modelValue || {}
-  },
-  set: (value) => {
-    emits('update:modelValue', value)
-  }
-})
-
-// 获取结构体字段值
-const getStructFieldValue = (identifier: string) => {
-  return structValue.value[identifier]
-}
-
-// 更新结构体字段
-const updateStructField = (identifier: string, value: any) => {
-  const newStruct = { ...structValue.value }
-  newStruct[identifier] = value
-  structValue.value = newStruct
-}
-
-// 数组类型处理
-const arrayValue = computed({
-  get: () => {
-    return Array.isArray(props.modelValue) ? props.modelValue : []
-  },
-  set: (value) => {
-    emits('update:modelValue', value)
-  }
-})
-
-// 添加数组项
-const addArrayItem = () => {
-  const newArray = [...arrayValue.value]
-  // 根据数组元素类型创建默认值
-  const arrayItemType = props.dataSpecs?.arrayInfo?.dataType
-  let defaultValue = null
-  switch (arrayItemType) {
-    case 'int':
-    case 'float':
-    case 'double':
-      defaultValue = 0
-      break
-    case 'bool':
-      defaultValue = false
-      break
-    case 'text':
-      defaultValue = ''
-      break
-    case 'struct':
-      defaultValue = {}
-      break
-    case 'array':
-      defaultValue = []
-      break
-  }
-  newArray.push(defaultValue)
-  arrayValue.value = newArray
-}
-
-// 更新数组项
-const updateArrayItem = (index: number, value: any) => {
-  const newArray = [...arrayValue.value]
-  newArray[index] = value
-  arrayValue.value = newArray
-}
-
-// 移除数组项
-const removeArrayItem = (index: number) => {
-  const newArray = [...arrayValue.value]
-  newArray.splice(index, 1)
-  arrayValue.value = newArray
-}
-</script>
-
-<style scoped lang="scss"></style>