Vue实现多标签选择器


Posted in Javascript onNovember 28, 2019

本文实例为大家分享了Vue实现多标签选择器展示的具体代码,供大家参考,具体内容如下

实现效果

Vue实现多标签选择器

实现代码

<html lang="en">

<head>
 <title>Document</title>

 <!-- 引入本地组件库 -->
 <link rel="stylesheet" href="static/element-ui/index.css" >
 <script src="static/element-ui/vue.js"></script>
 <script src="static/element-ui/index.js"></script>

 <!-- 引入CDN样式 -->
 <!-- <link rel="stylesheet" href="https://unpkg.com/element-ui/lib/theme-chalk/index.css" > -->
 <!-- <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script> -->
 <!-- <script src="https://unpkg.com/element-ui/lib/index.js"></script> -->

 <style>
  .not-active {
   display: inline-block;
   font-size: 12px;
   margin: 5px 8px;
  }
  
  span {
   margin: 0 2px;
  }
 </style>
</head>

<body>

 <div id="app">
  <!-- 待选标签 -->
  <div v-for='(category, categoryIndex) in categories' :key="category.id">
   <!-- 分类 -->
   <span class="not-active">{{category.name}}:</span>

   <template>
    <span v-if="category.count"class="not-active" @click="clearCategory(category, categoryIndex)"> 不限</span>
    <my-tag v-else>不限</my-tag>
   </template>

   <!-- 标签 -->
   <template v-for='(child, childIndex) in category.children'>
    <my-tag v-if="child.active" :closable='true' @click-child='clickChild(category, categoryIndex, child, childIndex)'>
     {{ child.name }}
    </my-tag>
    <span v-else class="not-active" @click='clickChild(category, categoryIndex, child, childIndex)'>{{ child.name }}</span>
   </template>
  </div>

  <!-- 已选标签 -->
  <div v-if='conditions.length'>
   <span class="not-active" @click="clearCondition">清空已选:<span>
    
   <el-tag
   v-for='(condition, index) in conditions' 
   :key="condition.id"
   type="primary"
   :closable="true"
   size="small"
   :disable-transitions="true"
   @close='removeCondition(condition, index)'
   @click='removeCondition(condition, index)'>
    {{condition.name}}
   </el-tag>
  </div>
 </div>

 <script src="./data.js"></script>

 <script>
  // 简单封装一个公用组件
  Vue.component('my-tag', {
   template: "<el-tag v-bind='$attrs' v-on='$listeners' effect='dark' size='small' :disable-transitions='true' @click='clickChild' @close='clickChild'><slot></slot></el-tag>",

   methods: {
    clickChild() {
     this.$emit("click-child")
    }
   }
  });

  var app = new Vue({
   el: '#app',
   data() {
    return {
     categories, // 分类标签,可从外部加载配置
     conditions: [] // 已选条件
    }
   },

   watch: {
    // 监听条件变化,按照请求接口拼装请求参数
    conditions(val){
     let selectedCondition = {};

     for(let categorie of this.categories){
      let selected_list = [];
      for(let child of categorie.children){
       if(child.active){
        selected_list.push(child.name);
       }
      }
      selectedCondition[categorie.name] = selected_list.join("|")
     }
     console.log(selectedCondition);
    }
   },

   methods: {
    // 处理标签点击事件,未选中则选中,已选中则取消选中
    clickChild(category, categoryIndex, child, childIndex) {
     let uid = `${categoryIndex}-${childIndex}`
     child.uid = uid;
     console.log(uid)
     
     // 取消选择
     if (child.active === true) {
      category.count--;
      child.active = false;
      this.conditions.forEach((conditionChild, index) => {
       if (conditionChild.uid === child.uid) {
        this.conditions.splice(index, 1);
       }
      });
     // 选择
     } else {
      category.count++;
      child.active = true;
      this.conditions.push(child);
     }
    },
   
    // 清除已选整个类别标签
    clearCategory(category, categoryIndex) {
     category.count = 0;
     
     // 可选列表均为未选中状态
     category.children.forEach(child => {
      child.active = false;
     })

     // 清空该类已选元素
     for (let index = this.conditions.length - 1; index >= 0; index--) {
      const conditionChild = this.conditions[index];
      if (conditionChild.uid.startsWith(categoryIndex)) {
       this.conditions.splice(index, 1);
      }
     }
    },
    
    // 移除一个条件
    removeCondition(condition, index) {
     let categoryIndex = condition.uid.split("-")[0];
     this.categories[categoryIndex].count --;

     this.conditions.splice(index, 1)
     condition.active = false;
    },

    // 清空所有条件
    clearCondition() {
     for(let i = this.conditions.length-1; i >=0 ; i--){
      this.removeCondition(this.conditions[i], i);
     }
    }
   }
  });
 </script>

</body>

</html>

标签筛选的数据格式

data.js

var categories = [{
 name: '品牌',
 count: 0,
 children: [{
  name: '联想',
 }, {
  name: '小米',

 }, {
  name: '苹果',

 }, {
  name: '东芝',

 }]
}, {
 name: 'CPU',
 count: 0,
 children: [{
  name: 'intel i7 8700K',

 }, {
  name: 'intel i7 7700K',

 }, {
  name: 'intel i9 9270K',

 }, {
  name: 'intel i7 8700',

 }, {
  name: 'AMD 1600X',


 }]
}, {
 name: '内存',
 count: 0,
 children: [{
  name: '七彩虹8G',

 }, {
  name: '七彩虹16G',

 }, {
  name: '金士顿8G',

 }, {
  name: '金士顿16G',

 }]
}, {
 name: '显卡',
 count: 0,
 children: [{
  name: 'NVIDIA 1060 8G',

 }, {
  name: 'NVIDIA 1080Ti 16G',

 }, {
  name: 'NVIDIA 1080 8G',

 }, {
  name: 'NVIDIA 1060Ti 16G',

 }]
}]

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
jquery 锁定弹出层实现代码
Feb 23 Javascript
Extjs优化(二)Form表单提交通用实现
Apr 15 Javascript
JavaScript中的字符串操作详解
Nov 12 Javascript
JavaScript实现大数的运算
Nov 24 Javascript
jquery实现选中单选按钮下拉伸缩效果
Aug 06 Javascript
浅谈Javascript中的12种DOM节点类型
Aug 19 Javascript
关于js二维数组和多维数组的定义声明(详解)
Oct 02 Javascript
jQuery中table数据的值拷贝和拆分
Mar 19 Javascript
element UI upload组件上传附件格式限制方法
Sep 04 Javascript
Mint UI实现A-Z字母排序的城市选择列表
Dec 28 Javascript
Vue使用JSEncrypt实现rsa加密及挂载方法
Feb 07 Javascript
详解如何修改 node_modules 里的文件
May 22 Javascript
swiper实现异形轮播效果
Nov 28 #Javascript
Vue请求java服务端并返回数据代码实例
Nov 28 #Javascript
javascript实现异形滚动轮播
Nov 28 #Javascript
javascript实现切割轮播效果
Nov 28 #Javascript
javascript实现商品图片放大镜
Nov 28 #Javascript
javascript实现视频弹幕效果(两个版本)
Nov 28 #Javascript
javascript实现弹幕墙效果
Nov 28 #Javascript
You might like
php中global和$GLOBALS[]的分析之一
2012/02/02 PHP
PHP读取文本文件并逐行输出该行使用最多的字符与对应次数的方法
2016/11/25 PHP
php pdo操作数据库示例
2017/03/10 PHP
关于PHP定时发送服务的解决办法
2017/04/23 PHP
Javascript 个人笔记(没有整理,很乱)
2007/07/07 Javascript
extjs fckeditor集成代码
2009/05/10 Javascript
使用js检测浏览器的实现代码
2013/05/14 Javascript
js给onclick赋值传参数的两种方法
2013/11/25 Javascript
javaScript中的this示例学习详解及工作原理
2014/01/13 Javascript
JS多物体实现缓冲运动效果示例
2016/12/20 Javascript
js 转义字符及URI编码详解
2017/02/28 Javascript
JS触摸事件、手势事件详解
2017/05/04 Javascript
React Native如何消除启动时白屏的方法
2017/08/08 Javascript
jQuery动态操作表单示例【基于table表格】
2018/12/06 jQuery
Vue+abp微信扫码登录的实现代码示例
2020/01/06 Javascript
Openlayers学习之加载鹰眼控件
2020/09/28 Javascript
[02:51]DOTA2英雄基础教程 艾欧
2014/01/13 DOTA
[50:27]OG vs LGD 2018国际邀请赛淘汰赛BO3 第一场 8.26
2018/08/30 DOTA
在Django的模型和公用函数中使用惰性翻译对象
2015/07/27 Python
详解python里的命名规范
2018/07/16 Python
关于python列表增加元素的三种操作方法
2018/08/22 Python
python计算阶乘和的方法(1!+2!+3!+...+n!)
2019/02/01 Python
python中的colorlog库使用详解
2019/07/05 Python
PyQt5实现简单的计算器
2020/05/30 Python
css3和jquery实现自定义checkbox和radiobox组件
2014/04/22 HTML / CSS
英国可持续奢侈品包包品牌:Elvis & Kresse
2018/08/05 全球购物
华纳兄弟工作室的官方授权商店:WB Shop
2018/11/30 全球购物
OnePlus加拿大官网:中国国际化手机品牌
2020/10/13 全球购物
教师岗位职责范本
2013/12/29 职场文书
三个儿子教学反思
2014/02/03 职场文书
幼儿园大班毕业感言
2014/02/06 职场文书
大学生村官承诺书
2014/03/28 职场文书
2014年个人思想工作总结
2014/11/27 职场文书
民间借贷借条范本
2015/05/25 职场文书
如何起草一份正确的合伙创业协议书?
2019/07/04 职场文书
Python requests用法和django后台处理详解
2022/03/19 Python