自定义组件实现v-model

2023-05-16

在项目中需要做一个标题展开框,点击展开才会显示下面的内容。因为多个地方都需要这样的可展开标题,所以做了一个自定义组件。组件需要一个双向绑定的值,控制展开/缩放。于是就思考,父向子可以用props传值,子传父用事件触发,也这样实现了。后来了解到v-model其实就是数据绑定和事件触发的语法糖,和我之前实现的类似,只不过我自己的实现是自己定义个事件名,而v-model的事件是input事件。于是改写成了v-model,使得子组件被复用起来更简单。

文章目录

    • 1. 实现效果
    • 2. 代码
    • 3. 分析
    • 4. v-model语法糖
    • 5. 扩展(在render函数中的使用)

1. 实现效果

在这里插入图片描述
点击展开时
在这里插入图片描述
title组件控制下面表格的显示/隐藏

2. 代码

父组件中参考如下:(用pug写的)

div.hour-forecast-table
    TitleCollapse.title-collapse-wrap(:title="'时段_'+title" v-model="collapse")
    div.table-wrap(v-if="collapse")
      Table(:columns="columns" :data="tableData" border max-height="500")

TitleCollapse子组件如下

<template lang="pug">
div.title-collapse
  div.title-header
    div.title-text {{title}}
    div.collapse-button(@click="clickCollapseButton")
      span.collapse-text {{collapseText}}
      Icon(:type="value?'ios-arrow-up':'ios-arrow-down'")
</template>

<script>
    export default {
      name: "TitleCollapse",
      props: {
        title: {
          type: String
        },
        value: {
          type: Boolean
        }
      },
      data () {
        return {
          collapse: this.value
        }
      },
      watch: {
        value (val) {
          this.collapse = val
        },
        collapse (val) {
          this.$emit('input', val)
        }
      },
      computed: {
        collapseText () {
          if (this.collapse) {
            return '收起'
          } else {
            return '展开'
          }
        },
      },
      methods : {
        clickCollapseButton () {
          this.collapse = !this.collapse
        },
      }
    }
</script>

<style scoped lang="scss">
.title-collapse {
  .title-header{
    display: -webkit-flex;
    justify-content: left;
    position: relative;
    .title-text{
      font-size: 16px;
    }
    .collapse-button{
      font-size: 14px;
      color: #1890FF;
      position: absolute;
      right: 0;
    }
  }
}
</style>

3. 分析

实现双向绑定有两步,第一步是父传给子,通过props传,v-model在props中是value。然后按按钮子组件里的值变化,不可以直接改props里的值,所以要在data里声明一个新值collapse当中介,赋初始值为value,并且watch value,在value改变时改变collapse。按按钮改变collapse的值,在watch里监控collapse,collapse改变时向外触发input事件,这样就实现了双向绑定。
总结来看,v-model其实就是v-bind和v-on的语法糖。

4. v-model语法糖

其实在vue中,在使用v-model绑定数据之后,既绑定了数据,又添加了事件监听,这个事件就是input事件
例如官方文档给出:
在这里插入图片描述
可以看出v-modal就是v-bind和v-on的语法糖,自定义组件的实现就是接受了一个value值,在有新的value(比如点击展开/收起按钮的时候新值改变)去触发input事件把新值传出来。这样之前的代码就很好理解了

5. 扩展(在render函数中的使用)

使用了iview的table,但在table中要自定义一个checkbox选择框,所以需要用到render函数。选择框希望可以双向绑定,发现render函数里需要自己去实现v-model,这就又涉及到了v-model的语法糖,实现如下

            tableColumns: [
              {
                title: '序号',
                key: 'id'
              },
              {
                title: '分类',
                key: 'targetTypeCategory'
              },
              {
                title: '是否参与计算',
                key: 'factor',
                render:(h, params) => {
                  return  h('Checkbox', {
                      style:{
                        margin:"15px 0px 15px 15px",
                        display:"block"
                      },
                      props: {
                        value: this.tableData[params.index].factor,
                      },
                      on: {
                        input: (event) => {
                          this.$set(this.tableData[params.index], 'factor', event);
                        },
                      },
                    })
                }
              },
              {
                title: '是否进行公式替换',
                key: 'funReplace',
                render:(h, params) => {
                  return h('Checkbox', {
                    style:{
                      margin:"15px 0px 15px 15px",
                      display:"block"
                    },
                    props: {
                      value: this.tableData[params.index].funReplace,
                    },
                    on: {
                      input: (event) => {
                        this.$set(this.tableData[params.index], 'funReplace', event);
                      },
                    },
                  })
                }
              }
              }
            ]
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

自定义组件实现v-model 的相关文章

  • django 更新时的模型验证

    我创建了一个名为 Term 的模型及其验证器 如下所示 from django db import models from django contrib auth models import User from django core ex
  • Ruby on Rails - 创建用户时创建配置文件

    所以基本上我已经编写了自己的身份验证而不是使用 gem 因此我可以访问控制器 我的用户创建工作正常 但是当创建我的用户时 我还想在我的个人资料模型中为他们创建个人资料记录 我已经让它大部分工作了 我只是似乎无法将新用户的 ID 传递到新的
  • 使用其他自变量的所有可能组合获取许多模型中特定变量的 p 值

    我正在尝试使用一组自变量的所有可能组合来运行许多回归模型 在此示例中 我对以下系数感兴趣cyl与列出的其他变量的所有可能组合xlist df lt mtcars md lt mpg cyl xlist lt c disp hp am n l
  • 如何解耦小部件的模型/视图

    我正在编写一个应用程序 用于绘制小部件 菜单 控件等以创建应用程序模型 每个屏幕都表示为小部件的集合 每个小部件都是简单的类 例如 class Model object def init self self widgets class Wi
  • AutoMapper,如何保持映射对象之间的引用?

    我使用 AutoMapper 将 UI 模型转换为 POCO 然后使用 DataContractSerializer 将其序列化为 XML 以便保留它们之间的引用 问题来了 在绘制地图时 这些实体之间的引用丢失 UI 类相互引用 但映射过程
  • Zend_Forms、控制器放在哪里?模型?别的地方?

    构建 Zend Forms 的代码最好放在哪里 我曾经把这个逻辑放在我的控制器中 但在我需要在不同的地方使用相同的表单后 我就放弃了这个逻辑 这意味着我必须在不同的控制器中重复创建表单 因此 我将表单创建代码移至我的模型中 这看起来正确吗
  • 如何在 MVC 中的单个 foreach 循环中创建水平表?

    在 ASP Net MVC 中 有什么方法可以将以下代码压缩为单个 foreach 循环吗 table class table tr td Name td td td tr tr td Item td tr table
  • MVC 模型对象、域对象和 DTO 之间有什么区别

    MVC 模型对象 域对象和 DTO 之间有什么区别 我的理解是 MVC 模型对象 对要由相应视图显示的数据进行建模 它可能不会直接映射到域对象 即可能包含来自一个或多个域对象的数据 客户端 可能包含业务逻辑 例如 验证 计算属性等 没有持久
  • 为什么有两个类:视图模型和域模型?

    我知道使用域模型作为视图模型可能很糟糕 如果我的域模型有一个名为 IsAdmin 的属性 并且我有一个创建控制器操作来创建用户 那么有人可以更改我的表单并使其 POST IsAdmin true 表单值 即使我没有在视图中公开这样的文本字段
  • 我需要双向创建 automapper createmap 吗?

    这可能是一个愚蠢的问题 n00b 到 AutoMapper 并且时间很短 我想使用 AutoMapper 从 EF4 实体映射到 ViewModel 类 1 如果我打电话 CreateMap
  • 使用 dropdownlist 时的 Asp.net mvc ModelState 有效性

    ModelState IsValid始终为 false 因为我在要提交的表单中使用下拉列表 并且收到此异常 The parameter conversion from type System String to type System We
  • Rails 在模型中验证值在数组内

    我有一个表格 我可以在其中传递一个字段命名 type我想要检查它的值是否在允许类型的数组内以便任何人不得发布不允许的类型 数组看起来像 allowed types type1 type2 type3 type4 type5 type6 ty
  • Django与领域和自身的多对多关系独特

    我尝试使用语言和内容创建帖子 并将其与同一页面的其他版本相关联 但我陷入困境 class Page models Model content models TextField language models CharField max le
  • 如何将 Request->all() 与 Eloquent 模型一起使用

    我有一个 lumen 应用程序 需要在其中存储传入的 JSON 请求 如果我写这样的代码 public function store Request request if request gt isJson data request gt
  • asp.net mvc相当于rails回调before_save

    您好 我正在寻找一个 ASP NET MVC 回调 以便在保存模型之前获取详细数据 Rails 中有 before save Thanks 如果您正在使用实体框架 您的标签表明 那么这个 StackOverflow 帖子 https sta
  • Kendo UI - observable、ObservableObject 和 Model 之间的区别

    observable ObservableObject 和 Model 之间有什么区别 谢谢 Model继承自ObservableObject 而ObservableObject又继承自Observable 可观察的 http docs k
  • Django 中级模型用户

    我想创建一个模型 其中用户拥有多家公司一定数量的股份 看来我应该使用 Django 中间模型关系 但我不确定如何将中间模型应用到内置 Django 用户模型 目前 公司与股东 用户 之间存在多对多关系 如何为每个特定的公司股东关系添加股份数
  • 使模型绑定适用于没有默认构造函数的模型

    我一直在试图找到一种方法 让模型绑定与带有参数的构造函数的模型一起进行 那个行动 HttpPost public ActionResult Create Company company HttpPostedFileBase logo com
  • 如何在模型更改时停止ListView“跳跃”

    我需要做什么 我需要创建一个聊天窗口用一个ListView在 QML 中存储聊天消息 我设置listView positionViewAtEnd 以便跟踪最后的消息 我禁用positionViewAtEnd当我向上滚动时 我可以阅读过去的消
  • Magento:如何覆盖本地模块中的模型

    我试图在本地文件夹中覆盖本地文件夹中的模块 但我不知道是否可能 这就是我所做的 我创建了 local Mycompany Modulename Model Model php 我想覆盖 local Othercompany Modulena

随机推荐