113 集11 ctrl+左键多选 vue中change事件阻止冒泡 flex布局 border渐变 svg经过变颜色 $event实参 el-tree样式 el-upload回显 table 菜单

文章讲述了在Vue组件中实现多选和单选功能,如何使用`ctrl+左键`进行多选操作,同时防止颜色选择器的点击事件在父节点上冒泡。代码展示了如何通过`@mousedown.prevent`和`click.stop`处理这些交互逻辑。

1.ctrl+左键单击多选,单击单选

精简代码

  <div class="model-list">
      <div
        @mousedown.prevent="handleClick(item, $event)"
        class="model-list-item"
        v-for="item in modelList"
        :key="item.id"
        :class="{ 'model-active': item.active }"
      >
        {{ item.name }}
      </div>
    </div>


//script

 public modelList = [
    {
      id: 0,
      name: '马栏山方案-HR-0001',
      active: false,
    },
    {
      id: 1,
      name: '马栏山方案-HR-0002',
      active: false,
    },
    {
      id: 2,
      name: '马栏山方案-HR-0003',
      active: false,
    },
  ];
  //单选 状态切换
  modelSelect(info: any) {
    this.modelList.forEach(item => {
      if (item.id === info.id) {
        item.active = !item.active;
      } else {
        item.active = false;
      }
    });
  }

  //多选状态为true
  multiSelect(info: any) {
    this.modelList.forEach(item => {
      if (item.id === info.id) {
        item.active = !item.active;
      }
    });
  }

  //判断是否多选操作
  handleClick(item: any, event: any) {
    // 检查是否按下了Ctrl键并是左键点击
    if (event.ctrlKey && event.button === 0) {
      this.multiSelect(item);
    } else {
      this.modelSelect(item);
    }
  }
<template>
  <!-- 数据编辑--合并 -->
  <CsDialog
    :width="580"
    @close="visibleDialog = false"
    @reduce="visibleDialog = false"
    @expend="visibleDialog = false"
    title="合并"
    :visible="visibleDialog"
  >
    <div class="row-item common-wrapper">提示:选择一个模型继承其属性</div>
    <div class="model-list">
      <div
        @mousedown.prevent="handleClick(item, $event)"
        class="model-list-item"
        v-for="item in modelList"
        :key="item.id"
        :class="{ 'model-active': item.active }"
      >
        {{ item.name }}
      </div>
    </div>

    <template slot="footer">
      <div class="end__operation">
        <CsButton @click="visibleDialog = false">确定</CsButton>
        <CsButton @click="visibleDialog = false">取消</CsButton>
      </div>
    </template>
  </CsDialog>
</template>

<script lang="ts">
import { Component, Vue, Prop } from 'vue-property-decorator';

@Component({
  components: {},
})
export default class CombineDialog extends Vue {
  @Prop() visible!: any;

  get visibleDialog() {
    return this.visible;
  }
  set visibleDialog(val: any) {
    this.$emit('update:visible', val);
  }

  mounted() {}
  public modelList = [
    {
      id: 0,
      name: '马栏山方案-HR-0001',
      active: false,
    },
    {
      id: 1,
      name: '马栏山方案-HR-0002',
      active: false,
    },
    {
      id: 2,
      name: '马栏山方案-HR-0003',
      active: false,
    },
    {
      id: 3,
      name: '马栏山方案-HR-0004',
      active: false,
    },
    {
      id: 4,
      name: '马栏山方案-HR-0005',
      active: false,
    },
    {
      id: 5,
      name: '马栏山方案-HR-0006',
      active: false,
    },
    {
      id: 6,
      name: '马栏山方案-HR-0006',
      active: false,
    },
    {
      id: 7,
      name: '马栏山方案-HR-0006',
      active: false,
    },
    {
      id: 8,
      name: '马栏山方案-HR-0006',
      active: false,
    },
  ];

  modelSelect(info: any) {
    this.modelList.forEach(item => {
      if (item.id === info.id) {
        item.active = !item.active;
      } else {
        item.active = false;
      }
    });
  }
  multiSelect(info: any) {
    this.modelList.forEach(item => {
      if (item.id === info.id) {
        item.active = !item.active;
      }
    });
  }

  handleClick(item: any, event: any) {
    // 检查是否按下了Ctrl键并是左键点击
    if (event.ctrlKey && event.button === 0) {
      this.multiSelect(item);
    } else {
      this.modelSelect(item);
    }
  }
}
</script>

<style lang="scss" scoped>
.excavation-analysis {
  position: absolute;
  top: 0;
  left: 50%;
}
.end__operation {
  float: right;
  display: flex;
}

.el-radio-group {
  padding: 5px 8px;
  border-radius: 2px;
  border: 1px solid rgba(204, 212, 228, 1);
  background-color: #f9fafc;
  display: flex;
  align-items: center;
}
.row-item {
  display: flex;
  justify-content: space-between;
  margin-bottom: 8px;
}
.common-wrapper {
  display: flex;
  align-items: center;
  font-size: 14px;
  font-weight: 400;
  line-height: 22px;
  color: rgba(115, 123, 141, 1);
  padding: 5px 8px;
  border-radius: 2px;
  border: 1px solid rgba(204, 212, 228, 1);
  background-color: #f9fafc;
  font-family: PingFang SC;
}
.file-select {
  display: flex;
  justify-content: space-between;
  width: 100%;
}

.model-list {
  font-family: PingFang SC;
  font-size: 14px;
  color: rgba(115, 123, 141, 1);
  max-height: 300px;
  overflow-y: auto;
  .model-list-item {
    height: 32px;
    line-height: 32px;
    padding-left: 8px;
    &:nth-child(2n + 1) {
      background-color: rgba(245, 248, 253, 1);
    }
  }
  .model-active {
    background: rgba(203, 218, 255, 1) !important;
  }
}
</style>

2.vue中change事件阻止冒泡

问题:在点击选择颜色的时候,触发了父节点的点击事件,导致开启了背景颜色

解决办法

<template>
  <div class="special-effects">
    <div :class="['item', item.active ? 'active' : '']" v-for="item in specialList" @click.stop="clickBtn(item)" :key="item.id">
      <img :src="item.icon" alt="" />
      <span>{{ item.title }}</span>
      <div @click.stop>
        <el-color-picker @change="changeColor" show-alpha v-if="item.title == 'X光效'" v-model="color"></el-color-picker>
      </div>
    </div>
  </div>
</template>

给颜色选择器套一层,加上@click.stop

3.flex均分布局

错误写法写成flex:33%

4.border渐变设置

5种CSS实现渐变色边框(Gradient borders方法的汇总5种方法实现渐变边框效果。icon-default.png?t=O83Ahttps://mp.weixin.qq.com/s?__biz=MjM5MDA2MTI1MA==&mid=2649115656&idx=2&sn=3e5739a25b4ba5e89529dac5590b7681&chksm=be586ba5892fe2b34d26580224acf7842a99a73d7ea87bcc33aa231238154685379e03df76e6&scene=27

   box-sizing: border-box;
        width: 330px;
        height: 36px;
        padding: 6px 12px 6px 12px;
        border-radius: 4px;
        border-width: 1px;
        border-style: solid;
        border-image-slice: 1; /* 添加这一行来定义边框图片的切片方式 */
        border-image-source: linear-gradient(90deg, #496987 0.48%, rgba(77, 118, 142, 0.3) 47.32%);
        background: linear-gradient(90deg, rgba(36, 76, 120, 0.05) 0%, rgba(36, 76, 120, 0.5) 100%);


在Vue中设置渐变边框,您已经正确地使用了border-image-source属性配合linear-gradient来创建渐变边框。您的代码片段展示了一个使用线性渐变作为边框图像的例子,这是实现边框渐变的标准方法。这里是对您代码的一个简单解析和确认:

.file-list-header {
  /* 其他样式属性... */
  border-width: 1px;
  border-style: solid;
  border-image-source: linear-gradient(90deg, #496987 0.48%, rgba(77, 118, 142, 0.3) 47.32%);
  /* 注意:为了使渐变边框生效,还需要定义border-image-slice、border-image-repeat等属性 */
}

注意事项:
border-image-slice: 这个属性定义了边框图片如何被分割。默认情况下,边框图片可能不会按预期显示,因为它需要被切片并拉伸以适应边框。通常,可以设置为border-image-slice: 1;来简化处理,表示从图片的边缘向内切割1单位的宽度来创建边框片段。

border-image-repeat: 控制边框图片的平铺方式,如stretch(拉伸以填充边框)、repeat(重复)、round(重复并根据需要调整图像的大小以适合边框的长度)等。默认值是stretch,通常对于渐变边框来说已经足够。

.file-list-header {
  /* 其他样式属性... */
  border-width: 1px;
  border-style: solid;
  border-image-source: linear-gradient(90deg, #496987 0.48%, rgba(77, 118, 142, 0.3) 47.32%);
  border-image-slice: 1; /* 添加这一行来定义边框图片的切片方式 */
  border-image-repeat: stretch; /* 添加这一行来控制边框图片的重复方式,可选,默认是stretch */
}

下面这种更有效:

 .border-box {
        width: 100px;
        height: 100px;
        border: 4px solid transparent;
        border-radius: 16px;
        background-clip: padding-box, border-box;
        background-origin: padding-box, border-box;
        background-image: linear-gradient(to right, #fff, #fff),
          linear-gradient(90deg, #8f41e9, #578aef);
      }

background-clip的应用:彩色文字

p {
  border: 0.8em darkviolet;
  border-style: dotted double;
  margin: 1em 0;
  padding: 1.4em;
  background: linear-gradient(60deg, red, yellow, red, yellow, red);
  font: 900 1.2em sans-serif;
  text-decoration: underline;
}

.border-box {
  background-clip: border-box;
}
.padding-box {
  background-clip: padding-box;
}
.content-box {
  background-clip: content-box;
}

.text {
  background-clip: text;//背景被裁剪成文字的前景色。
  -webkit-background-clip: text;
  color: rgba(0, 0, 0, 0.2);
}

 

5.svg经过变颜色

首先svg的fill属性设置为currentColor  ---fill="currentColor"

然后给svg的父级元素,或者本身设置color即可设置颜色

6.$event:实参

在vue中$event表示默认参数,例如:下拉菜单


//  等价于 @command="handleCommand($event)"

<el-dropdown @command="handleCommand">
  <span class="el-dropdown-link">
    下拉菜单<i class="el-icon-arrow-down el-icon--right"></i>
  </span>
  <el-dropdown-menu slot="dropdown">
    <el-dropdown-item command="a">黄金糕</el-dropdown-item>
    <el-dropdown-item command="b">狮子头</el-dropdown-item>
    <el-dropdown-item command="c">螺蛳粉</el-dropdown-item>
    <el-dropdown-item command="d" disabled>双皮奶</el-dropdown-item>
    <el-dropdown-item command="e" divided>蚵仔煎</el-dropdown-item>
  </el-dropdown-menu>
</el-dropdown>

<script>
  export default {
    methods: {
      handleCommand(command) {
        this.$message('click on item ' + command);
      }
    }
  }
</script>

因此如果想额外传值,则可以在括号后面他添加,来接受$event默认参数之外的其他参数

7.el-tree样式

//结构
   <el-tree
      :data="treeNodeArray"
      show-checkbox
      node-key="path"
      ref="tree"
      highlight-current
      :render-after-expand="false"
      :props="defaultProps"
      @check-change="handleCheckChange"
      @node-click="handleNodeClick"
      @node-contextmenu="handleRightClick"
      style="height: 100%"
      :filter-node-method="filterNode"
    >
      <template #default="{ node, data }">
        <slot :node="node" :data="data">
          <span class="custom-tree-node tree-node" :title="node.label">
            <span>{{ node.label }}</span>
            <div v-if="data.children.length > 0" class="child-total">{{ data.children.length }}</div>
          </span>
        </slot>
      </template>
    </el-tree>
//样式
::v-deep .el-tree {
  background-color: transparent;
  /* color: #fff; */
  color: #d1ebff;
  .el-tree-node {
    position: relative;
    .el-tree-node__content {
      padding-left: 0px !important ;
      background-color: transparent;
    }
    &.is-expanded:before {
      display: block;
      content: '';
      position: absolute;
      left: 11px;
      top: 25px;
      width: 1px;
      height: calc(100% - 30px);
      background: hsla(0, 0%, 100%, 0.5);
    }
    .el-tree-node__children .el-tree-node {
      width: calc(100% - 30px);
      margin-left: 30px;
      position: relative;
    }
  }
}

::v-deep .custom-tree-node {
  display: flex;
  width: calc(100% - 46px);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  span {
    display: inline-block;
    width: calc(100% - 40px);
    text-overflow: ellipsis;
    overflow: hidden;
    white-space: nowrap;
  }
  .child-total {
    color: #00c6ff;
    width: 16px;
    height: 16px;
    line-height: 16px;
    text-align: center;
    border-radius: 2px 2px 8px 2px;
    background: rgba(82, 184, 255, 0.2);
  }
}
::v-deep {
  .el-tree-node__content > label.el-checkbox {
    .el-checkbox__inner {
      background: transparent;
    }
  }
}
::v-deep .el-tree-node__content:hover {
  background-color: transparent;
}
::v-deep .el-tree--highlight-current .el-tree-node.is-current > .el-tree-node__content {
  background-color: transparent;
}

8.el-upload回显

拿到图片字符串地址,然后用fileList来回显

 this.fileList.push({ 
            name: this.projectData.projectImg.match(/\/([^/]+)$/)[1],
             url: this.projectData.projectImg      });

9.el-table样式改变 及 使用样式混入复用

  .facility-require {
    background-color: #0c1e35;
    ::v-deep .el-table {
      &::before {
        display: none;//去除table最底下的一条白色的线
      }
      .el-table__body-wrapper,
      .el-table__header-wrapper {
        table {
          thead {
            tr {
              .el-table__cell {
                padding: 6px 0;
                background-color: #0c1e35;
                &:not(:first-child) { //选中除了第一个
                  .cell {
                    border-left: 1px solid rgba(255, 255, 255, 0.1);
                  }
                }
                &:first-child {
                  .cell {
                    padding: 0 14px;
                  }
                }
              }
            }
          }

          tr {
            color: #fff;
            td {
              padding: 6px 0;
              background-color: #0c1e35;
              border-bottom: none;
              &:not(:first-child) {
                .cell {
                  border-left: 1px solid rgba(255, 255, 255, 0.1);
                }
              }
            }
            th {
              border-bottom: none;
            }
          }
        }
      }
    }
  }

样式混入复用写法

1.首先定义@mixin 样式名

    @mixin analysis-table {}

2.然后导入另一个样式文件中

    @import '~@/xxx/xxx/index.scss'

3.用@include 样式名;调用

  ::v-deep .el-table {
    @include analysis-table;
  }

 10.选中除了第一个的盒子的样式选择器

&:not(:first-child){}

11.菜单el-menu样式修改

el-menu 组件:导航菜单中箭头方向问题(对默认的上下进行样式的修改) - star-meteor - 博客园原先是element-ui中是默认上下 /*菜单打开*/ .el-submenu.is-opened>.el-submenu__title .el-submenu__icon-arrow { -webkit-transform: rotateZ(180deg); transform: rotaicon-default.png?t=O83Ahttps://www.cnblogs.com/star-meteor/p/12719089.htmlElement UI样式修改之NavMenu导航菜单箭头样式修改_element navmenu 导航菜单样式修改-CSDN博客文章浏览阅读772次。本文讲述了如何根据UI设计稿修改Element UI的NavMenu导航菜单的箭头样式,通过查找并替换字体图标内容,以及应用穿透样式来实现与设计稿一致的向下箭头效果。https://blog.csdn.net/qq_37635012/article/details/135847822

  //修改选中效果
  ::v-deep .el-menu-vertical-demo {
        position: relative;
        border: none;
        /*
        .el-submenu__title {
          background-color: transparent !important;
        }

        .el-menu-item {
          background-color: transparent !important;
        } */

        .el-menu-item::after {
          content: '';
          position: absolute;
          right: 0;
          top: 0;
          width: 2px;
          height: 100%;
        }

        .el-menu-item.is-active::after {
          background-color: #196cff;
        }
      }

      //修改箭头--ctrl+F12 找el-icon想要的content的值,进行覆盖 
      ::v-deep .el-submenu > .el-submenu__title .el-submenu__icon-arrow.el-icon-arrow-down::before {
        content: '\e790';
      }

      //菜单关闭
      ::v-deep .el-submenu > .el-submenu__title .el-submenu__icon-arrow {
        -webkit-transform: rotateZ(-90deg);
        -ms-transform: rotate(-90deg);
        transform: rotateZ(-90deg);
      }

      //菜单展开
      ::v-deep .el-submenu.is-opened > .el-submenu__title .el-submenu__icon-arrow {
        -webkit-transform: rotateZ(0deg);
        -ms-transform: rotate(0deg);
        transform: rotateZ(0deg);
      }

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值