当前位置: 首页 > 知识库问答 >
问题:

vue.js - vue3 报错解决 ?

盖昀
2024-08-29
<template>
  <!-- 编辑组织 -->
  <div class="self-el-dialogs" v-dialogdrag>
    <dialog-form v-model="selfshow" :rules="rules" :form.sync="form" :detail="detail" :request="organization"
      :title="title" @close="close" @success="success" labelWidth="55px" size="custom" customClass="org-custom-class">
      <!-- 添加校区 -->
      <template v-if="detail.type == '3'">
        <dialog-form-item label="上级">
          <el-input v-model="form.pid_name" disabled autocomplete="off"></el-input>
        </dialog-form-item>
        <dialog-form-item label="名称" prop="name" :rules="{ required: true, message: '请输入校区名称', trigger: 'blur' }">
          <el-input v-model="form.name" autocomplete="off" placeholder="请输入校区名称"></el-input>
        </dialog-form-item>
        <el-form-item label="区域" prop="province_id">
          <area-cascader style="width: 100%" placeholder="请选择区域" :show-all-levels="true"
            v-model:province_id="form.province_id" v-model:city_id="form.city_id" :leval="2" />
        </el-form-item>
        <dialog-form-item label="属性" prop="identity_id">
          <select-options :request="classificationCode" :search="{ code: 'identity' }" v-model="form.identity_id"
            placeholder="请选择校区属性"></select-options>
        </dialog-form-item>
        <dialog-form-item label="分类" prop="campus_type">
          <el-select v-model="form.campus_type" placeholder="请选择校区分类">
            <el-option :label="item.name" :value="item.id" v-for="(item, index) in campusType" :key="index"></el-option>
          </el-select>
        </dialog-form-item>
        <!-- 地级市校区业绩统计(V1)待联调 -->
        <dialog-form-item label="归属" v-if="detail.type == '3'" prop="area_belong_id">
          <el-select v-model="form.area_belong_id" filterable placeholder="请选择归属" style="width: 240px">
            <el-option v-for="item in areaArr" :key="item" :label="item.name" :value="item.id" />
          </el-select>
        </dialog-form-item>
        <dialog-form-item label="激励业绩" prop="is_area_achievement" v-if="detail.type == '3'">
          <el-radio-group v-model="form.is_area_achievement" class="ml-4" style="margin-left: 10px">
            <el-radio label="1" size="large">核算</el-radio>
            <el-radio label="2" size="large">不核算</el-radio>
          </el-radio-group>
        </dialog-form-item>
        <dialog-form-item label="代码" prop="code" :rules="{ required: true, message: '请输入校区代码', trigger: 'blur' }">
          <el-input v-model="form.code" autocomplete="off" placeholder="请输入校区代码"></el-input>
        </dialog-form-item>
      </template>
      <!-- 添加部门 -->
      <template v-if="detail.type == '4'">
        <dialog-form-item label="上级">
          <el-input v-model="form.pid_name" disabled autocomplete="off"></el-input>
        </dialog-form-item>
        <dialog-form-item label="名称" prop="dept_id" :rules="{ required: true, message: '请选择部门', trigger: 'change' }" v-if="type == '1'">
          <select-options :request="dept" v-model="form.dept_id" :filterable="true" :remote="true" placeholder="请选择部门"
            v-model:modelValueName="form.name" @change="deptChange"></select-options>
        </dialog-form-item>
        <dialog-form-item label="名称" prop="name" v-if="type == '2'">
          <el-input class="name" v-model="form.name" autocomplete="off" :placeholder="'请输入部门名称'"></el-input>
        </dialog-form-item>
        <el-form-item label="区域" prop="province_id">
          <area-cascader style="width: 100%" placeholder="请选择区域" :show-all-levels="true"
            v-model:province_id="form.province_id" v-model:city_id="form.city_id" :leval="2" />
        </el-form-item>
        <dialog-form-item label="代码" prop="code" :rules="{ required: true, message: '请输入部门代码', trigger: 'blur' }">
          <el-input v-model="form.code" autocomplete="off" placeholder="请输入部门代码"></el-input>
        </dialog-form-item>
        <!-- 地级市校区业绩统计(V1)待联调 -->
        <dialog-form-item label="归属" v-if="detail?.is_schools == '为省级分校群'" prop="area_belong_id">
          <el-select v-model="form.area_belong_id" filterable placeholder="请选择归属" style="width: 240px">
            <el-option v-for="item in areaArr" :key="item.id" :label="item.name" :value="item.id" />
          </el-select>
        </dialog-form-item>
        <dialog-form-item label="激励业绩" prop="is_area_achievement" v-if="detail?.is_schools == '为省级分校群'">
          <el-radio-group v-model="form.is_area_achievement" class="ml-4" style="margin-left: 10px">
            <el-radio label="1" size="large">核算</el-radio>
            <el-radio label="2" size="large">不核算</el-radio>
          </el-radio-group>
        </dialog-form-item>
      </template>
      <!-- 添加岗位 -->
      <template v-if="detail.type == '5'">
        <dialog-form-item label="名称" prop="post_id" :rules="{ required: true, message: '请选择岗位', trigger: 'change' }">
          <select-options :request="post" v-model="form.post_id" :filterable="true" placeholder="请选择岗位"
            v-model:modelValueName="form.name"></select-options>
        </dialog-form-item>
      </template>
      <!-- 结算单元 -->
      <dialog-form-item label="结算单元" prop="" v-if="type == '2'">
        <el-radio-group v-model="form.is_settle_cell" class="ml-4" style="margin-left: 10px">
          <el-radio label="1" size="large">是</el-radio>
          <el-radio label="2" size="large">否</el-radio>
        </el-radio-group>
      </dialog-form-item>
      <dialog-form-item label="停用" prop="is_usable" v-if="type == '2' && detail.type != '5'">
        <el-switch v-model="form.is_usable" active-value="2" inactive-value="1" inline-prompt></el-switch>
      </dialog-form-item>
    </dialog-form>
  </div>
</template>
<script lang="ts">
import { campusType } from '../../config'
import { defineComponent, reactive, ref, toRef, toRefs, watchEffect, onMounted } from 'vue'
import { organization } from '../../api/organizationStructure'
import { asyncArea } from '../../api/index'
import { classificationCode } from '@/api/common'
import { post, dept, area } from '../../api/index'
import areaCascader from '@/components/BusinessCenter/baseSelects/area-cascader.vue'
interface prop {
  show: boolean
  type: string
  detail?: any
}
export default defineComponent({
  name: 'editOrganization',
  components: {
    areaCascader
  },
  props: {
    show: {
      type: Boolean,
      default: false
    },
    type: {
      type: String
    },
    detail: {
      type: Object
    }
  },
  setup(props: prop, { emit }) {
    const option = ref<any>()
    let close = () => {
      emit('update:show', false)
    }
    let success = () => {
      close()
      emit('success')
    }
    const state = reactive({
      selfshow: false,
      areaArr: [],
      form: {
        pid: props.detail.pid,
        type: props.detail.type,
        sort: props.detail.sort,
        name: '',
        dept_id: '',
        identity_id: '',
        province_id: '',
        city_id: '',
        is_usable: '1',
        is_area_achievement: '', // 是否激励
        area_belong_id: '', // 归属id
        area_belong_id_name: ''
      } as any,
      title: '',
      rules: {
        name: [{ required: true, message: '请输入名称', trigger: 'blur' }],
        customer_code: [
          { required: false, message: '请输入客户编码', trigger: 'blur' }
        ],
        identity_id: [
          { required: true, message: '请选择属性', trigger: 'change' }
        ],
        campus_type: [
          {
            required: props.detail.type == '3' ? true : false,
            message: '请选择校区分类',
            trigger: 'change'
          }
        ],
        dept_type: [
          {
            required: props.detail.type == '4' ? true : false,
            message: '请选择部门分类',
            trigger: 'change'
          }
        ],
        province_id: [
          { required: true, message: '请选择区域', trigger: 'change' }
        ]
      },
      dept_type: [
        { name: '市场营销类', id: '2' },
        { name: '运营服务类', id: '1' },
        { name: '教学教研类', id: '3' },
        { name: '决策职能类', id: '4' },
        { name: '信息技术类', id: '5' }
      ],
      postData: [] as Array<any>
    })
    //省份更改
    const provideChange = (id: string) => {
      setTimeout(() => {
        option?.value?.getData && option.value.getData()
        state.form.city_id = ''
      }, 10)
    }
    watchEffect(() => {
      state.selfshow = props.show
      // 默认为'0'的时候
      if (props.detail?.area_belong_id === '0') {
        delete props.detail.area_belong_id
      }

      state.form = JSON.parse(JSON.stringify(props.detail))
      console.log(state.form, '看看数据')
      if (props.detail.type == '3') {
        state.title = '校区'
      } else if (props.detail.type == '4') {
        state.title = '部门'
      } else if (props.detail.type == '5') {
        state.title = '岗位'
      }
    })

    let deptChange = (val: any) => {
      dept.getList({ name: '', page: 1, size: 50, noloading: true }).then(res => {
        res.data.list.forEach((item: any) => {
          if (item.id == val) {
            state.form.dept_type = item.dept_type
          }
        })
      })
    }

    let getArea = () =>
      area.getList({}).then(({ data }) => {
        if (data.length) state.areaArr = data
      }).catch(error => {
        console.error('获取归属列表失败:', error)
      })

    onMounted(() => {
      getArea()
    })

    return {
      deptChange,
      getArea,
      option,
      close,
      ...toRefs(state),
      organization,
      success,
      asyncArea,
      classificationCode,
      provideChange,
      campusType: campusType,
      dept,
      post,
      area
    }
  }
})
</script>

image.png 请教一下大佬们 为什么 迷糊查询的时候 会报错,key没有重复的嗄??

bug 修改

共有1个答案

白祺然
2024-08-29

针对你提供的 Vue 3 组件代码和遇到的问题(模糊查询时报错,但声明没有重复的 key),这里有几个可能的原因和相应的解决方案:

1. 重复的 key 属性

虽然你提到没有重复的 key,但在 Vue 中使用 v-for 时确保每个元素都有一个唯一的 key 是非常重要的。在你的代码中,有几个地方使用了 v-for,比如:

<el-option
  v-for="item in areaArr"
  :key="item"
  :label="item.name"
  :value="item.id"
/>

这里 :key="item" 可能是问题所在,如果 item 本身是一个对象,并且这些对象在数组中的引用可能相同(即使内容不同),那么 Vue 可能会认为 key 是重复的。你应该使用对象内的一个唯一属性作为 key,比如 :key="item.id"

修改后

<el-option
  v-for="item in areaArr"
  :key="item.id"
  :label="item.name"
  :value="item.id"
/>

2. 异步数据处理

在你的组件中,你使用了异步数据(如 getArea() 方法)。确保在数据到达并且被正确处理后再渲染组件是很重要的。如果数据在渲染过程中仍然是 undefinednull,那么你的模板可能会尝试访问不存在的属性,导致错误。

解决方案

  • 确保所有需要的数据在模板渲染前已经准备好。
  • 使用可选链(Optional Chaining)来防止访问未定义或 null 的属性。

3. 组件的响应式更新

在 Vue 3 中,使用 reactiveref 创建的响应式数据需要正确地在模板中引用。你使用了 toRefs 来解构响应式对象,这是一个好的做法,因为它可以保持响应性。

4. 检查第三方组件

你的组件中使用了多个自定义组件(如 dialog-form, dialog-form-item, select-options, area-cascader 等)。确保这些组件内部没有导致问题的代码。特别是它们如何处理 props 和 events,以及它们是否正确地维护了内部的响应性和 key。

5. 错误的错误消息

有时候,错误消息可能并不直接指向问题所在。检查控制台中的错误堆栈跟踪,看看是否有其他地方(可能是父组件或子组件)触发了错误。

6. Vue 开发者工具

使用 Vue 开发者工具来检查组件的状态和属性,这可以帮助你快速定位问题。

通过以上步骤,你应该能够诊断并解决你遇到的模糊查询报错问题。如果问题仍然存在,可能需要更详细的错误信息和代码上下文来进一步分析。

 类似资料:
  • 错误提示如下: storybook 版本

  • 我首先使用 vue-cli 创建了一个项目 除了勾选了一个 typescript 之后,其他都是默认,一路回车 然后安装了几个依赖 引入 Antd 然后,从 https://antdv.com/components/menu-cn 赋值关于 a-menu 的 demo 代码 修改 src/components/HelloWorld.vue 然后运行 yarn serve 解决打开浏览器就报错了:

  • 大佬们帮忙看一个问题,关于Vue3 SSR onServerPrefetch生命周期的 我是想在该生命周期里调用接口获取数据然后直接在HTML里渲染,结果报错了 这是报错信息!!! 我查看了Vue文档SSR的章节https://cn.vuejs.org/guide/scaling-up/ssr.html#component-life...,并没有找到问题所在,甚至连示例都一致。

  • vue3、vite项目本地运行正常,打包报一堆错,应该是type-check的报错,应该怎么解决? 无

  • vue3+vite打包的时候,报错Access is denied,请问怎么解决啊?重新装了node_modules包,用nvm试了npm的几个版本都不行

  • 在vue3和pinia使用ts type+sId+zId 三个都会报 “property type does not exist on object” 新补充 v1,v2...是接口返回来的,自己重新定义了新key,v1写在IUserState了没有报错,其他都飘红