不太确定我是否能从手册(或完全vue.js)中了解“非属性”:https://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>
然后我将其添加到ParentComponent中,如下所示:
<template>
<ChildComponent v-model="parentValue" placeholder="default" @keydown.enter="parentMethod"/>
</template>
<script>
export default {
data () {
return {
parentValue: "",
};
},
methods: {
parentMethod () {
...
}
},
}
</script>
该流应该是(并且是这样工作的)-在按下Enter键之后,写入ChildComponent中文本字段的任何内容都应一直发送到ParentComponent,因为parentValue
和parentMethod()
应该被调用。< / p>
如果我正确理解BasicComponent是其模板根组件的一种扩展,则意味着<input>
将不仅具有props类型和class set,而且还将placeholder
(具有“ default”值)?
这是否也意味着分配了v-model
数据的parentValue
道具也将传播到<input>
元素,使我的:value
和v-on
绑定冗余吗?
另一个问题-v-on="listeners"
在没有指定事件的情况下如何工作,这是否意味着我在监听每个事件?
在父组件中,有一个简写的@keydown.enter
,表示它正在侦听keydown.enter事件,但是在listeners()
方法中,我发出了一个input
事件……
我也很难理解listeners()
方法中发生的一切,因此,对破译它的任何帮助将不胜感激。 :D
预先感谢您的帮助。
欢呼
答案 0 :(得分:1)
让我们一次做一个主题...
道具是您在props
对象中定义的参数。使用props,您可以告诉用户应该为给定prop使用什么类型,是否需要它们,默认值,分配验证功能等。
道具也是反应性的,因此,如果您的模板依赖于道具并且道具进行更新,那么模板也会如此。
您分配给组件的属性,但不与任何属性对应,将传递给$attrs
变量。您可以使用它来访问这些值,例如$attrs.id
获取ID,或$attrs.name
获取名称,等等。
是的,您在ChildComponent
上键入的内容已被传递给ParentComponent
。它们通过您的v-model
和@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">
您的<input>
标记将继承<ChildComponent>
除外 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)
}
}
您要为放置在listeners
标记上的每个事件侦听器(包括您的ChildComponent
事件)分配给keydown
计算属性,这就是它起作用的原因。
分配在这一行中完成:
...this.$listeners,
它使用传播运算符将$listeners
变量(包含所有组件事件)中的所有元素添加到要返回的对象中。
您不继承的唯一事件是input
,如以下行所示:
input: event => this.$emit('input', event.target.value)
在这一行中,您告诉代码input
事件的行为将是您定义的行为,而不是继承的行为。
然后,当您将v-on="listeners"
分配给输入时,就是告诉它侦听listeners
变量中列出的每个事件。也就是说:您要将所有继承的事件和自定义input
事件附加到输入事件。
最后,要解释为什么它不是多余的但为什么它不起作用,您必须了解v-model
的工作方式。 (通常)通过侦听组件的input
事件并使用它来更新同一组件的value
属性来进行工作。所以在这一行:
<ChildComponent v-model="parentValue" placeholder="default" @keydown.enter="parentMethod"/>
您正在做两件事:
parentValue
的值分配给value
的{{1}}道具ChildComponent
事件时更新parentValue
。这意味着为您的input
标签分配一个值和侦听器不是多余的,因为您需要它来使input
正常工作,但是最终将无法工作,因为您的组件没有v-model
道具。它有一个value
道具。
要解决此问题,您有两种选择:
childValue
重命名为childValue
value
作为模型要执行第二种方法,只需将这段代码附加到您的childValue
:
ChildComponent
这将告诉您的组件使用该道具和该事件来使model: {
prop: 'childValue',
event: 'input'
}
工作。
最后的提示:将来,请尝试将问题缩小到单个主题。这样会更容易回答,并会帮助以后搜索这些主题的人。