美文网首页
vue2.x 组件化与验证插件的编写

vue2.x 组件化与验证插件的编写

作者: itvwork | 来源:发表于2017-09-12 15:43 被阅读167次

    学习了一年多的 vue 感觉vue还真是个强大的组件化框架.作为一个前端开发工作者,在开当中预到不少问题。也看到不少开发者写的vue代码,每个人写的代码都有些不同。很多人对组件化理解得不是很深,写的代码很多重复的代码却没抽出来,做成一个独立的组件。我先说说我遇到的情况:

    很多人做表单的时候,一个页面一个组件,下面写很多原生input。比如:

    image.png

    像这样一个页面很多人都会直接一个路原生表单走到黑,

    <form>
    <label class="row-label">
        <span>标题</span>
        <span class="text-outdoor">
           <input type="text"    class="input-text  />
           <i class="clear-word" ></i>
            <em>错误信息</em>
     </span>
    </label>
    <label class="row-label">
        <span>标题</span>
        <span class="text-outdoor">
           <input type="text"    class="input-text  />
           <i class="clear-word" ></i>
            <em>错误信息</em>
     </span>
    </label><label class="row-label">
        <span>标题</span>
        <span class="text-outdoor">
           <input type="text"    class="input-text  />
           <i class="clear-word" ></i>
            <em>错误信息</em>
     </span>
    </label>
    <form>
    </template>
    

    然后表单就一直加在这个页面,这样一个页面不觉得有很多重用的地方法嘛,为什么不把一个表单儿独立成一个组件呢,这样可大地减少代码理,下面是我自己把一个input 封装成一个组件的代码,我觉得一个input一个组件会给我们带来很大的方便。比如验证写验证的候可以独立验证。像表单验证这种自定义很强的插件本来是要自己写是最好的。组件化表单我方便我们写这样的插件。当然这仅能代表我的写法,没什么特别的意思大家觉得好就点赞,觉得不好当我没说。也可以给一些意见我,当作交流。

    好了下面直接复制出我自己独立成组件的代码:

    <label class="row-label">
      <span class="row-title" v-if="toggleTitle==1" :style="{width:tw}">{{title}}</span>
      <span class="text-outdoor">
          <input :type="inputType" :id="id"  :value="value"   :disabled='isDisabled' class="input-text" :placeholder="tips"   ref="input"   @input="updateValue($event.target.value)"  />
          <i class="clear-word"  @click="clear()" v-if="value&&(type!='password')&&(!isDisabled)" ></i>
          <i :class="{'icon-view-pwd':(inputType=='password'),'icon-hide-pwd':(inputType!='password')}"  v-if="value&&(type=='password')&&(!isDisabled)"   @click="inputType!='password'?inputType='password':inputType='text' "></i>
          <em class="err-msg" v-if="err!==true">{{err}}</em>
      </span>
    </label>
    </template>
    <script>
    export default {
      props: {
        value: {
          type: String, //需要绑定的值 
          default: ''
        },
        title: {
          type: String
          default: '标题'  //表单的标题名称
        },
        tips: {
          type: String,//表单的placeholder
          default: '请输入内容'
        },
      type: {
          type: String,   //表单的类型,比如text number
          default: 'text'
        },
        tw: {
          type: String,//标题所占的宽度
          default: '.1rem'
        },
        toggleTitle: { //就否要显示标题
          type: String,
          default: '0'
        },
        isDisabled:{ //是否禁用
          default:false
        },
        schema:{ //验证字段的对象
          default:false
        },
        rule:{ //验证的规则
          default:false
        },
      },
      computed: {
      },
      data() {
        return {
          inputType: this.$props.type,
          newvalue:this.$props.value,
          err:'',
          id:'input-'+parseInt(Math.random()*1000)+'-'+parseInt(Math.random()*1000)  //来个随机id好调用focus
        }
      },
      methods: {
        updateValue: function(value) {
           if(this.schema){
              this.err=this.schema.single(this.rule,value); //验证表单信息
            }
           this.$emit('update:value', value);
        },
        valtVal:function(){ //提交时验证
            this.err=this.schema.single(this.rule,this.value);
            return this.err;
        },
        focus:function(){
                document.getElementById(this.id).focus();
        },
        showErr:function(err){ //显示错误的信息,这个是做异步验证的,下面会说
            this.err=err;
        },
        clear: function() { //清理表单
          this.$refs.input.value = "";
          this.$emit('update:value', "");  <br/>}
      }
    };
    </script>
    

    验证码器代码:

    
    
    
    export default function Validator(data,self,ref) {  
        this.data = data;//保存新建的规则,
        this.result=""
        this.self=self; 将页面的this传过来并保存
        this.ref=ref; //将表单的ref索引传过来
     
    }
    Validator.prototype = {
        constructor: Validator,
        single: function(valname, val) { //验证单个字段  查看表单组件的valtVal()方法
            let str = true;
            if (this.data[valname]['tirm']) {
                val = this.trim(val);
            }
            for (let i = 0; i < this.data[valname]['rule'].length; i++) {
                let msg = this.data[valname]['msg'][i];
                let rule = this.data[valname]['rule'][i];
                if (typeof rule == 'string') {
                    if (this[rule](val)) {
                        str = true;
                    } else {
                        str = msg;
                        break;
                    }
                } else {
                    if (this[rule[0]](rule, val)) {
                        str = true;
                    } else {
                        str = msg;
                        break;
                    }
                }
            }
    
            return str;
        },
        all: function(data) {
            return this.data[valname];
        },
        require: function(str) { //必须字段
            if (str) {
                return true;
            } else {
                return false;
            }
        },
        tel: function(str) { //国内固话验证
            var result = str.match(/^(\(\d{3,4}\)|\d{3,4}-)?\d{7,8}$/);
            if (result == null) return false;
            return true;
        },
        tel400: function(str) {
            if (str.match(/^400\-[\d|\-]{7}[\d]{1}$/)) { //第一次匹配 400-(七个数字和-)(数字结尾)
                if (str.match(/[\-]/g) == "-,-") { //第二次匹配两个 -
                    return true;
                } else {
                    return false;
                }
            } else {
                return false;
            }
        },
        trim: function(str) { //去除前后空格
            return str.replace(/(^\s*)|(\s*$)/g, '');
        },
        between: function(arr, val) { //区间大小
            if (val.length >= arr[1] && val.length <= arr[2]) {
                return true;
            } else {
                return false;
            }
        },
        max:function(arr,val){
          if (val.length > arr[1]) {
              return false;
          } else {
              return true;
          }
        },
        max:function(arr,val){
          if (val.length <arr[1]) {
              return false;
          } else {
              return true;
          }
        },
        phone: function(str) {
          var result = str.match(/^1[34578]\d{9}$/);
          if (result == null) return false;
          return true;
        },
        email: function(str) { //email
            var result = str.match(/^\w+((-\w+)|(\.\w+))*\@[A-Za-z0-9]+((\.|-)[A-Za-z0-9]+)*\.[A-Za-z0-9]+$/);
            if (result == null) return false;
            return true;
        },
        getResult: function() {
            return this.result;
        },
        strlen: function(str) { //
            return str.replace(/[^\x00-\xff]/g, "**").length;
        },
        alltel:function (str) {
            return this.tel(str)||this.tel400(str)||this.phone(str);
        },
        getdata:function () {
            return this.self.shop
        },
       allvalt:function(){
            let child = this.self.$refs[this.ref?this.ref:'form'].$children;
            let oneerr=true;//获取第一个错误的组件 然后获取焦点
            for(let i =0 ; i<child.length;i++){
                if(child[i].rule){
                    if(child[i].valtVal()!==true&&oneerr===true){  判断第一个没有通过验证的是哪个组件
                        child[i].focus();//调用组件的focus,查看input的focus方法
                        oneerr=false;
                    }
                }
            }
            if(oneerr===true){
                return true; 
            }else{
                return false;
            }
        }
    
    };
    
    

    页面调用代码:

    导入你的验证器代码在你的入口文件:import Schema from './validator/index.js';
    Window.Schema=Schema||{};注册全局
    
    <template>
    <indoor>
        <form-edit ref='form'>
          <input-text toggleTitle=1 title="店铺名称:"  tips="请输入店铺名称"  :value.sync="shop.store_name"  :schema="schema" rule="store_name"  tw="1rem"></input-text>
         //调用的时我们必须把数据绑定到上面
            <input-text toggleTitle=1 title="联系人(可不填):"  tips="请输入联系人姓名"  :value.sync="shop.store_contact" tw="1rem"></input-text>
          <input-text toggleTitle=1 title="电话号码:"  tips="请输入联系电话"  :value.sync="shop.store_phone" :schema="schema" rule="store_phone" tw="1rem"></input-text>
          <input-text toggleTitle=1 title="店面地址:" ref='addr'  tips="请输入地址至少要到区"  :value.sync="shop.store_address" :schema="schema" rule="store_address"  tw="1rem"></input-text>
            <div class="sub-bar" style="padding-left: 1.3rem">
                <button  class="btns btn-sub" @click="send()">{{subword}}</button>
            </div>
        </form-edit>
    </indoor>
    </template>
    <script>
    //下面就是我写的验证器用法
    let schema ={
       store_name:{
         tirm:false,
         rule:['require',['between',3,20]],//这是用到的规则
         msg:['店名是必须','店名必须在10-15个字符'] // 对应上面输入出的错误信息
      },
      store_phone:{
        rule:['require','alltel'],
        msg:['电话是必填的',"请输入正确的电话号码,固话,手机,400电话"]
      },
      store_address:{
        rule:['require'],
        msg:['地址不能为空']
      }
    };
    
    export default {
        components: { addbtn },
        data() {
            return {
                btn: [{
                        type: 'link',
                        url: '/admin/shop/add',
                        name: '添加店铺',
                        class: 'btn-add-model'
                    }
                ],
                shop:{
                  store_name:"",
                  store_phone:'',
                  store_ewm:'',
                  store_contact:'',
                  store_address:'',
                  latlng:''
                },
                forbid:true,
                subword:"提交",
                schema:new Schema(schema,this), //将验证码
                tips:''
            }
        },   
        watch: {
            '$route': function(to, from) {
                if (this.$route.query.page) {
                    this.$refs.page.change({});
                }
            }
        },
        methods: {
          async send(){
            if(!this.schema.allvalt()){
                    return false;
            }
          }
         
    };
    </script>
    
    

    不懂的可以看我的源代码 https://github.com/itvwork/itvwork
    按提示安装依赖 然后运行项目
    访问9090端口点击登录,然后点店铺管理,点击右上角的店铺添加 就可以看到源码了

    验证器放在 app/validator 目录下
    子组件事input放在 app/commpents/input/input-text.vue中
    调用子组件和验证器的案例在:app/view/store/add.vue中

    本文写到这里,有什么建议和疑问可以发我邮箱xieke76v@qq.com
    这只是我自己总结出来的方法,当然大家有更好的方法也可以说,大家多交流,谢谢

    相关文章

      网友评论

          本文标题:vue2.x 组件化与验证插件的编写

          本文链接:https://www.haomeiwen.com/subject/vafcsxtx.html