场景描述

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

封装成为组件

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>



自定义组件使用v-model的更多相关文章

  1. Android开发之自定义组件和接口回调

    说到自定义控件不得不提的就是接口回调,在Android开发中接口回调用的还是蛮多的.在这篇博客开始的时候呢,我想聊一下iOS的自定义控件.在iOS中自定义控件的思路是继承自UIView, 在UIVie ...

  2. Android自定义组件

    [参考的原文地址] http://blog.csdn.net/l1028386804/article/details/47101387效果图: 实现方式: 一:自定义一个含有EditText和Butt ...

  3. 自定义组件之MoreListView

    前言 本文针对自定义组件进行一些分析.还是那句老话“授之于鱼不如授之以渔”.今天要讲的是一个自定义的可以分页的ListView. 网上都讲了些ListView分页的方法,那么为什么我在这里还需要自己写 ...

  4. axure复用-自定义组件,母版(模板)

    组件(控件)是用于设计线框图的用户界面元素.在组件(控件)面板中包含有常用的控件库,如按钮.图片.文本框等.从组件面板中拖动一个控件到线框图区域中,就可以添加一个组件.组件可以从一个线框图中被拷贝(C ...

  5. ExtJS 自定义组件

    主要参考的是官方文档 <!DOCTYPE html> <html lang="en"> <head> <meta charset=&quo ...

  6. 如何在自定义组件中使用v-model

    文章属于速记,有错误欢迎指出.风格什么的不喜勿喷. 先来一个组件,不用vue-model,正常父子通信 <!-- parent --> <template> <div c ...

  7. 仿照admin的stark自定义组件的功能实现

    仿照admin的stark自定义组件的功能实现:其中最主要的就是增删改查的实现 1.查:首先页面中显示表头和数据,都是动态的,而不是写死的. (1) 先看表头和表单数据:这个是查看的视图函数,但是为了 ...

  8. vue框架之自定义组件中使用v-model

    通常 vue在html常见表单空间支持v-model双向绑定例如 <input v-model="message" placeholder="edit me&quo ...

  9. 自定义组件v-model的实质性理解

    用了几个月Vue一直很纠结自定义组件的v-model实现,最近开始学习React时,React中受控组件与状态提升的理念与v-model不谋而合. 转载请注明地址: https://www.cnblo ...

  10. Android自定义组件系列【6】——进阶实践(3)

    上一篇<Android自定义组件系列[5]--进阶实践(2)>继续对任老师的<可下拉的PinnedHeaderExpandableListView的实现>进行了分析,这一篇计划 ...

随机推荐

  1. 2023-04-02:设计一个仓库管理器,提供如下的方法: 1) void supply(String item, int num, int price) 名字叫item的商品,个数num,价格pri

    2023-04-02:设计一个仓库管理器,提供如下的方法: void supply(String item, int num, int price) 名字叫item的商品,个数num,价格price. ...

  2. 2021-08-26:长度为N的数组arr,一定可以组成N^2个数字对。例如arr = [3,1,2],数字对有(3,3) (3,1) (3,2) (1,3) (1,1) (1,2) (2,3) (2

    2021-08-26:长度为N的数组arr,一定可以组成N^2个数字对.例如arr = [3,1,2],数字对有(3,3) (3,1) (3,2) (1,3) (1,1) (1,2) (2,3) (2 ...

  3. 2021-10-01:矩阵置零。给定一个 m x n 的矩阵,如果一个元素为 0 ,则将其所在行和列的所有元素都设为 0 。请使用 原地 算法。进阶:一个直观的解决方案是使用 O(mn) 的额外空间

    2021-10-01:矩阵置零.给定一个 m x n 的矩阵,如果一个元素为 0 ,则将其所在行和列的所有元素都设为 0 .请使用 原地 算法.进阶:一个直观的解决方案是使用 O(mn) 的额外空间, ...

  4. distinct()去重

    distinct()去重 Student.objects.all().distinct()

  5. 深度学习基础入门篇[8]::计算机视觉与卷积神经网络、卷积模型CNN综述、池化讲解、CNN参数计算

    深度学习基础入门篇[8]::计算机视觉与卷积神经网络.卷积模型CNN综述.池化讲解.CNN参数计算 1.计算机视觉与卷积神经网络 1.1计算机视觉综述 计算机视觉作为一门让机器学会如何去"看 ...

  6. python如何利用算法解决业务上的【分单问题】

    分单是很多企业日常工作中非常典型的一项内容,它非常复杂,但同时又极为重要,如何合理的分单是企业管理中一个很重要的课题. 之所以说分单很复杂,是因为影响单据该分给谁,分多少量这个事儿本身就有太多的影响因 ...

  7. 使用c#实现23种常见的设计模式

    使用c#实现23种常见的设计模式 设计模式通常分为三个主要类别: 创建型模式 结构型模式 行为型模式. 这些模式是用于解决常见的对象导向设计问题的最佳实践. 以下是23种常见的设计模式并且提供c#代码 ...

  8. STM32F429 Discovery开发板应用:实现SPI-SD Card文件写入(搭载FatFS文件系统)

    MCU:STM32F429ZIT6 开发环境:STM32CubeMX+MDK5 外购了一个SPI接口的SD Card模块,想要实现SD卡存储数据的功能. 首先需要打开STM32CubeMX工具.输入开 ...

  9. .NET周报 【6月第1期 2023-06-04】

    专题 - NanoFramework项目案例 如果有时间,我会在周报中加入一些专题和项目案例的分享,本周就是讨论.NET NanoFramework项目案例的专题,在讨论 NanoFramework ...

  10. @SafeVarargs注解的使用

    在声明具有模糊类型(比如:泛型)的可变参数的构造函数或方法时,Java编译器会报unchecked警告.鉴于这些情况,如果程序员断定声明的构造函数和方法的主体不会对其varargs参数执行潜在的不安全 ...