首页 > 其他分享 >自定义组件使用v-model

自定义组件使用v-model

时间:2023-08-13 10:11:28浏览次数:38  
标签:return name 自定义 张三 组件 model id

场景描述

我们在一个系统中,会出现这样的情况,
有一个联系人的下拉框,这个下拉框中的数据是从服务端获取的。
在很多页面都需要使用这个联系人(下拉框)。
我们通常是这样做的:
写一个下拉框组件然后调用接口。
这样不仅会造成代码冗余,而且不利于后期的维护。
比如说:如果有一天这个要发生变化,如果整个系统中有几十处。
难道我们要更改几十处?不会吧。这样好难受呀。
有的小伙伴说:这个还不简单:封装成为一个组件呀。

封装成为组件

concatPersonSelect.vue

<template>
  <el-form ref="form" :model="form" label-width="80px">
    <el-form-item label="联系人">
      <el-select v-model="form.person" placeholder="请选择活动区域">
        <el-option v-for="(item,index) in listAtt" :key="index" :label="item.name" :value="item.id"></el-option>
      </el-select>
    </el-form-item>
</el-form>
</template>
<script>
  export default {
    data() {
      return {
        listAtt:[],
        form: {
          person: '',
        }
      }
    },
    created() {
      this.getUserList()
    },
    methods: {
      // 模拟接口
      getUserList(){
        setTimeout(()=>{
          this.listAtt = [{
            name:'张三1',id:1
          },{
            name:'张三2',id:2
          },{
            name:'张三3',id:3
          },{
            name:'张三4',id:4
          }]
        },1600)
      }
    },
   
  }
</script>

页面使用

<template>
  <div>
    <h2>自定义组件也可以使用v-model</h2>
    <concatPersonSelect></concatPersonSelect>
  </div>
</template>
<script>
export default {
  components:{
    concatPersonSelect
  },
  data(){
    return{
      
    }
  }
}
</script>

现在遇见的问题

是的,现在我们是把它封装成为了一个组件。
但是如果获取组件中的值呢?
这........,思考一会。
机智的小伙伴说:子组件提供一个方法,父组件通过ref的方式去调用。
那如果要赋值呢?子组件也提供一个方法,父组件去使用。
这样就可以获取值,赋值了。(耶,简直是一个天才)
这样虽然可以,但是真的优点繁琐,还有其他好的方法吗?
我们可以使用v-model,是的,我们给自己封装的组件使用v-model

组件中使用v-model的想法

我们给下拉框绑定一个 change 事件,这样值发生变化后。
通过 this.$emit 去更新。
与此同时,v-model中的值是 data中的 userValue 值。
userValue 中的值是从props中来的。
然后使用 model 中的 event 属性与 emit 事件保持一致

改造组件,组件可以使用 v-model

<template>
  <el-form ref="form"  label-width="80px">
    <el-form-item label="联系人">
      <el-select @change="changeGetValue" v-model="userValue" placeholder="请选择活动区域">
        <el-option v-for="(item,index) in listAtt" :key="index" :label="item.name" :value="item.id"></el-option>
      </el-select>
    </el-form-item>
</el-form>
</template>
<script>
  export default {
    model: {
      event: 'input-change', // 这个事件与下面的emit事件与之对应
      prop: 'propsInfoValue' // 
    },
    props:{
      // 父组件传递的值,用于数据回填
      propsInfoValue:{
        type:String,
        default:()=>{
          return ''
        }
      }
    }, 
    data() {
      return {
        listAtt:[],
        userValue: this.propsInfoValue
      }
    },
    created() {
      this.getUserList()
    },
    methods: {
      // 模拟接口
      getUserList(){
        setTimeout(()=>{
          this.listAtt = [{
            name:'张三1',id:'1'
          },{
            name:'张三2',id:'2'
          },{
            name:'张三3',id:'3'
          },{
            name:'张三4',id:'4'
          }]
        },1600)
      },
      // 值发生变化会被触发,就去更新
      changeGetValue(){
        this.$emit('input-change', this.userValue)
      }
    }
  }
</script>

页面就可以使用 v-model 了

<template>
  <div>
    <h2>自定义组件也可以使用v-model</h2>
    <concatPersonSelect v-model="obj.name" ></concatPersonSelect>
    <el-button @click="getHandler"> 获取值 </el-button>
  </div>
</template>
import concatPersonSelect from '../components/concatPersonSelect/concatPersonSelect.vue'
export default {
  components:{
    concatPersonSelect
  },
  data(){
    return{
      obj:{
        name:''
      }
    }
  },
  methods: {
    getHandler(){
      console.log('获取的值', this.obj)
    }
  }
}

如何有必填参数怎么搞?

我们都知道,如果某一个参数是必填的话。
在elementui中的form表单中。
需要同时满足两个条件,那就是:
rules 属性传入约定的验证规则,
并将 Form-Item 的 prop 属性设置为需校验的字段名即可。
因此,子组件中的 el-form-item中应该有一个 prop属性,
并且这个属性的值与 rules属性中的规则字段相同就行。
我们打算在子组件中使用  
v-bind="$attrs" 和 inheritAttrs: false,
这样页面中的参数可以直接进行传递

更新优化子组件

<template>
  <div>
    <el-form-item label="联系人"  v-bind="$attrs">
      <el-select @change="changeGetValue" v-model="userValue" placeholder="请选择联系人">
        <el-option v-for="(item,index) in listAtt" :key="index" :label="item.name" :value="item.id"></el-option>
      </el-select>
    </el-form-item>
  </div>
</template>
<script>
  export default {
    model: {
      event: 'input-change', // 这个事件与下面的emit事件与之对应
      prop: 'propsInfoValue' // 
    },
    props:{
      // 父组件传递的值,用于数据回填
      propsInfoValue:{
        type:String,
        default:()=>{
          return ''
        }
      }
    }, 
    inheritAttrs: false, //不让属性直接渲染在根节点上
    data() {
      return {
        listAtt:[],
        userValue: this.propsInfoValue
      }
    },
    created() {
      this.getUserList()
    },
    methods: {
      // 模拟接口
      getUserList(){
        setTimeout(()=>{
          this.listAtt = [{
            name:'张三1',id:'1'
          },{
            name:'张三2',id:'2'
          },{
            name:'张三3',id:'3'
          },{
            name:'张三4',id:'4'
          }]
        },1600)
      },
      // 值发生变化会被触发,就去更新
      changeGetValue(){
        this.$emit('input-change', this.userValue)
      }
    },
   
  }
</script>

页面使用

<template>
  <div>
    <h2>自定义组件也可以使用v-model</h2>

    <el-form :rules="rules" :model="ruleForm" ref="form"  label-width="80px">
      <el-form-item label="活动名称" prop="activeName">
        <el-input v-model="ruleForm.activeName"></el-input>
      </el-form-item>

      <!-- prop中的值必须与验证规则中的字段保持一致,否者无法验证 -->
      <concatPersonSelect prop="personName" v-model="ruleForm.personName" >
      </concatPersonSelect>

      <el-button @click="getHandler"> 获取值 </el-button>
    </el-form>
    
  </div>
</template>

<script>
export default {
  components:{
    concatPersonSelect
  },
  data(){
    return{
      // 表单中的字段
      ruleForm:{
        activeName:'',
        personName:''
      },
      // 验证规则以及提示语
      rules: {
        activeName: [
          { required: true, message: '请输入活动名称', trigger: 'blur' },
        ],
        personName: [
          { required: true, message: '请选联系人', trigger: 'change' }
        ]
      }
    }
  },
  methods: {
    getHandler(){
      console.log('获取的值', this.ruleForm)
      
      this.$refs['form'].validate((valid) => {
        // 验证规则成功
        console.log(1,valid)
      })
    }
  }
}
</script>


标签:return,name,自定义,张三,组件,model,id
From: https://www.cnblogs.com/IwishIcould/p/17613620.html

相关文章

  • ❤ React07-React 组件的生命周期2
    函数周期render生命周期渲染componenetDidUpdate()生命周期更新注意部分:seState应该放在判断if里面ajax的请求部分应该放在这里组件的生命周期三卸载阶段......
  • 在 Spring Framework 中实现自定义 AOP 切面
    在SpringFramework中,面向切面编程(AOP)是一种重要的编程范式,它允许我们在应用程序中以模块化的方式处理横切关注点(如日志记录、事务管理等)。本文将深入探讨如何使用SpringFramework实现自定义AOP切面,通过代码示例演示其实际应用。1.概述AOP的核心思想是将横切关注点与主要......
  • mac下配置git自定义快捷命令
    mac下配置git自定义快捷命令 对于经常使用终端命令来对git仓库进行操作来说,如果能用别名来代替,那可太省事了。mac就支持这样的配置 1.指定自定义别名 vi ~/.bash_profile 配置环境变量,插入类似下面的内容(等号右边的别名根据自己习惯自定义即可):1aliasgcd='git......
  • WPF自定义控件实战:自制上传文件显示进度按钮
    自定义控件在WPF开发中是很常见的,有时候某些控件需要契合业务或者美化统一样式,这时候就需要对控件做出一些改造。 目录按钮设置圆角按钮上传文件相关定义测试代码 话不多说直接看效果默认效果:上传效果:按钮设置圆角因为按钮本身没有CornerRadius属性,所......
  • 基于scheduler framework开发自定义调度器
    k8sv1.19.0基于schedulerframework开发插件,本质上是实现接口。下载代码mkdirsigs.k8s.iocdsigs.k8s.iogitclonehttps://github.com/kubernetes-sigs/scheduler-plugins.gitcdscheduler-pluginsgitcheckoutrelease-1.19新增代码pkg目录下新增label_a_b目录packag......
  • Odoo12_自定义导出excel
    1.首先按钮或者菜单出发一个后端方法返回url动作defdownload_xxx_excel(self):url='/export_xxx_excel?id={self.id}return{'type':'ir.actions.act_url','url':url,'tar......
  • Qt自定义控件之动画文本
    @TOC前言在Qt中,自定义控件可以让我们实现丰富的用户界面效果和交互体验。其中,动画文本是一种常见的效果,通过文本的动态变化可以吸引用户的注意力,增强用户体验。本文将介绍如何使用Qt实现一个动画文本的自定义控件,让你的应用程序更加生动活泼。一、动画文本的效果功能实现:基础功......
  • 开源日志组件Sejil--附带日志管理界面
    1.开源日志组件源码: https://github.com/alaatm/Sejil2.下载下来发现里面对于不同的.netcore版本的配置提供了对应的示例 .NetCore3.1Program.cs文件中publicclassProgram{publicstaticvoidMain(string[]args)=>CreateHostBuilder(args).B......
  • 在传奇游戏界面添加或删除自定义功能按钮
    本教程是以HERO引擎和非凡登录器(原猎鹰登录器)为例进行示范,其他引擎请自行进行测试,。自定义功能按钮就是在游戏界面中处于小地图,组队等按钮上面的一排可自定义进行功能设置的按钮,如图中所示,用方框选中的就是想要达到的效果。以下是具体添加方法:首先要下载下面我们给大家准备好的一......
  • 组合式api-ref引用子组件、dom元素, defineExpose的使用
    和vue2一样,我们有时候希望父组件能够调用子组件中的方法、属性。那么就要用到ref。然后你会发现,根本调用不了子组件中的方法"sonSayHi",如下图:原因:使用......