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 相关文章推荐
二级域名转向类
Nov 09 Javascript
javascript英文日期(有时间)选择器
May 02 Javascript
javascript中的关于类型转换的性能优化
Dec 14 Javascript
javascript实现动态模态绑定grid过程代码
Sep 22 Javascript
JavaScript判断数组是否存在key的简单实例
Aug 03 Javascript
js 递归和定时器的实例解析
Feb 03 Javascript
Vue.js最佳实践(五招助你成为vuejs大师)
May 04 Javascript
CKEditor4配置与开发详细中文说明文档
Oct 08 Javascript
setTimeout与setInterval的区别浅析
Mar 23 Javascript
详解Vue中的基本语法和常用指令
Jul 23 Javascript
vue - props 声明数组和对象操作
Jul 30 Javascript
如何在JS文件中获取Vue组件
Sep 16 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导入导出CSV文件
2014/11/03 PHP
PHP打开和关闭文件操作函数总结
2014/11/18 PHP
discuz目录文件资料汇总
2014/12/30 PHP
PHP多维数组转一维数组的简单实现方法
2015/12/23 PHP
PHP实现可精确验证身份证号码的工具类示例
2018/05/31 PHP
php实现生成PDF文件的方法示例【基于FPDF类库】
2018/07/21 PHP
jQuery对象和DOM对象使用说明
2010/06/25 Javascript
jquery阻止冒泡事件使用模拟事件
2013/09/06 Javascript
一个html5播放视频的video控件只支持android的默认格式mp4和3gp
2014/05/08 Javascript
Three.js学习之几何形状
2016/08/01 Javascript
Node.js + Redis Sorted Set实现任务队列
2016/09/19 Javascript
Mac下使用charles遇到的问题以及解决办法
2017/01/10 Javascript
JavaScript 总结几个提高性能知识点(推荐)
2017/02/20 Javascript
详解vue-router 2.0 常用基础知识点之router.push()
2017/05/10 Javascript
Express进阶之log4js实用入门指南
2018/02/10 Javascript
vue通过cookie获取用户登录信息的思路详解
2018/10/30 Javascript
Vue.js桌面端自定义滚动条组件之美化滚动条VScroll
2020/12/01 Vue.js
vue3.0+vue-router+element-plus初实践
2020/12/02 Vue.js
[05:03]2018DOTA2亚洲邀请赛主赛事首日回顾
2018/04/04 DOTA
自己编程中遇到的Python错误和解决方法汇总整理
2015/06/03 Python
python中正则表达式与模式匹配
2019/05/07 Python
详解PyQt5信号与槽的几种高级玩法
2020/03/24 Python
flask项目集成swagger的方法
2020/12/09 Python
CSS3使用border-radius属性制作圆角
2014/12/22 HTML / CSS
美国著名童装品牌:OshKosh B’gosh
2016/08/05 全球购物
NIHAOMARKET官方海外旗舰店:意大利你好华人超市
2018/01/27 全球购物
大学教师年终总结的自我评价
2013/10/29 职场文书
测试工程师岗位职责
2013/11/28 职场文书
电脑教师的自我评价
2013/12/18 职场文书
大众服装店创业计划书范文
2014/01/01 职场文书
乔迁宴答谢词
2014/01/21 职场文书
2014年大学生党课心得体会范文
2014/03/29 职场文书
自书遗嘱范文
2015/08/07 职场文书
Ruby GDBM操作简介及数据存储原理
2022/04/19 Ruby
单机多实例部署 MySQL8.0.20
2022/05/15 MySQL
Python docx库删除复制paragraph及行高设置图片插入示例
2022/07/23 Python