vue2 插值语法中使用可选链运算符(.?)compile异常排查思路

发布于:2025-03-07 ⋅ 阅读:(17) ⋅ 点赞:(0)

@[TOC](vue2 插值语法中使用可选链运算符(.?)compile异常排查思路)

前言

最近接到组内前端求助,在使用v-for进行动态渲染的时候项目突然不能正常编译了,报错提示SyntaxError: Unexpected token ...十分奇怪
在这里插入图片描述
代码可参考如下:

      <h3>动态渲染内容</h3>
      <el-row v-for="(item, index) in form.subObjList" :key="index" :gutter="12" :style="{ background: '#edfced' }">
        <el-col> {{item?.projectNameLabel}}:{{item?.projectName}}</el-col>
        <el-col> {{item?.technicalPointLabel}}:{{item?.technicalPoint}}</el-col>
        <el-col> {{item?.mainFunctionLabel}}:主要功能:{{item?.mainFunction}}</el-col>
        <el-col> {{item?.difficultyLabel}}:{{item?.difficulty}}</el-col>
        <el-col><hr></el-col>
      </el-row>

待渲染的数据

      this.form.subObjList = [
        { projectNameLabel: '项目名称',
          projectName: 'xx项目前端',
          technicalPointLabel: '技术点',
          technicalPoint: 'vue vuex vue-router js',
          mainFunctionLabel: '主要功能',
          mainFunction: '前端交互ux整改,完善用户体验',
          difficultyLabel: '难点',
          difficulty: '大批量数据渲染'
        },
        { projectNameLabel: '项目名称',
          projectName: 'xx项目后端',
          technicalPointLabel: '技术点',
          technicalPoint: 'springboot mybatis redis pgsql',
          mainFunctionLabel: '主要功能',
          mainFunction: '支持用户的特定业务流程',
          difficultyLabel: '难点',
          difficulty: '大批量数据校验'
        }
      ]

排查思路

把新增的代码区域el-row以及内部el-col注释掉,重新加载检查编译情况,这时能成功编译
接着在放开el-row新增自定义el-col,重新加载检查编译情况,能够成功编译和渲染

      <h3>动态渲染内容</h3>
      <el-row v-for="(item, index) in form.subObjList" :key="index" :gutter="12" :style="{ background: '#edfced' }">
      <el-col>heheda</el-col>
<!--        <el-col> {{item?.projectNameLabel}}:{{item?.projectName}}</el-col>-->
<!--        <el-col> {{item?.technicalPointLabel}}:{{item?.technicalPoint}}</el-col>-->
<!--        <el-col> {{item?.mainFunctionLabel}}:主要功能:{{item?.mainFunction}}</el-col>-->
<!--        <el-col> {{item?.difficultyLabel}}:{{item?.difficulty}}</el-col>-->
<!--        <el-col><hr></el-col>-->
      </el-row>

在这里插入图片描述
观察到插值语法中的可选链运算符(.?)比较怪,于是选取一个el-col去掉.?并放开注释,可以正常渲染
在这里插入图片描述
再次加上.?,重现了编译失败
在这里插入图片描述
由此可以确认是在插值语法中使用可选链运算符(.?)引起的

临时解决措施

去掉可选链运算符(.?),与前端确认,此处动态渲染的数据需请求接口得到,item的属性没有在data()中申明,所以使用(.?)来避免一些潜在的问题

后续

处理完这个问题后,计划在个人PC上复现,但是并没有复现成功(环境为vue 3.4.28 & node 18.20.4
),经过搜查发现该问题会在vue2低版本上出现,此时相应的node.js版本不支持在插值语法中使用可选链运算符,于是搭建了(vue 2.6.10 & node 14.16),确实成功复现了这个问题。求助的项目vue版本为2.5.x,考虑到不久后该项目就会升级vue 3,所以没有深究如何在vue 2中实现插值语法可以使用可选链运算符号。
此处分享在vue3中该案例的完整代码:

<template>
  <div>
    <h3>Welcome</h3>
    <el-form :model="form" label-width="100px">
      <el-row :gutter="20">
        <el-col :span="12">
          <el-form-item label="姓名">
            <el-input v-model="form.name"></el-input>
          </el-form-item>
        </el-col>
        <el-col :span="12">
          <el-form-item label="年龄">
            <el-input v-model="form.age"></el-input>
          </el-form-item>
        </el-col>
      </el-row>
      <el-row :gutter="20">
        <el-col :span="8">
          <el-form-item label="地址">
            <el-input v-model="form.address"></el-input>
          </el-form-item>
        </el-col>
      </el-row>
    <h3>动态渲染内容</h3>
      <el-row v-for="(item, index) in form.subObjList" :key="index" :gutter="12" :style="{ background: '#edfced' }">
        <el-col> {{item?.projectNameLabel}}:{{item?.projectName}}</el-col>
        <el-col> {{item?.technicalPointLabel}}:{{item?.technicalPoint}}</el-col>
        <el-col> {{item?.mainFunctionLabel}}:主要功能:{{item?.mainFunction}}</el-col>
        <el-col> {{item?.difficultyLabel}}:{{item?.difficulty}}</el-col>
        <el-col><hr></el-col>
      </el-row>
    </el-form>
    <button @click="setRenderInfo">动态渲染赋值</button>
    <button @click="clearRenderInfo">动态渲染清空</button>
  </div>
</template>

<!--vue3写法-->
<!--<script setup lang="ts" name="About">
import { reactive, ref } from 'vue'
import type { ComponentSize, FormProps } from 'element-plus'

let form = {
  name: '松树戈',
  age: '66',
  address: '这里',
  secondLabel: '我就是第二个标题',
  subObjList: []

}
// 模拟远程请求后对subObjList进行赋值
form.subObjList = [
  { projectNameLabel: '项目名称',
    projectName: 'xx项目前端',
    technicalPointLabel: '技术点',
    technicalPoint: 'vue vuex vue-router js',
    mainFunctionLabel: '主要功能',
    mainFunction: '前端交互ux整改,完善用户体验',
    difficultyLabel: '难点',
    difficulty: '大批量数据渲染'
  },
  { projectNameLabel: '项目名称',
    projectName: 'xx项目后端',
    technicalPointLabel: '技术点',
    technicalPoint: 'springboot mybatis redis pgsql',
    mainFunctionLabel: '主要功能',
    mainFunction: '支持用户的特定业务流程',
    difficultyLabel: '难点',
    difficulty: '大批量数据校验'
  }
]
</script>-->
<!--vue2写法-->
<script>
  export default {
    data() {
      return {
        form: {
          name: '松树戈',
          age: '66',
          address: '这里',
          secondLabel: '我就是第二个标题',
          subObjList: []
        }
      }
    },
    mounted() {
      console.log('在-mounted内部')
    },
    methods: {
      setRenderInfo() {
        this.form.subObjList = [
          { projectNameLabel: '项目名称',
            projectName: 'xx项目前端',
            technicalPointLabel: '技术点',
            technicalPoint: 'vue vuex vue-router js',
            mainFunctionLabel: '主要功能',
            mainFunction: '前端交互ux整改,完善用户体验',
            difficultyLabel: '难点',
            difficulty: '大批量数据渲染'
          },
          { projectNameLabel: '项目名称',
            projectName: 'xx项目后端',
            technicalPointLabel: '技术点',
            technicalPoint: 'springboot mybatis redis pgsql',
            mainFunctionLabel: '主要功能',
            mainFunction: '支持用户的特定业务流程',
            difficultyLabel: '难点',
            difficulty: '大批量数据校验'
          }
        ]
      },
      clearRenderInfo() {
        this.form.subObjList = []
      }
    }
  }
</script>
<style scoped>
.about {
  display: flex;
  justify-content: center;
  align-items: center;
  height: 100%;
  color: rgb(85, 84, 84);
  font-size: 18px;
}
</style>

demo项目完整代码:

码云
gitehub


网站公告

今日签到

点亮在社区的每一天
去签到