zoukankan      html  css  js  c++  java
  • vue 自定义组件 v-model

    官方的介绍讲得比较全,这里就省去复制粘贴的步骤了。此处模拟一种非表单元素的 v-model 组件:

    类似复选框,在组件里点选不同的选项,然后能跟父组件双向绑定。

    1. 首先做好基础的排版及样式

    <template>
      <div style="padding:10px">
        <span>1</span>
        <span>2</span>
        <span>3</span>
        <span>4</span>
      </div>
    </template>
    
    <style scoped>
      span{
        display: inline-block;
        width: 80px;
        height: 30px;
        line-height: 30px;
        border-radius: 4px;
        border: 1px solid #333;
        color: #333;
        text-align: center;
      }
      span.active{
        border-color: #f45619;
        color: #f45619;
      }
    </style>

    2. 添加 model 属性

    根据文档内容,v-model 需要两个属性:value、event,一个用来传值(父传子),一个用来接收并赋值(子传父)。

    <input
      v-bind:value="searchText"
      v-on:input="searchText = $event.target.value"
    >

    我们定为 val、change 以示区分

    <script>
    
    export default {
      model:{
        prop:'val',
        event:'change'
      },
      // val 这个值本身是不存在的,所以需要通过 props 定义
      props:{
        val: Array,
      },
      
    };
    </script>

    3. 接下来,我们把数据进一步处理,通过 computed 计算属性操作父组件传过来的值。val 为 0,1,2,3 中的值组成的数组,如:[ 1,3 ]。通过 computed 转换为 list : [ 0,1,0,1]

    <template>
      <div style="padding:10px">
        <span :class="{'active':list[0]}" >1</span>
        <span :class="{'active':list[1]}" >2</span>
        <span :class="{'active':list[2]}" >3</span>
        <span :class="{'active':list[3]}" >4</span>
      </div>
    </template>
    
    <script>
    
    export default {
      model:{
        prop:'val',
        event:'change'
      },
      // val 这个值本身是不存在的,所以需要通过 props 定义
      props:{
        val: Array,
      },
      computed:{
        list(){
          let arr = []
          this.val.forEach(i=>{
            let n = parseInt(i)
            arr[n] = 1
          })
          return arr
        }
      },
    };
    </script>
    
    <style scoped>
      span{
        display: inline-block;
        width: 80px;
        height: 30px;
        line-height: 30px;
        border-radius: 4px;
        border: 1px solid #333;
        color: #333;
        text-align: center;
      }
      span.active{
        border-color: #f45619;
        color: #f45619;
      }
    </style>

    4. 到这里实现了单向的绑定,然后根据子组件的事件操作给父组件传值。通过子组件的点击事件触发父组件的事件提交,并把新值带给父组件

    <template>
      <div style="padding:10px">
        <span :class="{'active':list[0]}" @click="onTap(0)">1</span>
        <span :class="{'active':list[1]}" @click="onTap(1)">2</span>
        <span :class="{'active':list[2]}" @click="onTap(2)">3</span>
        <span :class="{'active':list[3]}" @click="onTap(3)">4</span>
      </div>
    </template>
    
    <script>
    
    export default {
      model:{
        prop:'val',
        event:'change'
      },
      // val 这个值本身是不存在的,所以需要通过 props 定义
      props:{
        val: Array,
      },
      computed:{
        list(){
          let arr = []
          this.val.forEach(i=>{
            let n = parseInt(i)
            arr[n] = 1
          })
          return arr
        }
      },
      methods:{
        onTap(n){
          console.log(n)
          let list = this.list
          list[n] = !list[n]
          let res = []
          list.map((i, idx)=>{
            if(i) res.push(idx)
          })
          // 注意
          // 此处的 change ,来自一开始定义在 model 属性里的event
        // 父组件在接收到传过来的新值后,会用这个新值更新 val 属性,这样就会更新了自组件的值,完成双向绑定的过程
    this.$emit('change',res)
    }
    }
    };
    </script>
    
    <style scoped>
      span{
        display: inline-block;
        width: 80px;
        height: 30px;
        line-height: 30px;
        border-radius: 4px;
        border: 1px solid #333;
        color: #333;
        text-align: center;
      }
      span.active{
        border-color: #f45619;
        color: #f45619;
      }
    </style>

    5. 父组件引用:

    // 父组件
    <template>
      <div class="hello">
        <hello v-model="value"></hello>
      </div>
    </template>
    
    <script>
    import hello from '@/components/model'
    export default {
      components:{ hello },
      data () {
        return {
          value:[1,3],
        }
      },
    }
    </script>

    参考官方文档 :

    在组件上使用 v-model 、 自定义组件的 v-model

  • 相关阅读:
    Oracle数据类型之number
    jQuery与Dom
    Tableau问题及解决办法汇总
    安装
    impala语句
    需要模拟点击爬虫小案例
    Navicat连接Oracle报错处理
    python manage.py runserver报错
    Django安装报错
    用户行为日志
  • 原文地址:https://www.cnblogs.com/_error/p/10345275.html
Copyright © 2011-2022 走看看