【问题总结(12)】Cascader 省市区联动 obj[] Object.key() some.() String() forEach() 数组筛选过滤filter

1.obj[]
对象没有obj[0],这是数组的表达法arr[]. 数组有内置索引,对象没有,obj[] 里是key(键名)
下面展示一些

// An highlighted block
const animalData = {
  '猫': ['波斯', '缅因', '布偶', '暹罗', '英短'],
  '狗': ['萨摩耶', '柴犬', '柯基', '松狮', '拉布拉多']
}
for (const n in animalData) {
  console.log(animalData[n])// ['波斯', '缅因', '布偶', '暹罗', '英短'] ['萨摩耶', '柴犬', '柯基', '松狮', '拉布拉多'] 
}
当遍历这个对象时,遍历的值相当于索引但是不是索引,而是所有key的名字,最后通过obj[n]拿到遍历的所有的key对应的value

参考: obj[n]与obj[“n”].
待敲: obj[key],ojb[‘key’]和obj.key.

由此受启发 理解antd的代码

// An highlighted block
const obj = {: ['波斯', '缅因', '布偶', '暹罗', '英短'],: ['萨摩耶', '柴犬', '柯基', '松狮', '拉布拉多'] }
// for (const n in obj) {
//   console.log(obj[n])
// }
console.log(obj[0])
console.log(obj[0][0])
obj[0] undefined  ``
obj[猫] 变量名会报错
obj['猫'] 得到 ['波斯', '缅因', '布偶', '暹罗', '英短'],  相应的 ,obj里key的名如果是汉字或者字母要用` ''  `单引号括起来

链接: link.

2.数组与对象
下面展示一些 内联代码片

// An highlighted block
const groupData = ['猫', '狗']
console.log(groupData[0])// 猫
const animalData = {
  '猫': ['波斯', '缅因', '布偶', '暹罗', '英短'],
  '狗': ['萨摩耶', '柴犬', '柯基', '松狮', '拉布拉多']
}
console.log(animalData[groupData[0]])// ['波斯', '缅因', '布偶', '暹罗', '英短'] 猫是 key键名
console.log(animalData[groupData[0]][0])// 波斯 
groupData[index] => animalData[key] 数组的value 与对象的key相同 是一个接口  实现级联
groupData[0] => animalData['猫']

JS数组

链接: JS数组方法总结大全
.

对象 ES6

下面展示一些 内联代码片

// An highlighted block
const testData = [
  { id: '1', name: '可莉', province: '310000', city: '310100', area: '310107', group: '猫', animal: '1' },
  { id: '2', name: '枫原万叶', province: '310000', city: '310100', area: '310115', group: '狗', animal: '1' },
  { id: '3', name: '德莉傻', province: '320000', city: '320100', area: '320113', group: '猫', animal: '2' },
  { id: '4', name: '舰长', province: '320000', city: '321300', area: '321323', group: '狗', animal: '2' },
  { id: '5', name: '八重樱', province: '320000', city: '320100', area: '320102', group: '猫', animal: '4' }
]
console.log(testData)
// 获取ID集合
 const res =  animalParams () { //报错
  let animalID = '' // 品种ID集合
  this.testData.map((item) => {
    animalID += item.id + ','
  })
  return animalID
}
如果要写成 对象形式, 要用ES6写法 不用function 写成对象形式

this

下面展示一些 内联代码片

// A code block
var foo = 'bar';
// An highlighted block
const testData = [
  { id: '1', name: '可莉', province: '310000', city: '310100', area: '310107', group: '猫', animal: '1' },
  { id: '2', name: '枫原万叶', province: '310000', city: '310100', area: '310115', group: '狗', animal: '1' },
  { id: '3', name: '德莉傻', province: '320000', city: '320100', area: '320113', group: '猫', animal: '2' },
  { id: '4', name: '舰长', province: '320000', city: '321300', area: '321323', group: '狗', animal: '2' },
  { id: '5', name: '八重樱', province: '320000', city: '320100', area: '320102', group: '猫', animal: '4' }
]
console.log(testData)
// 获取ID集合
 function animalParams () {
  let animalID = '' // 品种ID集合
  this.testData.map((item) => { //报错位置
    animalID += item.id + ','
  })
  return animalID
}
// animalParams()
console.log(animalParams())

报错
在这里插入图片描述
原因
这个demo是直接写在script标签里面的,并没有放在vue的export里面。this.testData.map 不用加 this
如果这个animalParams放到methods里,要加this

改正

// An highlighted block
testData.map((item) => .....

函数调用

在上面的例子中,想拿到animalID

// An highlighted block
........
 return animalID
}
console.log(animalParams) // 没有调用
console.log(animalID) // 报错

在这里插入图片描述

原因: 因为函数没有执行 

改正

// An highlighted block
console.log(animalParams())
animalParams() 意思是执行 拿到return animalID的值 

方法OR函数

str.toLowerCase()
将调用该方法的字符串值转为小写形式,并返回。toLowerCase 不会影响字符串本身的值。
Object.keys()
参数: obj 要返回其枚举自身属性的对象。
返回值:一个表示给定对象的所有可枚举属性的字符串数组。

// An highlighted block
var anObj = { 100: 'a', 2: 'b', 7: 'c' };
console.log(Object.keys(anObj)); // console: ['2', '7', '100']

JavaScript String() 函数
语法:String(object)
定义和用法: String() 函数把对象的值转换为字符串。

Array.prototype.some()
描述:some() 为数组中的每一个元素执行一次 callback 函数,直到找到一个使得 callback 返回一个“真值”(即可转换为布尔值 true 的值)。如果找到了这样一个值,some() 将会立即返回 true。否则,some() 返回 false。callback 只会在那些”有值“的索引上被调用,不会在那些被删除或从来未被赋值的索引上调用。
链接: some().
其余不放链接了,自己搜吧 乐趣多多 肯定会有意想不到的收获

没看懂

以上几种方法连用
// An highlighted block
computed: {
    searchData: function() {
      var search = this.search;
 
      if (search) {
        return this.products.filter(function(product) {
          return Object.keys(product).some(function(key) {
            return String(product[key]).toLowerCase().indexOf(search) > -1
          })
        })
      }
 
      return this.products;
    }
  }
})

————————————————
版权声明:本文为CSDN博主「Jarvan大熊」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/dx18520548758/article/details/80109038

forEach()
描述 按升序为数组中含有效值的每一项执行一次 callback 函数, callback 函数就是执行体里给定的函数。

过滤

第一类 原生js

  1. 条件判断
// A code block
var foo = 'bar';
// An highlighted block
<div id="div">  
<li v-for="n in evenNumbers">{{ n }}</li>
</div>
 
<script>
varvm=new Vue({
el:"#div",
data:{
  numbers: [ 1, 2, 3, 4, 5 ]
},
computed:{
  evenNumbers: function () {
    return this.numbers.filter(function (number) 
	{
      return number<4   //原生js 
    })
  }
}
})
 
</script>
————————————————
版权来自:本文为CSDN博主「灵灵7」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/weixin_41796631/article/details/82924451

example 2
链接: 数组——筛选数组.
2. map遍历

vue 对象数组筛选(根据对象属性名获取属性值)
// 数据源
tripData=[{"ID":1,"票号":"104-0000000001","订单编号":"1326011"},
{"ID":2,"票号":"104-0000000002","订单编号":"1326012"},
{"ID":3,"票号":"104-0000000003","订单编号":"1326013"}]

//方法体
//获取ID集合
TicketParams () { 
    var vTicketID = "";//票号ID集合
    this.tripData.map((item) => {
    vTicketID += item.ID + ",";
    })
    return vTicketID;//1,2,3
}

3.箭头函数
下面展示一些 内联代码片

// A code block
var foo = 'bar';
// An highlighted block
                    for(let i = 0;i < tableData.length;i++){
                        this.tableData[i] = tableData.filter(obj => obj.postLevel == (i + 1));
                    }

4.几种JS方法
待敲

// A code block
var foo = 'bar';
// script
var vm = new Vue({
  el: '#app',
  data: {
    search: '',
    products: [{
      name: '苹果',
      price: 25,
      category: "水果"
    }, {
      name: '香蕉',
      price: 15,
      category: "水果"
    }, {
      name: '雪梨',
      price: 65,
      category: "水果"
    }, {
      name: '宝马',
      price: 2500,
      category: "汽车"
    }, {
      name: '奔驰',
      price: 10025,
      category: "汽车"
    }, {
      name: '柑橘',
      price: 15,
      category: "水果"
    }, {
      name: '奥迪',
      price: 25,
      category: "汽车"
    }]
  },
  computed: {
    searchData: function() {
      var search = this.search;
 
      if (search) {
        return this.products.filter(function(product) {
          return Object.keys(product).some(function(key) {
            return String(product[key]).toLowerCase().indexOf(search) > -1
          })
        })
      }
 
      return this.products;
    }
  }
})

//html
<div id="app">
  <input v-model='search' />
  <ul v-if="searchData.length > 0">
    <li v-for="item in searchData">{{item.name}},价格:{{item.price}}</li>
  </ul>
  <div v-else>暂无数据</div>
</div>
  1. 参考性极强
methods showOrder里和二次录入taskList相似
// An highlighted block
<template>
  <div class="maincont">
    <header>
      <a href="javascript:history.back(-1)" class="back-off fl"><span class="glyphicon glyphicon-menu-left"></span></a>
      <div class="head-mid">
        <form action="#" method="get" class="prosearch"><input type="text" /></form>
      </div>
    </header>
    <ul class="pro-select">
      <li :class="{'pro-selCur':order_type==1}">
        <a href="javascript:;" @click="showOrder(1)" >新品</a>
      </li>
      <li :class="{'pro-selCur':order_type==2}">
        <a href="javascript:;" @click="showOrder(2)">销量</a>
      </li>
      <li :class="{'pro-selCur':order_type==3}">
        <a href="javascript:;" @click="showOrder(3)">价格</a>
      </li>
    </ul><!--pro-select/-->
    <div class="prolist">
      <dl v-for=" (v,k) in goodsList">
        <dt>
          <router-link :to="{name:'GoodsDetail',query:{goods_id:v.goods_id}}">
            <img :src="v.goods_goods_img" width="100" height="100" />
          </router-link>
        </dt>
        <dd>
          <h3>
            <router-link :to="{name:'GoodsDetail',query:{goods_id:v.goods_id}}">
              {{v.goods_name}}
            </router-link>
          </h3>
          <div class="prolist-price"><strong>¥{{v.goods_selfprice}}</strong> <span>¥{{v.goods_marketprice}}</span></div>
          <div class="prolist-yishou"><span>{{v.discount}}</span> <em>已售:{{v.sale_number}}</em></div>
        </dd>
        <div class="clearfix"></div>
      </dl>

    </div><!--prolist/-->
    <button  v-if="has_more == 1" @click="loadMore">点击加载更多</button>
    <button class="nodata" v-else>我也是底限的。。。。</button>
    <div class="height1"></div>
    <tab-bar></tab-bar>
  </div><!--maincont-->

</template>
<script>
import  "@/assets/css/bootstrap.min.css"
import  "@/assets/css/style.css"
import  "@/assets/css/response.css"
import  "@/assets/js/jquery.min.js"
import  "@/assets/js/jquery.excoloSlider.js"
import  "@/assets/js/style.js"
import TabBar from "./Public/TabBar";
import Common from "../Mixins/Common";
import Index from "./Index";
export default {
  name: 'Reg',
  components: { TabBar:TabBar},
  mixins:[ Common ],
  data () {
    return {
      goodsList: [],
      page:1,
      has_more:1,
      order_type:1
    }
  },
  methods:{
    showOrder : function( order_type ){
      this.order_type = order_type;
      this.page = 1;
      this.getGoodsList();
    },
    loadMore: function () {
      this.getGoodsList( this.page);
    },
    getGoodsList:function ( ) {
      let api_req = {
        page:this.page,
        order_type:this.order_type
      };
      console.log( api_req);
      this.$http.post('api/getProductList', api_req ).then( (response) =>{
        if( response.body.status == 200 ){
          if( this.page == 1 ){
            this.goodsList = response.body.data.data;
          }else{
            this.goodsList =  this.goodsList.concat(response.body.data.data);
          }
          if( response.body.data.data.length < 10  ){
            this.has_more = 0;
          }
          this.page++;
        }
      },(error) => {
        alert(error);
      })
    }
  },
  watch:{
    goodsList:function ( val ) {
      console.log( val );
      for ( let i  in val  ){
        //parseFloat 转成Float类型,toFixex 保留2位小数
        this.goodsList[i].discount =  parseFloat( val[i].goods_selfprice  /  val[i].goods_marketprice  ).toFixed(2)*10;
      }
    }
  },
  mounted(){
    this.getGoodsList();
  }
}

</script>

<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>

button{
  margin-top: 5px;
  border: 0;
  width: 100%;
  background-color: rgba(0, 161, 255, 0.29);
}
.nodata{
  color: #cccccc;
  background-color:#3c763d;
}
</style>




参考: vue-实现商品列表(列表+刷新+筛选).
6.input筛选
待敲

v_tableList: 列表需要的数据
v_filterKeyword: 搜索框双向绑定的key
v_detailList: 后台拿的数据
// An highlighted block
computed: {
    v_tableList () {
      if (this.v_filterKeyword !== '') {
        let keyword = this.v_filterKeyword.toLowerCase()
        return this.v_detailList.filter(item => {
          // 以name来搜索
          let str = item.name.toLowerCase()
          return str.indexOf(keyword) !== -1
        })
      } else {
        return this.v_detailList || []
      }
    }
  }

参考: vue 实现数组筛选功能 filter过滤.
7.多条件筛选
下面展示一些 内联代码片

搜索条件要绑定的数据
// An highlighted block
filterForm:{
	schoolName:'',//输入的学校名称
	position:'',//选择的区域区域
	schoolLevel:"",//选择的学校办别
},
schoolList:[
	{schoolName:'青岛市实验高级中学',schoolLevel:"",position:'山东省青岛市城阳区硕阳路69号'},
	{schoolName:'山东省青岛第二中学',schoolLevel:"",position:'山东省青岛市崂山区松岭路70号'},
	{schoolName:'山东省青岛第一中学',schoolLevel:"",position:'山东省青岛市市南区单县路46号'},
	{schoolName:'山东省青岛第三十九中学',schoolLevel:"",position:'市南区登州路5号'},
	{schoolName:'山东省青岛第六中学',schoolLevel:"",position:'山东省青岛市黄岛区云台山路66号'},
	{schoolName:'山东省青岛第十九中学',schoolLevel:"",position:'山东省青岛市即墨区鳌山卫街道卫场路69号'},
	{schoolName:'青岛艺术学校',schoolLevel:"",position:'青岛市李沧区九水路176号'},
	{schoolName:'山东省青岛第九中学',schoolLevel:"",position:'山东省青岛市黄岛区七星河路559号'},
	{schoolName:'青岛电子学校',schoolLevel:"",position:'山东省青岛市市北区台东一路118号'}
],//其中schoolList是元数据
resull:[]//搜索结果,也是列表循环的数据

监听
// An highlighted block
watch: {
	// 监听对象变化
	filterForm:{
		handler(val, oldVal){
			if(val){
				// 如果筛选条件全为空,查全部;否则按条件筛选
				var objIsEmpty = this.filterForm.schoolName == '' && this.filterForm.schoolLevel == '' && this.filterForm.position == ''
				if(objIsEmpty){
					this.result = this.schoolList
				} else {
					// /拿到有值的参数
					let tempFilter = {};
					for(var key in this.filterForm) {
						if(typeof(this.filterForm[key]) != "undefined" && typeof(this.filterForm[key]) != "null" && this.filterForm[key] != null && this.filterForm[key] != "") {
							tempFilter[key] = this.filterForm[key];
						}
					}
					// console.log(tempFilter,'输出tempFilter')
					this.result = this.schoolList.filter(
						//筛选
						(item) => {
							let flag = false;
							for(key in tempFilter) {
								console.log(key,'输出key')
									if(item[key].toString().indexOf(tempFilter[key].toString()) >= 0) {
										flag = true;
									} else {
                                        flag = false;
                                        break;
                                    }
                                }
                                if(flag) {
                                    return item;
                                }
                            }
                        );
                        console.log(this.result,'输出筛选结果')
                    }
                }
            },
            deep:true
        }
}

参考: vue中优雅的实现前端列表多条件筛选
.

7.表头查询过滤
链接: Antd的table筛选,表头columns的filters过滤清空
.
8. 参考性极强

下面展示一些 内联代码片

根据第一个控件所选项确定第二个控件下拉内容的对象数组,并使默认为第一个数组项(就是这个)
// An highlighted block
    change1: function (val) {
      if (val) {
        this.selectData.com2 = this.optionData.com2[val][0].value; //根据第一个控件所选项确定第二个控件下拉内容的对象数组,并使默认为第一个数组项
        this.change2(); //控件2手动改变时会自动触发该方法,但是被动改变时不会触发,所以手动加上去
      } else {
        this.selectData.com2 = ""; //若前一个控件清空则后一个控件所选内容也清空
        this.change2();
      }
    },
    change2: function () {
      var val = this.selectData.com2;
      if (val) {
        this.selectData.com3 = this.optionData.com3[val][0].value;
      } else {
        this.selectData.com3 = "";
      }
    },

参考: vue+elementui–el-select控件实现三级联动
.

9.看过滤部份找灵感
下面展示一些 内联代码片

  item一般用作对象的元素,element为key对应的value      length的用法
// An highlighted block
 if(this.tableData.length > 0) {
	         this.value1.forEach(element =>{
	           this.tableData.forEach((item,index) =>{
	             if(element == item.value) {
	                this.tableData.splice(index,1);
	              }
	           })
	         })
	       }
————————————————
版权声明:本文为CSDN博主「时光回溯」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/qq_43729779/article/details/103479331

10.敲代码找灵感
下面展示一些 内联代码片

// A code block
var foo = 'bar';
// An highlighted block
<template>
  <div class="filter-more">
    <div style="width: 100%; min-height: 50px; background: #f9f9fc">
      <a href="#" style="color: #9babc5" class="text-select">筛选结果(125</a>
      <a
        href="#"
        v-for="(item, index) in selectBox"
        class="text-select"
        :key="index"
      >
        {{ item.text }}
        <i @click="removeCurrentSelect(index,item)">&times;</i>
      </a>
      <a href="#" style="color: #9babc5" @click="clearAll" class="text-select"
        >清除筛选结果</a
      >
    </div>
    <transition name="selectbox">
      <div class="box" v-show="boxshow">
        <div class="items" v-for="(item, index) in filterBox" :key="index">
          <i-col class="title" span="2">{{ item.name }}</i-col>
          <i-col span="22">
            <a
              href="#"
              v-for="(v, i) in item.items"
              :key="i"
              @click="clickrange(index, v, i)"
              class="text-filter"
            >
              <span :class="{ isActive: v.active }">{{ v.text }}</span>
              <i
                v-if="v.active && item.name != '文件类型:'"
                @click.stop="detail"
                class="el-icon-circle-plus"
              />
            </a>
          </i-col>
        </div>
        <div class="items">
          <i-col class="title" span="2">日期:</i-col>
          <el-date-picker
            v-model="value1"
            type="daterange"
            value-format="yyyy-MM-dd"
            range-separator="至"
            start-placeholder="开始日期"
            end-placeholder="结束日期"
          >
          </el-date-picker>
        </div>
      </div>
    </transition>
  </div>
</template>

<script>
export default {
  name: "筛选组件",
  props: {
    expand: true,
  },
  watch: {
    expand: {
      handler(n) {
        this.boxshow = n;
      },
      deep: true,
    },
    value1: {
      handler(n) {
        if (n != "") {
          this.time = n[0] + "至" + n[1];
          this.selectBox.unshift({
            value: "0",
            text: this.time,
            active: false,
          });
        }
      },
    },
  },
  data() {
    return {
      boxshow: false,
      btnTxt: false,
      selectBox: [],
      time: "",
      filterBox: [
        {
          name: "类别:",
          items: [
            { value: "1", text: "全部", active: false },
            { value: "2", text: "物理印章", active: false },
            { value: "3", text: "电子印章", active: false },
          ],
        },
        {
          name: "印章类型:",
          items: [
            { value: "allAge", text: "全部", active: false },
            { value: "treeY", text: "公章", active: false },
            { value: "fourteenY", text: "财务章", active: false },
            { value: "fortyY", text: "合同章", active: false },
          ],
        },
        {
          name: "文件类型:",
          items: [
            { value: "allSex", text: "全部", active: false },
            { value: "man", text: "合同", active: false },
            { value: "women", text: "发票", active: false },
            { value: "unknow", text: "普通文件", active: false },
          ],
        },
        {
          name: "部门:",
          items: [
            { value: "1", text: "全部", active: false },
            { value: "2", text: "财务部", active: false },
            { value: "3", text: "法务部", active: false },
            { value: "4", text: "行政部", active: false },
          ],
        },
      ],
      value1: "",
    };
  },
  methods: {
    togglebox: function () {
      this.boxshow = this.props.expand;
    },
    clickrange(parentIndex, el, childIndex) {
      var item = this.filterBox[parentIndex].items;
      console.log("选中了之前", this.selectBox);
      item.filter((v, i) => {
        if (i === childIndex) {
          v.active = !v.active; // 选中和反选
          console.log("选中了之前", this.selectBox);
          this.selectBox.unshift(v); // 选中的数组
          console.log("选中了", this.selectBox);
        } else {
          // v.active = false; // 取消选中,实现一行只选一个就放开此段代码
          this.selectBox.filter((childEl, childI) => {
            if (childEl.active === false) {
              this.selectBox.splice(childI, 1); // 反选删除数组中的当前个
            }
          });
        }
      });
      if (this.time != "") {
        this.selectBox.unshift({ value: "0", text: this.time, active: false });
      }
    },
    removeCurrentSelect(index,item) {
        // 如果是time,就先清空
        if(item.value==0){
          this.time=''
          this.value1=''
        }
      this.filterBox.filter((el, i) => {
        el.items.filter((data, childIndex) => {
          if (data.text == this.selectBox[index].text) {
            data.active = false;
          }
        });
      });
      this.selectBox.splice(index, 1);
      
    },
    // 清空所有的选项
    clearAll() {
      this.selectBox.filter((childEl, childI) => {
        childEl.active = false;
      });
      this.selectBox = [];
      this.time = "";
      this.value1 = "";
    },
    detail() {
      console.log("21312312");
    },
  },
};
</script>

<style lang="scss" scoped>
.filter-more {
  width: 100%;
  font-size: 14px;
  margin: 0 auto;
  border: 1px solid #e8f4fd;
  //   padding: 25px 15px;
}
.box {
  //   height: 400px;
  overflow: hidden;
  color: $gray;
  .items {
    height: 50px;
    width: 95%;
    margin-left: 3%;
    display: flex;

    align-items: center;
    .title {
      width: 100px;
      color: $blank;
    }
  }
}
.text-toggle {
  text-align: center;
  cursor: pointer;
}
.selectbox-leave-active,
.selectbox-enter-active {
  transition: all 1s ease;
}
.selectbox-leave-active,
.selectbox-enter {
  height: 0px !important;
}
.selectbox-leave,
.selectbox-enter-active {
  height: 150px;
}
.text-filter {
  display: inline-block;
  color: $gray;
  width: 80px;
  span {
    display: inline-block;
    text-align: center;
    // width: 60px;
    &:hover {
      border-radius: 40px;
      color: #ffffff;
      animation: myfirst 1s;
      -moz-animation: myfirst 1s; /* Firefox */
      -webkit-animation: myfirst 1s; /* Safari and Chrome */
      -o-animation: myfirst 1s; /* Opera */
      animation-fill-mode: forwards;
    }
  }
  .el-icon-circle-plus {
    color: $red;
    padding-left: 3px;
  }
}
.text-select {
  display: inline-block;
  padding: 0px 5px;
  border: none;
  border-radius: 40px;
  color: $red;
  font-size: 14px;
  padding: 20px;
  i {
    display: inline-block;
    height: 100%;
    font-size: 15px;
    padding: 0px 5px;
  }
}
.isActive {
  border-radius: 40px;
  color: $red;
}
@keyframes myfirst {
  from {
    background: #ffffff;
  }
  to {
    background: $red;
  }
}
</style>
<style  lang='scss'>
.el-range-editor--medium .el-range-input {
  width: 88px;
  height: 19px;
  font-size: 14px;
  font-family: Rubik-Regular;
  line-height: 17px;
  background-color: $subMenuBg;
  color: $gray;
  opacity: 1;
}
.el-range-editor--medium .el-range-separator {
  text-align: center;
}
.el-range-editor--medium.el-input__inner {
  background-color: $subMenuBg;
  width: 297px;
  height: 36px;
  overflow: hidden;
}
.el-range-editor--medium .el-range-separator {
  color: $gray;
}
</style>

参考: vue+elementUI实现多级联动筛选
.
11. v-model
下面展示一些 内联代码片

// A code block
var foo = 'bar';
// An highlighted block
<div>
	<input class="one" type="text" placeholder="请输入..." v-model="search"/>
	<table>
		<tr v-for="item in searchData" :key="item">
			<td>{{item.name}}</td>
			<td>{{item.status}}</td>
		</tr>
	</table>
</div>

export default {
  data: function () {
    return {
      search: '',
      products: [
        {name: '小明', status: '已发放'},
        {name: '小花', status: '待处理'},
        {name: '韩梅梅', status: '派送中'},
      ]
    }
  },
  computed: {
    searchData: function () {
      var search = this.search
      if (search) {
        return this.products.filter(function (product) {
          return Object.keys(product).some(function (key) {
            return String(product[key]).indexOf(search) > -1
          })
        })
      }
      return this.products
    }
  }
}


11.敲代码 找灵感

下面展示一些 内联代码片

// A code block
var foo = 'bar';
// html
<div class="inputLine">
     <span>所在区域</span>
     <select name="" v-model="countryName" @change="selectCountry">
        <option :value="item" v-for="(item,index) in area">
        {{item.country}}
        </option>
     </select>
     <select name="" v-model="cityName" style="width:90px">
        <option :value="item" v-for="(item,index) in countryName.city">
        {{item}}
        </option>
     </select>
</div>

//data
countryName: {
     country: "客户等级",
     city: [
       "白金",
       "黄金",
       "钻石",
       "VIP",
       "VVIP",
      ]
   },
  cityName: "白金",
  area:[
  {
    country: "客户等级",
    city: [
      "白金",
      "黄金",
      "钻石",
      "VIP",
      "VVIP",
    ]
   },
  {
     country: "风险承受能力",
     city: ["低风险", "中低风险", "中高风险", "高风险"]
   },
  {
     country: "持有产品",
     city: ["理财", "基金", "保险","贵金属","存单","国债"]
   },
  ],

//method
selectCountry(value){
  this.cityName=this.countryName.city[0];
},
  1. 这个博客写的很好,连后端都有,就是用的Jquery
    下面展示一些 内联代码片
// A code block
var foo = 'bar';
// An highlighted block
var foo = 'bar';

参考: select下拉菜单实现二级联动
.

下面展示一些 内联代码片

// A code block
var foo = 'bar';
// html
<template>
  <!-- 异步数据字典联动控件封装 -->
  <div
    class="data-dict"
    v-loading="!isFinishedGetOptions"
    element-loading-spinner="el-icon-loading"
    element-loading-background="rgba(255, 255, 255, 0)"
    element-loading-custom-class="loading-cascader">
    <el-cascader ref="dictCascaderRef"
      v-model="_current"
      :options="filterOptions || null"
      :key="isFinishedGetOptions"
      :props="dictTreeProps"
      :disabled="disabled"
      :filterable="filterable"
      :clearable="clearable"
      :multiple="multiple"
      :size="size"
      :before-filter="beforeFilter"
      @blur="blurFn"
      @change="changeFn"
    ></el-cascader>
  </div>
</template>


<style lang="scss" scoped>
>>> .loading-cascader {
  line-height: 32px;
  .el-loading-spinner {
    height: 32px;
    line-height: 32px;
    top: 0;
    margin-top: 0;
    text-align: right;
    padding-right: 10px;
  }
}
.data-dict {
  position: relative;
  .el-cascader,
  .el-select {
    display: block;
    width: 100%;
  }
}
</style>


//js

    import { arrayValueEquals } from '@/utils/util.js'
    export default {
        components: {
        },
        model: {
            prop: 'value',
            event: 'input'
        },
        props: {
            value: { // 对应父组件v-model中的值
                type: [Array],
                default: () => null
            },
            dictKey: { //
                type: String,
                required: true,
                default: () => ''
            },
            checkStrictly: {
                type: Boolean
            },
            needReturnCheckedNodes: {
              type: Boolean,
            },
            disabled: {
                type: Boolean
            },
            multiple: {
                type: Boolean
            },
            filterable: {
                type: Boolean
            },
            clearable: {
                type: Boolean
            },
            size: {
                type: String
            },
        },
        data () {
            return {
                filterKey: '',
                filterOptions: [],
                orginList: [],
                currentVal: [],
                isFinishedGetOptions: false,
                dictTreeProps: null
            }
        },
        computed: {
            _current: {
                get () {
                    return this.currentVal
                },
                set (val) {
                    this.currentVal = val
                    this.$emit('input', val)
                }
            }
        },
        watch: {
            value: {
                handler (newVal, oldVal) {
                    if (newVal && Array.isArray(newVal) && newVal.length) {
                        this.currentVal = newVal
                    } else {
                        this.currentVal = []
                    }

                    if (this.isFinishedGetOptions || arrayValueEquals(newVal, oldVal)) {
                      return
                    }
                    if (this.currentVal && this.currentVal.length) { // 如果当前有值,则获取数据用于回显
                      this.getAllTreeByCurrent()
                    } else {
                      this.getTreeInfo()
                    }
                },
                immediate: true
            }
        },
        created () {
            const ths = this
            console.log('created')
            ths.dictTreeProps = {
                lazy: true,
                children: 'children',
                label: 'name',
                value: 'key',
                multiple: ths.multiple,
                checkStrictly: ths.checkStrictly,
                lazyLoad (node, resolve) {
                    if (node.level === 0) {
                        ths.getInitTree(resolve)
                    } else {
                        ths.getChildrenInfo(node, resolve)
                    }
                }
            }
            if (!ths.dictKey) {
                ths.isFinishedGetOptions = true
                return false
            }
        },
        methods: {
            beforeFilter (val) {
              const ths = this
              ths.filterKey = val
              const promise = new Promise((resolve,reject)=>{
                const params = {
                    key: val,
                    source_uri: ths.dictKey
                }
                ths.$store.dispatch('xxxxxxx/getAllTreeByKeyword', params).then(res => {
                    const tempList = Array.isArray(res.data) ? res.data : (res.data ? [res.data] : [])
                    if (tempList && tempList.length) {
                      ths.filterOptions = tempList
                      resolve(tempList)
                    } else {
                        reject(new Error())
                    }
                }).catch(res => {
                  reject(new Error())
                })
              })
              return promise
            },
            blurFn () {
                this.filterKey = ''
            },
            // 值变化后回调
            changeFn (value) {
                let nodes = []
                if (this.needReturnCheckedNodes) {
                  nodes = this.$refs.dictCascaderRef.getCheckedNodes() || []
                }
                this.$emit('change', value, nodes)
            },
            // 获取子项列表
            getChildrenInfo (current, resolve) {
                if (!current || !current.data || !current.data.id) {
                    return false
                }

                // 如果已经有返回子节点数据
                if (current.data.leaf || (resolve && current.data.children && current.data.children.length)) {
                    resolve([])
                } else {
                    const params = {
                        node_id: current.data.id
                    }
                    const ths = this
                    ths.$store.dispatch('dictdata/getTreeChildByKey', params).then(res => {
                        let tempList = []
                        if (res.data && res.data.length && res.data[0].children && res.data[0].children.length) {
                            tempList = this.removeEmptyFn(res.data[0].children || [])
                        }

                        if (resolve) {
                            resolve(tempList)
                        }
                    }).catch(res => {
                        resolve([])
                    })
                }
              },
            // 移除子列表为空
            removeEmptyFn (list = []) {
                  const ths = this
                  const tempList = list
                  tempList.forEach(item => {
                    if (!item.children || !item.children.length) {
                        delete item.children
                    } else {
                        item.children = ths.removeEmptyFn(item.children)
                    }
                })
                return tempList
            },
            /**
             * 根据当前值获取树(用于回显
             *例如 [[11,111,1111], [13,131]] 则从后台返回第一级别所有数据【11;12;13...】,【11】children的所有数据,【111】children的所有数据,【13】children的所有数据,)
              */
            getAllTreeByCurrent () {
                const ths = this
                const params = {
                    path: ths.currentVal || [],
                    source_uri: ths.dictKey
                }
                ths.isFinishedGetOptions = false
                ths.$store.dispatch('xxxx/getAllTreeByCurrent', params).then(res => {
                    const tempList = Array.isArray(res.data) ? res.data : (res.data ? [res.data] : [])
                    if (tempList && tempList.length) {
                      ths.isFinishedGetOptions = true
                      ths.orginList = tempList
                    } else {
                      ths.getTreeInfo()
                    }
                }).catch(res => {
                    ths.isFinishedGetOptions = true
                })
            },
            // 初始化信息
            getTreeInfo () {
                const ths = this
                const params = {
                    key: ths.dictKey,
                    view_type: 'tree'
                }
                ths.isFinishedGetOptions = false
                ths.$store.dispatch('xxx/getTreeInfo', params).then(res => {
                    const tempList = res.data || []
                    ths.orginList = tempList
                }).catch(res => {
                }).finally(() => {
                    ths.isFinishedGetOptions = true
                })
            },
            // 初始化第一级信息
            getInitTree (resolve) {
                const ths = this
                if (ths.isFinishedGetOptions) {
                    if (resolve) {
                        resolve(ths.orginList)
                    }
                } else {
                    setTimeout(() => {
                        ths.getInitTree(resolve)
                    }, 300)
                }
            }
        }
    }

链接: vue element-ui 中 el-cascader的异步使用(包括回显,过滤)
.

第二类 filter()
filter()
描述: 创建一个新数组, 其包含通过所提供函数实现的测试的所有元素。
14. 这个博客讲得好,参考性强
下面展示一些 内联代码片

// A code block
var foo = 'bar';
// An highlighted block
//假设后端通过接口给我们的数据如下:
let data = [ {
        name: 'Andy',
        age: 13
    }, {
        name: 'Jack',
        age: 14
    }, {
        name: 'Lucy',
        age: 12
    } ]
//在实际项目中,我们需要根据筛选框中的条件来实现数据的过滤,下面为过滤方法:
//@param condition 过滤条件
//@param data 需要过滤的数据
let filter=(condition,data)=>{
    return data.filter( item => {
        return Object.keys( condition ).every( key => {
           return String( item[ key ] ).toLowerCase().includes( 
                   String( condition[ key ] ).trim().toLowerCase() )
            } )
     } )
}
//假设选择的条件为name中带字母a的元素
var condition={name:'a'}
filter(condition,data) //[ {name: 'Andy',age: 13},{name: 'Jack',age: 14}]
 
//假设选择的条件为name中带字母a,而且age为13的元素
var condition={name:'a',age:13}
filter(condition,data) //[ {name: 'Andy',age: 13}]
 
 

参考: js 前端数据多条件筛选过滤
.

15.讲得很简单 试试
参考: filter 用法心得,可用作前端页面数据过滤.

16.隐藏选项
链接: Cascader 级联选择器通过状态展示隐藏
.

今天解决的

1.省市区联动
方法:通过比对antd demo 发现children 键名节点拿到的值 children,对照的是demo里的item,对照数据里三级结构,key键名

通过比对antd demo 发现children 键名节点拿到的值 children,对照的是demo里的item,对照数据里三级结构,key键名
// An highlighted block
  <a-cascader
    :field-names="{ label: 'name', value: 'code', children: 'items' }"//items是子节点,迭代子节点
    :options="options"
    placeholder="Please select"
    @change="onChange"
  />
//antd cascader 里的数据
{
    code: 'zhejiang',
    name: 'Zhejiang',
    items: [
      {
        code: 'hangzhou',
        name: 'Hangzhou',
        items: [
          {
            code: 'xihu',
            name: 'West Lake',
          },
        ],
      },
    ],
  },
// 对比后台的regionList数据
{
    'code': '130000',
    'name': '河北省',
    'children': [
      {
        'code': '130100',
        'name': '石家庄市',
        'children': [
          { 'code': '130102', 'name': '长安区' },
          { 'code': '130104', 'name': '桥西区' },
          { 'code': '130105', 'name': '新华区' },
          { 'code': '130107', 'name': '井陉矿区' },
          { 'code': '130108', 'name': '裕华区' },
          { 'code': '130109', 'name': '藁城区' },
          { 'code': '130110', 'name': '鹿泉区' },
          { 'code': '130111', 'name': '栾城区' },
          { 'code': '130121', 'name': '井陉县' },
          { 'code': '130123', 'name': '正定县' },
          { 'code': '130125', 'name': '行唐县' },
          { 'code': '130126', 'name': '灵寿县' },
          { 'code': '130127', 'name': '高邑县' },
          { 'code': '130128', 'name': '深泽县' },
          { 'code': '130129', 'name': '赞皇县' },
          { 'code': '130130', 'name': '无极县' },
          { 'code': '130131', 'name': '平山县' },
          { 'code': '130132', 'name': '元氏县' },
          { 'code': '130133', 'name': '赵县' },
          { 'code': '130181', 'name': '辛集市' },
          { 'code': '130183', 'name': '晋州市' },
          { 'code': '130184', 'name': '新乐市' }
        ]
      },
  1. 通过比对同事的代码,参考二次录入siteList.vue
    options的值 由计算属性改变
//html 这里绑定的options是由computed动态改变的
  <a-cascader
      :field-names="{ label: 'name', value: 'code', children: 'children' }"
      :options="options" //
      placeholder="请选择地址"
      @change="onChange"
    />
// data里设置初始值
  regionList:[],//一定要设置空值,这里是数据初始化
// computed 计算属性 动态改变前端的值
 computed: {
    options () { //
      return this.regionList
    },
    //methods 从接口调取后台的数据
     async loadData () {
      // 第一步 取接口

      const regionObj = await getAllRegion()
      // console.log(regionObj)
      const regionList = regionObj.result
      // console.log(regionList)// 是一个级联的对象数组
      this.regionList = regionList

搜索逻辑

如何把两个对象数组合成一个数组对象

obj[]
js arr[][]

通过cascader怎么对table过滤
js省市区级联过滤筛选表格
搜所推荐 前端页面数据过滤 前端页面数据过滤

select group 级联选择过滤
select group 级联选择过滤
group级联选择二级select
group级联选择二级select
antd select选择过滤

antd select选择过滤table

级联过滤table
通过select联动选择过滤table
vue js select table 联动筛选过滤
vue 点击按钮select 联动筛选table
vue 实现数组筛选功能 filter过滤
onFilter

总结

1.对照antd框架自带的代码 的数据结构进行更改 ,一下子解决了前几天省市区联动的困难
2.通过对照 同事的代码 ,模仿学习 模仿能力可以,但是理解疏忽了,接下来要知道为什么这样做,
2.通过一级一级地打log知道了obj[][]并不是新知识点啥稀奇古怪知识点,而是前面的时key,后面是key对应的value(数组)的第一个值
3.今天问人了吗 ,问了 多问问 问问题也有学问
4.搜索博客的能力
5.通过发现问题 搜索问题 以及测试 打log的方式 学会知识点
6.常见的语法 代码片要总结 无非要实现的情景都是可以抽象出模型的,在这个模型下 转化成数组和对象之间的操作 重点
多总结几种遍历方法,多总结计算机思维 遍历 映射

ps:很多情况前端页面进行数据的筛选,这个时候用到了filter,等同map “映射”, 过滤以后原来数组不变。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值