vue 自定义组件使用v-model
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了vue 自定义组件使用v-model相关的知识,希望对你有一定的参考价值。
参考技术A v-model 是 Vue2 中唯一支持双向绑定的指令,用于表单控件绑定,但不代表它只能用在表单控件之上。在文档 使用自定义事件的表单输入组件 一节中提到了, v-model 其实是个语法糖。这不过是以下示例的语法糖:
也就是说,你只需要在组件中声明一个name为value的props,并且通过触发input事件传入一个值,就能修改这个value。
查看详情: demo
demo里我保留了一些测试的东西,希望你能看的明白
如果绑定多个值的话,建议我们用object对象类型,Array数组类型,也就是说我们接收的value类型需要改变下。
props的验证类型建议也看看: props的验证类型
Vue:从自定义组件派生的自定义组件中的 v-model 和输入事件
【中文标题】Vue:从自定义组件派生的自定义组件中的 v-model 和输入事件【英文标题】:Vue: v-model and input event in custom component derived of a custom component 【发布时间】:2018-10-03 23:51:09 【问题描述】:我有一个自定义输入,我在其中接收一个值道具并在输入事件上发出一个输入事件。我可以毫无问题地使用此自定义输入与模型,现在我正在创建一个自定义密码输入,我将其初始化为自定义输入,但我无法使用值和输入事件处理程序绑定模型(将它们传递给自定义输入) .我该如何处理?
自定义输入:
我的程序模型 > 自定义输入(值和输入事件处理程序):有效 我的程序模型 > 自定义密码(值和输入事件处理程序)> 自定义输入:不起作用。代码:
Input.vue:
<template>
<div class="form-group">
<label for="" v-if="typeof label !== 'undefined'"> label </label>
<!-- GROUP -->
<template v-if="isGroup">
<div class="input-group">
<!-- PREPEND -->
<div v-if="hasPrepend" class="input-group-prepend"
:class="'inside bg-transparent' : prependInside, 'pointer': prependPointer"
@click="clickPrepend">
<span class="input-group-text"
:class="'bg-transparent' : prependInside">
<i aria-hidden="true"
v-if="prependType === 'icon'"
:class="'fa fa-' + prependContent"></i>
<template v-if="prependType === 'text'"> prependContent </template>
</span>
</div>
<!-- INPUT -->
<input class="form-control"
:type="type"
:class="generatedInputClass"
:readonly="readonly"
:disabled="disabled"
:value="value"
@input="inputEvent"
@change="onChange">
<!-- APPEND -->
<div v-if="hasAppend" class="input-group-append"
:class="'inside bg-transparent' : appendInside, 'pointer': appendPointer"
@click="clickAppend">
<span class="input-group-text"
:class="'bg-transparent' : appendInside">
<i aria-hidden="true"
v-if="appendType === 'icon'"
:class="'fa fa-' + appendContent"></i>
<template v-if="appendType === 'text'"> appendContent </template>
</span>
</div>
</div>
</template>
<!-- INPUT -->
<template v-else>
<input class="form-control"
:type="type"
:class="generatedInputClass"
:readonly="readonly"
:disabled="disabled"
:value="value"
@input="inputEvent"
@change="onChange"
>
</template>
<small class="form-text"
v-if="typeof helpText !== 'undefined'"
:class="generatedHelperClass">
helpText
</small>
</div>
</template>
<script>
export default
name: 'InputGroup',
props:
value: String,
label: String,
helpText: String,
size: String,
prependContent: String,
appendContent: String,
prependType:
type: String,
default: 'icon',
,
appendType:
type: String,
default: 'icon',
,
prependInside:
type: Boolean,
default: false,
,
appendInside:
type: Boolean,
default: false,
,
prependPointer:
type: Boolean,
default: false,
,
appendPointer:
type: Boolean,
default: false,
,
readonly:
type: Boolean,
default: false,
,
disabled:
type: Boolean,
default: false,
,
type:
type: String,
default: 'text',
,
valid:
type: Boolean,
default: null,
,
,
watch:
valid()
,
,
computed:
isGroup()
return this.hasPrepend || this.hasAppend;
,
hasPrepend()
return typeof this.prependContent !== 'undefined';
,
hasAppend()
return typeof this.appendContent !== 'undefined';
,
generatedInputClass()
const size = typeof this.size !== 'undefined' ? `form-control-$this.size` : '';
let valid = '';
if (this.valid !== null)
valid = this.valid ? 'is-valid' : 'is-invalid';
return `$size $valid`;
,
generatedHelperClass()
let valid = 'text-muted';
if (this.valid !== null)
valid = this.valid ? 'valid-feedback' : 'invalid-feedback';
return `$valid`;
,
,
methods:
inputEvent(e)
this.$emit('input', e.target.value);
,
clickPrepend(e)
this.$emit('click-prepend', e);
,
clickAppend(e)
this.$emit('click-append', e);
,
onChange(e)
this.$emit('change', this.value, e);
,
,
;
</script>
Password.vue:
<template>
<div>
<app-input
:label="label"
:type="type"
prepend-content="lock"
:append-content="passwordIcon"
:append-inside="true"
:append-pointer="true"
@click-append="tooglePassword"
:value="value"
@input="inputEvent">
</app-input>
</div>
</template>
<script>
import Input from './Input';
export default
name: 'Password',
components:
appInput: Input,
,
props:
value: String,
label:
type: String,
default: 'Contraseña',
,
readonly:
type: Boolean,
default: false,
,
disabled:
type: Boolean,
default: false,
,
valid:
type: Boolean,
default: null,
,
,
data()
return
pass: '',
type: 'password',
;
,
computed:
passwordIcon()
return this.type === 'password' ? 'eye' : 'eye-slash';
,
,
methods:
tooglePassword()
this.type = this.type === 'password' ? 'text' : 'password';
,
inputEvent(e)
this.$emit('input', e.target.value);
,
,
;
</script>
【问题讨论】:
【参考方案1】:问题是你的Password
监听app-input
组件的input
事件,它的值实际字符串值已经,而不是元素(你必须调用@ 987654325@获取字符串值)
换句话说,在 Password.vue 中,而不是:
inputEvent(e)
this.$emit('input', e.target.value);
,
做:
inputEvent(e)
this.$emit('input', e);
,
CodeSandbox demo here.
【讨论】:
谢谢,现在我在 1 小时后弄明白了,但谢谢 :)以上是关于vue 自定义组件使用v-model的主要内容,如果未能解决你的问题,请参考以下文章