不太确定我是否理解手册(或 vue.js)中的“非 prop 属性”: https: //v2.vuejs.org/v2/guide/components-props.html
假设我有 ChildComponent.vue 文件:
<template>
<input type="text" class="input" :value="childValue" v-on="listeners">
</template>
<script>
export default {
props: {
childValue: {
type: String,
default: 'blah',
}
},
computed: {
listeners() {
return {
// Pass all component listeners directly to input
...this.$listeners,
// Override input listener to work with v-model
input: event => this.$emit('input', event.target.value)
}
}
}
}
</script>
Run Code Online (Sandbox Code Playgroud)
然后我将它添加到 ParentComponent 中,如下所示:
<template>
<ChildComponent v-model="parentValue" placeholder="default" @keydown.enter="parentMethod"/>
</template>
<script>
export default {
data () {
return {
parentValue: "",
};
},
methods: {
parentMethod () {
...
}
},
}
</script>
Run Code Online (Sandbox Code Playgroud)
流程应该是(并且像这样工作) - 按 Enter 键后写入 ChildComponent 中的文本字段的任何内容都应该一直发送到 ParentComponent,并且parentValue应该parentMethod()被调用。
如果我理解正确的话 BasicComponent 是对其模板根组件的扩展,这意味着<input>不仅具有 props 类型和类集,而且placeholder(具有“默认”值)?
另外,这是否意味着分配数据v-model的 propparentValue也将传播到<input>element,从而使 my:value和v-onbind 冗余?
v-on="listeners"另一个问题 -在不指定事件的情况下到底是如何工作的,这是否意味着我正在监听每个事件?在父组件中有一个简写@keydown.enter,这意味着它正在监听 keydown.enter 事件,但在listeners()方法中我正在发出一个input事件......
我也很难理解listeners()方法中到底发生了什么,所以任何破译这一点的帮助将不胜感激。:D
预先感谢您的帮助。
干杯
让我们一次讨论一个主题......
Props 是您在对象中定义的参数props。使用 props,您可以告诉用户应该为给定的 prop 使用什么类型、是否需要、默认值、分配验证函数等。
此外,道具是反应性的,因此如果您的模板依赖于道具并且道具更新,那么您的模板也会更新。
您分配给组件但不对应于任何 props 的属性将传递给变量$attrs。您可以使用它来访问这些值,例如$attrs.id获取 id 或$attrs.name获取名称等。
是的,您在 上键入的内容ChildComponent 将被传递到ParentComponent. v-model它们通过 your和 via传递@keydown.enter="parentMethod"。
您可能知道事件是如何工作的,但如果您不知道,那么要点如下:当您需要将数据从子组件传递到父组件时,您可以在子组件中发出一个事件,并在父组件中侦听该事件。
例如,如果您想发出一个名为 foo 的事件,您可以$emit使用$emit('foo'). 然后,您可以通过添加到子级来在父级中监听它@foo="yourHandler",其中yourHandler编写了一个用于处理事件的函数。这就是你所做的@keydown.enter="parentMethod"。
<input>不仅有道具类型和类集,还有占位符(具有“默认”值)?:答:这要看情况。模板中的标记将接收的内容<input>取决于根元素 ( ) 是否<input>继承组件属性。inheritsAttrs该行为由组件的属性定义,默认为 true。
这意味着,在您的情况下,由于您没有指定inheritsAttrs它将默认为 true ,并且是的,您传递给的每个属性都<ChildComponent>将传递给您的<input>标签,除了您手动定义的内容。
由于您<input>像这样声明了标签:
<input type="text" class="input" :value="childValue" v-on="listeners">
Run Code Online (Sandbox Code Playgroud)
您的<input>标签将继承<ChildComponent> except type和value您的侦听器的所有属性(稍后会详细介绍)。该规则的例外是class和style,无论如何,它们总是被继承。
PS:请注意,type、class和placeholder是属性,而不是道具。
答:不可以,但是也行不通。原因如下:
当您使用这段代码声明侦听器时:
listeners() {
return {
// Pass all component listeners directly to input
...this.$listeners,
// Override input listener to work with v-model
input: event => this.$emit('input', event.target.value)
}
}
Run Code Online (Sandbox Code Playgroud)
listeners您将标记上放置的每个事件侦听器ChildComponent(包括您的事件)分配给您的计算属性keydown,这就是它起作用的原因。
分配是在这一行完成的:
...this.$listeners,
Run Code Online (Sandbox Code Playgroud)
$listeners它使用展开运算符将变量(保存所有组件事件)中的所有元素添加到您要返回的对象中。
您没有继承的唯一事件是input,如以下行中所定义:
input: event => this.$emit('input', event.target.value)
Run Code Online (Sandbox Code Playgroud)
通过这一行,您可以告诉代码,input事件的行为将是您定义的,而不是继承的。
然后,当您分配v-on="listeners"给输入时,您就是在告诉它监听listeners变量上列出的每个事件。也就是说:您将所有继承的事件和自定义input事件附加到输入事件中。
最后,要解释为什么它不是多余的但为什么它不起作用,您必须了解它是如何v-model工作的。它(通常)通过监听input组件的事件并使用它来更新value同一组件的 prop 来工作。所以在这一行中:
<ChildComponent v-model="parentValue" placeholder="default" @keydown.enter="parentMethod"/>
Run Code Online (Sandbox Code Playgroud)
你正在做两件事:
parentValue给value的 propChildComponentparentValue时进行更新。input这意味着为您的标签分配值和侦听器input并不是多余的,因为您需要它才能v-model正常工作,但它最终不会工作,因为您的组件没有道具value。它有一个childValue道具。
要修复它,您有两种选择:
childValue为valuechildValue模型要执行第二种方法,只需将这段代码附加到您的ChildComponent:
model: {
prop: 'childValue',
event: 'input'
}
Run Code Online (Sandbox Code Playgroud)
这将告诉您的组件使用该道具和该事件来工作v-model。
最后一点:将来,尝试将您的问题缩小到一个主题。回答起来会更容易,并且会帮助以后搜索这些主题的人。
| 归档时间: |
|
| 查看次数: |
7041 次 |
| 最近记录: |