基于vue2.x实现单选框与复选框组件

基于vue2.x实现单选框与复选框组件


w-single-input(单选框)

w-checkbox(多选框)

不是很会录屏,就放几组演示照片吧

基于vue2.x实现单选框与复选框组件_第1张图片
基于vue2.x实现单选框与复选框组件_第2张图片

基于vue2.x实现单选框与复选框组件_第3张图片话不多说,我们现在就开始实现这两个组件,首先你得搭好一个架子,架子具体实现请参考github,这个是我组件库开发的地址,通过修改vue-cli脚手架,将开发与展示放在一块,利于我前期的一个开发,examples下是展示实例,packages是包所在的文件目录,如果你感觉通过修改vue-cli脚手架太麻烦的话,也可以通过链接引入vue,然后对这两个组件进行注册,当然这也是可以的。


我们先来实现单选框组件

  1. 最开始我们需要的数据包含originOptionsselected这两个数据,我们通过方法queryData来添加我们想要的数据,冰鞋我们需要设定一个回掉函数singleCallback,来处理我们子组件返回的值,大概是父组件中需要这样写代码,并且我们父组件的html部分需要这样写。
<script>
export default{
    data(){
      return {
        single:{
          originOptions: [],
          selected: {}
        }
      }
    },
    mounted :function() {
        this.queryData();
    },
    methods: {
        queryData: function(){
        var mySelf = this
        //do ajax here
        // 单选
        mySelf.single.originOptions = [{"id":"1","name":"lemon"},{"id":"2","name":"mike"},{"id":"3","name":"lara"},{"id":"4","name":"zoe"},{"id":"5","name":"steve"},{"id":"6","name":"nolan"}];
        mySelf.single.selected = {"id":"4","name":"zoe"}
        this.$nextTick(function(){
            //dom更新之后,执行一些其他操所。
        })
        },
      singleCallback: function(data){
        this.single.selected = data;
        console.log('父级元素调用singleCallback 选中的是' + JSON.stringify(data))
      }
    }
  }
script>
//部分,请自行放在合适位置
<w-single-input v-bind:optionsdata="single.originOptions" v-bind:selecteddata="single.selected" @selected="singleCallback" >w-single-input>
  1. 下面我们来看最关键的部分,也就是组件的实现部分,我们通过,props: ['optionsdata','selecteddata'],来获取父元素传给子组件的值,并且我们还需要通过watch来监听数据的变化
watch: {
      //监听选项值和选中值得变化
      optionsdata: function (val, oldVal) {
        this.originOptions = val;
        this.show = false;
        // 默认值
        if (this.selected.id == ''){
          this.selected = this.originOptions[0];
        }
      },
      selecteddata: function(val, oldVal){
        this.selected = val
      }
    },

我们根据需要在data函数里面添加我们需要的数值.具体功能已经标明。

data: function() {
 return{
    originOptions: [],//从父组件接受回来的数据
    displayOptions: [],//需要展现的列表(查询的时候列表会变化)
    show: false,
    search: '',//查询input框中的数据
    selected: { //选中的选项
      id: "",
      name: ""
    }
  }
},
  1. 我们来设定子组件需要展示的模板,这里面有很多注意细节,比如没有数据时候信息展示的处理,input框选中后的效果,还有图标的变换等,具体操作亲看代码css部分你可以添加到vue文件的style标签中,这里我给出style文件的链接single.css
<div class="functional-select-wrapper" @click.stop="singleFocus()">
  <label class="display-container clearfix" :class="(show)?'single-selected-focus':''">
    <p v-show="selected.id == ''">
      <span v-if="originOptions.length != 0">请选择span>
      <span v-else>没有选项span>
    p>
    <p class="single-selected">{{ selected.name }}p>
    <i class="drop" :class="(show)?'drop-up':''">i>
  label>
  <div class="options-container" v-show="show">
    <div class="search-container">
      <input placeholder="search here" class="search-input" v-model="search" @keyup="singleSearch" @click.stop />
    div>
    <ul class="options-ul-list">
      <li v-show="displayOptions.length == 0">没有查询到数据li>
      <li v-for="item in displayOptions" @click.stop.prevent="singleSelect(item.id)" :class="(item.id == selected.id)?'selected':''">{{ item.name }}li>
    ul>
  div>
div>
  1. 我们来看子组件的需要的函数以及其他功能,首先singleFocus()函数实现单选框数据下拉展示,并且获得焦点,我们通过此函数调用函数searchInputFocus()来设定搜索框的焦点,这里面使用了this.$nextTick回掉函数,下一次数据更新之后重新获取焦点,singleSelect()函数则是根据我当前的id,从displayOptions数组中寻找对应的选项,并且赋值给selected,最后一个就是搜多功能函数了singleSearch我们通过用户输入的值来作正则匹配
    ,通过遍历选项列表,来更新displayOptions数组中的值,我们值发生变化后,列表会自动更新搜索的内容。整个script标签中的的代码如下。
  export default {
    name:'w-single-input',
    props: ['optionsdata','selecteddata'],
    data: function() {
      return{
        originOptions: [],
        displayOptions: [],
        show: false,
        search: '',
        selected: {
          id: "",
          name: ""
        }
      }
    },
    mounted: function(){
      //设置点击其他区域关闭选项
      window.addEventListener('click',this.blur);
    },
    watch: {
      //监听选项值和选中值得变化
      optionsdata: function (val, oldVal) {
        this.originOptions = val;
        this.show = false;
        // 默认值
        if (this.selected.id == ''){
          this.selected = this.originOptions[0];
        }
      },
      selecteddata: function(val, oldVal){
        this.selected = val
      }
    },
    methods:{
      singleFocus: function(){
        if (!this.show){
          document.body.click();
          console.log('single show');
          this.show = true;
          this.singleSearch();
          this.searchInputFocus();
        }
        else{
          this.blur();
        }
      },
      searchInputFocus: function(){
        let searchInput = this.$el.getElementsByClassName('search-input')[0];
        this.$nextTick(function(){
          //下一次dom更新之后使得searchInput获得焦点
          searchInput.focus();
        })
      },
      singleSelect: function(id){
        let mySelf = this;
        let displayOptions = mySelf.displayOptions;
        for (let i=0; ilet item = displayOptions[i];
          //在展示数组里找 找到后1.添加到selected
          if (item.id == id){
            let selected = mySelf.selected;
            selected.id = item.id;
            selected.name = item.name
          }
        }
        //关闭下拉框,清除search输入的值。
        mySelf.show = false;
        this.search = '';
        //传递给父级组件
        this.$emit('selected',this.selected);
         //console.log('选中的是' + JSON.stringify(this.selected));
      },
      singleSearch: function(){
        let mySelf = this;
        let search = mySelf.search;
        //根据用户输入值做正则
        let REG_RULE = new RegExp(search,"i");
        let originOptions = mySelf.originOptions;
        //将展示列表置空 然后用正则去原始列表中匹配
        mySelf.displayOptions = [];
        for (let i=0;ilet item = originOptions[i];
          if (REG_RULE.test(item.name)){
            mySelf.displayOptions.push(item)
          }
        }
      },
      blur: function(){
        this.show = false;
        this.search = '';
      }
    }
  }
</script>

Attributes

参数 说明 类型 可选值 默认值
optionsdata 可选值列表 Array 自定义 null
selected 指定当前选中的值 Json 可选列表中出现的值 null

多选框

  1. 单选框的实现与单选框的区别就是,我选中的不只是一项,而是很多,所以我们指定父组件向子组件传递的时候,我们将selected转变为selectedList数组,并且我们需要在子组件中,需要设定选项的移除功能,其余的功能和单选框差不多,我们在这里给出关键代码,并进行解释。
checkboxRemove:function(name){
   console.log(name);
   let myself = this;
   let optionName = name;
   let selectedList  = myself.selectedList;
   for(let i=0;ilet item  = selectedList[i];
     if(item.id == optionName){
       let index = selectedList.indexOf(item);
       selectedList.splice(index,1);//删除index对应的选项
       myself.checkboxInitSearch();//初始化搜索框
       myself.checkboxSearch();//调用搜索框
       myself.searchInputFocus();//获取焦点
       myself.dispatchData();//通过$emit来触发当前实例上的selected,并且将选中数据当作参数返回给父组件。
     }
   }
 },
  1. html部分,我们在单选框的基础上添加了选中值的展示,通过v-for遍历selectedList中的值,并且我们给他们添加删除按钮(i标签),通过id进行删除对应选项,
 <p class="multiple-selected-item" v-for="item in selectedList" track-by="$index">
        {{ item.name }}
     <i @click.stop.prevent="checkboxRemove(item.id)">×i>
 p>

整个变化就在一块,整体实现代码请点击这里

Attributes

参数 说明 类型 可选值 默认值
options-data 可选值列表 Array 自定义 null
selected-data 指定当前选中值得列表 Array 可选列表中出现的值 null

注意:写代码过程中遇到的问题有这么几个
1. 最后我们通过props:[]去接收参数,一般我采用的都是驼峰命名法,我们在html中写成驼峰命名法会报警告,所以这块我们父组件设定参数的时候通过短线连接符实现,如果你感觉很麻烦,两边都用小写是可以的,但是为了命名过长的话还是建议采用短线连接符来命名,感觉还是编码规范问题,刚一开始就得养成一个好习惯。
2. 通过$emit来触发当前实例上的事件,并传递参数回去。注会主要用在,我们选中值之后我们需要调用各自的回掉函数,我们通过其触发selected事件,并将参数返回给父组件,这样就实现了我们预期的一个效果,子组件选中之后,父组件通过callback显示对应信息,进行后续操作。


本次介绍组件大概就到这里了,如果你想使用我的组件,可以按照下面的方式进行使用。
npm install wvue-ui 

全局注册

import WVUE from 'wvue-ui' // 引入组件库
Vue.use(WVUE)

使用单个组件

import { w-button } from 'wvue-ui'

export default {
  components: {
    w-button
  }
}

在模板中,用 自定义标签的方式使用组件(按钮)

<template>
  <div>
    <w-button>这是一个按钮w-button>
  div>
template>
查看开发文档—WVUE,你们的支持,是我持久更新的动力。github

你可能感兴趣的:(vue)