开发项目中遇到的问题

本文总结了在Vue开发中遇到的各种问题,包括CSS选择器失效、Vue的computed属性使用、provide/inject的响应式问题、表单校验、自定义滚动条样式、Element UI的表单与表格问题,以及v-infinite-scroll的使用技巧。提供了相应的解决策略和代码示例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

css

  1. last-childfirst-child失效问题:
    如果父亲元素里的子元素有包含其他不一样的标签时,会出现获取不到的问题。
    当使用first的话,第一个子元素一定要是一样的标签.中间和最后可以是不一样的标签.
    last最后一个元素标签要一致,前面和中间可以是不一样标签。

    除了这些伪类,同样,其他的伪类在这种情况无法获取到。

vue

  1. 在使用this.$router.push实现路径跳转时,会延迟好几秒;
    是因为query属性的原因,当query对象属性以及属性值内容太多时,会增长路径拼接的速度。
  2. 在使用图片的时候,直接使用开发环境的路径在标签内使用图片或者在css中使用背景图片都会无法显示。
    第一种情况可以提前加载图片require(url)
  • css中给元素添加背景图,background: url(~@/img/page.png)
    ~是相对于其他路径(文件)的,类似于相对路径
    所以background正常使用相对路径也是ok的。

vue之computed

computed是计算出来的属性, 相当于计算结果, 所以我们不能直接对结果进行修改!

  1. getter函数
    负责使用data中的数据, 但是注意 只能用, 不能改! 使用完后 记得将结果return
  2. setter函数
    有一个参数 newValue, 负责接收传进来的值, 可以使用这个newValue给data中的数据进行操作:
  3. 给computed创建的属性赋值,其实是传参给setter函数,触发set事件

现在有个需求: 想给options里添加新的数据, 如何操作?

// 1. 需要用到set函数:
computed {
    objArr: {
        get() { return this.options;},
        set(newValue) {
            console.log('newValue', newValue)
            this.options.push(newValue);
        }
    }
}
// 2. 触发set函数 即给objArr赋值:
// 这里我们封装个方法:
methods: {
    setObjArr() {
        this.objArr = {b: 2}
    }
}
// 通过按钮点击触发
<button @click="setObjArr">set</button>
/**这里的this.objArr = { b: 2 }并不是把{b: 2} 赋值给objArr的意思, 而是传参给里面的set函数。
触发setObjArr事件, 会发现 计算属性 objArr 已经改变了, 其本质是因为data中的options发生了改变。**/

provide 和 inject 之响应式

provide和inject :provide并不是响应式的,当子组件inject的时候已经丢失了响应式功能

希望整个数据都是响应式的—provide提供一个函数
函数内部返回一个响应式的数据。此时整条数据的响应式的状态并不会丢失。

父组件:

provide() {
    return {
         getActiveSecurityType: () => ({
             activeSecurityType: this.securityType
         })
     }
 },

孙后代组件:

inject: ['getActiveSecurityType'],
computed: {
        activeSecurityType() {
            return this.getActiveSecurityType();
        },
    },
}
 watch: {
      activeSecurityType(newVal) {
      }
 }

form校验

  1. validate:
    对整个表单进行校验的方法,参数为一个回调函数。
    该回调函数会在校验结束后被调用,并传入两个参数:是否校验成功和未通过校验的字段。
    若不传入回调函数,则会返回一个 promise
    Function(callback: Function(boolean, object))
  2. validateField:
    对部分表单字段进行校验的方法
    Function(props: array | string, callback: Function(errorMessage: string))
<template>
  <el-form
    ref="form"
    :model="form"
    :rules="rules"
    label-width="80px"
    size="mini"
  >
    <el-form-item
      label="姓名"
      prop="name"
    >
      <el-input v-model.trim="form.name"></el-input>
    </el-form-item>

    <el-form-item
      label="年龄"
      prop="age"
    >
      <el-input v-model.number="form.age"></el-input>
    </el-form-item>

    <el-form-item
      label="学校"
      prop="school"
    >
      <el-input v-model.trim="form.school"></el-input>
    </el-form-item>

    <el-form-item>
      <el-button
        type="primary"
        @click="validate"
      >校验全部</el-button>

      <el-button
        type="primary"
        @click="validateField"
      >校验单个字段</el-button>

      <el-button
        type="primary"
        @click="validateFields"
      >校验多个字段</el-button>

    </el-form-item>
  </el-form>

</template>

<script>
// created at 2021-09-23
export default {
  name: 'TestForm',

  data() {
    return {
      form: {
        name: '',
        age: '',
        school: '',
      },

      rules: {
        name: [{ required: true, message: '请输入姓名', trigger: 'blur' }],
        age: [
          {
            required: true,
            message: '请输入年龄',
            trigger: 'blur',
          },
          { type: 'number', message: '年龄必须为数字值', trigger: 'blur' },
        ],
        school: [{ required: true, message: '请输入学校', trigger: 'blur' }],
      },
    };
  },
  methods: {
    /**
     * 校验全部字段
     */
    validate() {
      this.$refs['form'].validate((valid) => {
        console.log(valid); // true/false
      });
    },

    /**
     * 校验单个字段
     */
    validateField() {
      this.$refs['form'].validateField('name', (errorMessage) => {
        console.log(errorMessage);

        let valid = errorMessage == '' ? true : false;

        console.log(valid); // true/false
      });
    },

    /**
     * 校验多个字段
     */
    validateFields() {
      // 需要校验的字段
      let fieldsToValidate = ['name', 'age'];

      // 将回调转换为Promise
      Promise.all(
        fieldsToValidate.map((field) => {
          return new Promise((resolve, reject) => {
            this.$refs['form'].validateField(field, (errorMessage) => {
              resolve(errorMessage);
            });
          });
        })
      ).then((errorMessages) => {
        console.info(errorMessages);
        //  ['请输入姓名', '请输入年龄']

        // errorMessages 里是各个字段的验证错误信息, 如果数组里全为空串则所有验证通过
        // 判断errorMessages 里是否全是空串
        let valid = errorMessages.every((errorMessage) => {
          return errorMessage == '';
        });

        console.log(valid); // true/false
      });
    },
  },
};
</script>

初始化出现表单校验结果

el-form有一些表单校验会在初始化是就校验,解决方案:在form上绑定:validate-on-rule-change="false"

自定义滚动条

 /*滚动条样式*/
.innerbox::-webkit-scrollbar {/*滚动条整体样式*/
    width: 4px;     /*高宽分别对应横竖滚动条的尺寸*/
    height: 4px;
}
.innerbox::-webkit-scrollbar-thumb {/*滚动条里面小方块*/
    border-radius: 5px;
    -webkit-box-shadow: inset 0 0 5px rgba(0,0,0,0.2);
    background: rgba(0,0,0,0.2);
}
.innerbox::-webkit-scrollbar-track {/*滚动条里面轨道*/
    -webkit-box-shadow: inset 0 0 5px rgba(0,0,0,0.2);
    border-radius: 0;
    background: rgba(0,0,0,0.1);
}

element生成dom内文本前后自动追加空格

解决方案:

  1. 给对应的元素内添加一个标签
  2. 调整它的margin为负值

元素有滚动条出现时会占位,挤压元素

overflow属性设置值为
overflow: overlay

新特性记录

element table expand列合并

td.el-table__expand-column,
        th.el-table__expand-column {
            width: 0 !important;
            border-right: none !important;
            z-index: 1;

            &.is-left,
            &.is-right,
            &.is-center {
                .cell {
                    padding-right: 0 !important;
                }
            }
        }
        th.el-table__expand-column + th.is-left {
            overflow: visible !important;
            .cell {
                padding-left: 0 !important;
                transform: translate(-10px);
                z-index: 2;
            }
        }

element 下拉选值不回显问题

比如有一个所在地需要选择省市区,当省市选完后,选择区的时候,会发现值已经改变,但是区的下拉框没回显选中的数据,在打印中查看是修改成功了,但在页面中没有及时刷新改变后的值,也就是下拉框值无法选中。

解决方法:

出现这个问题好像是因为下拉框数据是循环掉别的接口得来的,因为数据层次太多,render函数没有自动更新,需手动强制刷新所以我直接强制刷新了值,而forceUpdate就是重新render。

写一个方法,在select的change事件中调用此方法,运用 this.$forceUpdate()强制刷新,页面正常选值。

change(){
	this.$forceUpdate()
}

函数导入错误导致的报错

在这里插入图片描述

通过弹窗取消按钮关闭弹窗可以清空表单,通过❎关闭表单不会清空

清空表单的时机放在关闭之前,非关闭之后

v-infinite-scroll 自动调用分页接口请求

问题出现在transition-group,将他替换成div

<el-scrollbar ref="scrollbar" class="h-full overflow-x-hidden">
  <transition-group
       v-if="allList && allList.length > 0"
       v-infinite-scroll="getMessageList"
       :infinite-scroll-immediate="false"
       :infinite-scroll-disabled="loading || loadingMore"
       :infinite-scroll-distance="50"
       name="messagelist"
       class="h-full"
       tag="ul"
   >
       <li
           v-for="(item, key) in allList"
           :key="item.messageId"
           :class="{ 'message-item': true, isRead: item.isRead, active: key === activeItem }"
           @click="getDetail(key)"
       >
           <div class="message-item-inner">
               <div class="message-close" @click.stop="deleteMsg(key)">
                   <i class="el-icon-close" />
               </div>
               <div class="flex">
                   <div>
                       <div class="message-title">{{ item.title }}</div>
                       <div class="leading-[12px]">
                           <span class="message-desc">{{ parseTime(item.sendTime) }}</span>
                       </div>
                   </div>
               </div>
           </div>
       </li>
       <li v-if="loadingMore" key="loading" class="message-item text-center">
           <div class="message-item-inner">
               <BosLoading></BosLoading>
           </div>
       </li>
       <li
           v-if="!loadingMore && totalCount !== -1 && allPage > Math.ceil(totalCount / allLimit)"
           key="loading"
           class="message-item text-center text-[#86909C] text-[12px]"
       >
           <div class="message-item-inner">{{ $t('COMMON_NO_MORE_DATA') }}</div>
       </li>
   </transition-group>

   <div v-else class="no-message">
       {{ $t('COMMON_NO_MESSAGE') }}
   </div>
</el-scrollbar>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值