首页 > 其他分享 >vue-treeselect 校验失败添加红框

vue-treeselect 校验失败添加红框

时间:2023-08-16 17:45:26浏览次数:53  
标签:node 红框 vue default 校验 treeselect type

需求

vue-treeselect 校验及清除校验 这篇介绍了用 @input 在校验失败时显示校验信息。但还需要同时显示红色边框。如下图所示:

image

解决办法

思路:动态绑定类名,校验失败时切换类名,更改边框颜色。

子组件 SelectTree

二次封装 vue-treeselect:组件 SelectTree
<template>
  <div class="select-tree">
    <treeselect
      :class="{ error: isError === true }"
      appendToBody
      z-index="9000"
      :flat="isFlat"
      :multiple="isMultiple"
      :noOptionsText="noOptionsText"
      noResultsText="未搜索到匹配项"
      :value-consists-of="valueConsistsOf"
      :limit="limitNum"
      :limitText="(count) => `+${count}`"
      v-model="modelValue"
      @input="performValidate"
      :options="optionTree"
      :show-count="showCount"
      :normalizer="normalizerNode"
      :placeholder="placeText ? placeText : `请选择上级${nodeLabel}(可搜索)`"
      :disabled="isDisabled"
      :disable-branch-nodes="disBranchNodes"
      :clearable="showClearable"
    >
      <label
        slot="option-label"
        slot-scope="{ node, shouldShowCount, labelClassName, countClassName }"
        :class="labelClassName"
      >
        <!-- 可自定义选项内容 -->
        <slot
          name="diy-option"
          v-bind="{ node, shouldShowCount, countClassName }"
        >
          {{ node.label }}
          <span v-if="shouldShowCount" :class="countClassName"
            >({{ node.children.length }})</span
          >
        </slot>
      </label>

      <div slot="value-label" slot-scope="{ node }">
        <!-- 可自定义值标签 -->
        <slot name="diy-value" v-bind="{ node }">
          {{ node.label }}
        </slot>
      </div>
    </treeselect>
  </div>
</template>

<script>
import Treeselect from "@riophae/vue-treeselect";
import "@riophae/vue-treeselect/dist/vue-treeselect.css";

export default {
  name: "SelectTree",
  components: {
    Treeselect,
  },
  computed: {
    modelValue: {
      get() {
        // 若选项中没有为 0 的 id,则自动把 modelValue 置为 null
        const flag = this.optionTree.find(
          (ele) => ele[this.exchangeNode.id] === 0
        );
        if (!flag && this.modelVal === 0) {
          return null;
        } else {
          return this.modelVal;
        }
      },
      set(val) {
        this.$emit("return-model", val);
        return val;
      },
    },
  },
  props: {
    // 校验失败:默认成功
    isError: {
      type: Boolean,
      default: false,
    },
    appendToBody: {
      type: Boolean,
      default: false,
    },
    // 限制所选选项的显示
    limitNum: {
      type: Number,
      default: 5,
    },
    // 防止价值组合:对于非固定和多选模式,如果选中了分支节点及其所有后代,则vue-treeselect会将它们组合到值数组中的单个项目中
    valueConsistsOf: {
      type: String,
      default: "BRANCH_PRIORITY",
    },
    // 是否开启多选
    isMultiple: {
      type: Boolean,
      default: false,
    },
    // 是否开启平面模式(父子节点不关联)
    isFlat: {
      type: Boolean,
      default: false,
    },
    // 无选项内容时的提示文本
    noOptionsText: {
      type: String,
      default: "暂无数据",
    },
    // 下拉框绑定值
    modelVal: {
      type: [String, Number, Array, null],
      default: null,
    },
    // 是否显示清空按钮
    showClearable: {
      type: Boolean,
      default: true,
    },
    // 自定义提示
    placeText: {
      type: [String, null],
      default: null,
    },
    // 是否禁止选择有子节点的选项
    disBranchNodes: {
      type: Boolean,
      default: false,
    },
    // 节点名称
    nodeLabel: {
      type: String,
      default: "节点",
    },
    // 是否显示计数
    showCount: {
      type: Boolean,
      default: true,
    },
    // 转换节点结构
    exchangeNode: {
      type: Object,
      default: () => {
        return {
          id: "id",
          label: "label",
          children: "children",
        };
      },
    },
    // 是否禁用
    isDisabled: {
      type: Boolean,
      default: false,
    },
    // 选项树:用于上级节点选项中选择
    optionTree: {
      type: Array,
      default: () => {
        let tree = [
          {
            id: 0,
            label: "全部节点",
            children: [],
          },
        ];
        tree[0].children = [];
        return tree;
      },
    },
  },
  methods: {
    // 进行校验
    performValidate() {
      this.$emit("perform-validate");
    },
    /* 转换节点数据结构 */
    normalizerNode(node) {
      if (node.children && !node.children.length) {
        delete node.children;
      }
      let res = {
        id: node[this.exchangeNode.id],
        label: node[this.exchangeNode.label],
        children: node[this.exchangeNode.children],
      };
      if (node[this.exchangeNode.isDisabled]) {
        res["isDisabled"] = node[this.exchangeNode.isDisabled];
      }
      return res;
    },
  },
};
</script>

<style lang="scss" scoped>
// 调整 vue-treeselect 禁用样式
::v-deep .vue-treeselect.vue-treeselect--disabled .vue-treeselect__control {
  background-color: #f5f7fa;
  border-color: #dfe4ed;
  cursor: not-allowed;

  .vue-treeselect__single-value {
    color: #c0c4cc;
  }
}

// 校验不通过时,输入框边框变红
::v-deep .vue-treeselect.error .vue-treeselect__control {
  border-color: #ff4949;
}
</style>

SelectTree 组件中,使用 :class="{ error: isError === true }" 动态绑定类名 error,设置有此类名时,边框变红:

// 校验不通过时,输入框边框变红
::v-deep .vue-treeselect.error .vue-treeselect__control {
  border-color: #ff4949;
}

父组件中使用

image

image

image

image

image

image

思考

以上这种传递变量更改动态类名的方式,虽然可以实现需求,但是有以下缺点:

  1. 组件耦合性太强,即使用时需要在多处书写代码;
  2. 若页面中有多处使用了子组件 SelectTree,某一处的校验会干扰其他处。

因此,此种方式不可取,需要进一步优化。

参考链接

  1. vue动态绑定类名的几种方法
  2. vue-treeselect 校验不出现红色方框的解决办法

标签:node,红框,vue,default,校验,treeselect,type
From: https://www.cnblogs.com/shayloyuki/p/17635778.html

相关文章

  • vue-router 配置
    1.安装   npminstallvue-router--save  vue2会有版本兼容问题:[email protected].配置  在src文件夹下新建router文件夹,在router文件夹中新建index.js//导入路由对象importRouterfrom'vue-router'//vue-router是插件所以我们用Vue.use......
  • 在不利用vue实现循环数据输入到表格
    如果您不使用Vue或其他前端框架,可以使用原生的JavaScript来实现将循环数据输入到表格中的操作。首先,您需要一个包含要展示数据的数组。然后,使用JavaScript循环遍历数据数组,动态创建表格的行和单元格,并将数据填充到相应的单元格中。下面是一个示例代码,展示了如何使用JavaScript将......
  • Vue 生命周期
    生命周期生命周期函数定义的位置与data属性、methods属性平级beforeCreate在Vue实例创建之前,data中的数据和methods中的方法并没有初始化,所以它不能被调用在created生命周期函数中,data中的数据和methods中的方法已经被初始化完成,可以在页面中调用......
  • Vue 样式绑定
    绑定HTMLclass:class (v-bind:class 的缩写) :class 指令也可以和一般的 class attribute共存绑定的对象并不一定需要写成内联字面量的形式,也可以直接绑定一个对象可以给 :class 绑定一个数组来渲染多个CSSclass绑定内联样式:style 支持绑定JavaScript对象......
  • vue 报错解决方法
    nodejs版本过高导致启动项目失败  控制台输入$env:NODE_OPTIONS="--openssl-legacy-provider"重新下载依赖 npmi启动项目npmrundev 参考  umi项目启动报错node:internal/crypto/hash:71this[kHandle]=new_Hash(algorithm,xofLen);_今夜來看雪的博客-CSDN博......
  • 搞懂 Vue3 中的各种 ref:toRef,toRefs,isRef,unref...
    在Vue3中,有许多与响应式相关的函数,例如toRef、toRefs、isRef、unref等等。合理地使用这些函数可以在实际开发中大大提高效率。本文将详细介绍这些函数的用法,让我们在实际开发中知道应该使用哪些API并能够熟练地回答面试官的相关问题。ref()大家对于ref这个API肯定都不......
  • vue-vuex中使用commit提交mutation来修改state的原因解析
    https://blog.csdn.net/a460550542/article/details/82620457 在vuex中,关于修改state的方式,需要commit提交mutation。官方文档中有这么一句话:更改Vuex的store中的状态的唯一方法是提交mutation。为了搞清楚其原因,查阅了很多资料,发现其它人在做vuex的源码解析的时候,并......
  • vuex中actions和mutations区别
    定义:在Vuex中,actions和mutations是两个核心概念,用于管理应用程序状态的变化。一:Mutationsmutations是用于修改Vuex状态的唯一方法。它们是同步操作,意味着它们必须是纯函数,以确保状态的可预测性。这意味着mutations应该只用于同步操作,例如在响应用户事件时更新状态。它们不应......
  • vue3 - 警告 `shallowRef` instead of `ref` - 解决
    完整警告[Vuewarn]:VuereceivedaComponentwhichwasmadeareactiveobject.Thiscanleadtounnecessaryperformanceoverhead,andshouldbeavoidedbymarkingthecomponentwith`markRaw`orusing`shallowRef`insteadof`ref`.这是因为参数内容有组件,......
  • 基于微服务+Java+Spring Cloud Vue +UniApp +MySql实现的智慧工地云平台源码
    智慧工地概念智慧工地是一种崭新的工程全生命周期管理理念,是指运用信息化手段,通过对工程项目进行精确设计和施工模拟,围绕施工过程管理,建立互联协同、智能生产、科学管理的施工项目信息化生态圈,并将此数据在虚拟现实环境下与物联网采集到的工程信息进行数据挖掘分析,提供过程趋势预测......