我是Vue的新手,试图构建一个“下拉”组件。我想从父组件使用它,如下所示:
<my-dropdown v-model="selection"></my-dropdown>
其中,selection
在父节点上存储为data
,应该更新以反映用户的选择。要做到这一点,我相信我的下拉组件需要一个value
prop ,它需要在选择更改时发出input
事件。
但是,我还想从子对象本身修改value
,因为我希望能够单独使用下拉组件(我需要修改它,因为如果单独使用组件,UI将不会更新以反映新选择的值)。
有没有一种方法可以像上面那样绑定v-model
,但也可以在子对象内部修改值(似乎我不能,因为value
是一个prop,子对象不能修改自己的prop)。
6条答案
按热度按时间e1xvtsh31#
您需要有一个本地值的计算属性代理来处理输入/值。
现在你可以设置你的模板使用
mySelection
值来管理你在这个组件中的数据,当它改变时,数据会正确地发出,并且当你在父组件中使用它时,数据总是与v-model(selected
)同步。3b6akqbq2#
Vue的理念是:“** prop 下降,事件上升**"。它甚至在文档中这样说:组成组件。
组件应该一起使用,最常见的是父子关系:组件A可以在其自己的模板中使用组件B。他们不可避免地需要彼此沟通:父母可能需要将数据向下传递给孩子,孩子可能需要将孩子发生的事情通知父母。然而,通过一个明确定义的接口,尽可能地保持父节点和子节点的解耦也是非常重要的。这确保了每个组件的代码都可以相对独立地编写和推理,从而使它们更易于维护,也更容易重用。
在Vue中,父子组件关系可以总结为props down,events up。父节点通过props将数据传递给子节点,子节点通过事件向父节点发送消息。让我们看看他们接下来是如何工作的。
不要尝试从子组件内部修改值。告诉父组件一些事情,如果父组件关心的话,它可以做一些事情。让child组件改变事情会给child太多的责任。
62lalag43#
您可以使用以下模式:
1.接受1个输入属性
1.在数据中添加其他变量
1.在创建时,将传入的prop写入数据变量
1.使用监视器,监视传入的 prop 的更改
1.在组件内部进行更改时,将更改发送出去
演示:
请注意,这个演示有一个功能,您可以关闭每个选择框的事件传播,因此您可以测试值是否在本地正确更新,这当然不是生产所需的。
pdsfdshx4#
如果你想在组件中修改一个prop,我建议你传递一个“默认值”prop给你的组件。我会这么做
接下来我有两个选择
选项1 -自定义下拉元素
由于您使用的是自定义HTML,因此无法设置选定的属性。所以你的方法要有创意。在组件内部,可以在创建组件时将默认值
prop
设置为数据属性。您可能希望以不同的方式执行此操作,并使用watcher
。我已经将其添加到下面的示例中。$emit
将把数据传递回父组件,而父组件不会被修改。如果您使用的是标准的select
元素,则不需要这样做。选项2 -标准
select
这个方法绝对是最简单的,这意味着您需要使用默认的
select
元素。8i9zcol25#
您可以使用自定义表单输入组件
使用自定义事件的表单输入组件
基本上,自定义组件应该接受
value
属性,并在值更改时发出input
事件azpvetkf6#
与@zero298的answer相呼应,Vue 3指南明确指出,组件不修改(内部) prop 是一种最佳实践:
对象/数组 prop 突变
当对象和数组作为prop传递时,虽然子组件不能改变prop绑定,但它将能够改变对象或数组的嵌套属性。这是因为在JavaScript中,对象和数组是通过引用传递的,而Vue要防止这种变化是不合理的。
这种变化的主要缺点是,它允许子组件以一种对父组件不明显的方式影响父组件的状态,这可能会使将来更难以推理数据流。作为最佳实践,您应该避免这种变化,除非父级和子级在设计上是紧密耦合的。在大多数情况下,子节点应该发出一个事件,让父节点执行变异。
因此,即使它是“可能的”,它也不是“最佳实践”。
$emit
事件,并让父级修改自己的状态。