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

  • 相关阅读:
    微信 token ticket jsapi_ticket access_token 获取 getAccessToken get_jsapi_ticket方法
    PHP 日志 记录 函数 支持 数组 对象 新浪 sae 环境 去掉 空格 换行 格式化 输出 数组转字符串
    原生 原始 PHP连接MySQL 代码 参考mysqli pdo
    PHP 数字金额转换成中文大写金额的函数 数字转中文
    使用PHPMailer发送带附件并支持HTML内容的邮件
    设置输出编码格式 header 重定向 执行时间 set_time_limit 错误 报告 级别 error_reporting
    html5 bootstrap pannel table 协议 公告 声明 文书 模板
    指向指针的指针
    二级指针
    c语言:当指针成为参数后
  • 原文地址:https://www.cnblogs.com/_error/p/10345275.html
Copyright © 2011-2022 走看看