[英]How to change the original value passed as props in vue3?
Assume you have a todo-list
component that will render the passed todos
for you.假设您有一个
todo-list
组件,它将为您呈现传递的todos
。 where the todos
is an Ref
object.其中待办事项是
Ref
todos
。
<todo-list :todos="todos"/>
And the todo-list
component also allow user to delete any of the passed todos.并且
todo-list
组件还允许用户删除任何传递的 todos。
But vue3 won't let us to mutate the props.todos
object.但是 vue3 不会让我们改变
props.todos
object。
So the only way to do this is make a clone of props.todos
, then if user click on the delete button, remove the item from that cloned one to update the view.所以这样做的唯一方法是克隆
props.todos
,然后如果用户单击删除按钮,从克隆的项目中删除项目以更新视图。 But this approach won't make change to the original passed todos
Ref object.但是这种方法不会改变原来通过的
todos
Ref object。
Another way to workaround this is emit an itemDeleted
event from the todo-list
, listen it from it's parent component, then remove the deleted item from the original passed todos
Ref object in the listener.解决此问题的另一种方法是从
todo-list
发出一个itemDeleted
事件,从它的父组件中侦听它,然后从侦听器中的原始传递的todos
Ref object 中删除已删除的项目。
But I want to keep all the logic inside of the todo-list
itself, so I want to know if there is any way to change the original todos
Ref object inside the todo-list
component.但是我想将所有逻辑保留在
todo-list
本身中,所以我想知道是否有任何方法可以更改todo-list
组件内的原始todos
Ref object。
I know a better solution could be using v-model:todo-list
, and emit a update:todo-list
event to update the original todo-list
Ref object.我知道一个更好的解决方案可能是使用
v-model:todo-list
,并发出一个update:todo-list
事件来更新原始的todo-list
Ref object。 But I'm wondering if I can do this without the v-model
directive.但我想知道我是否可以在没有
v-model
指令的情况下做到这一点。
Put the todos
in separate file called useTodo.js
which defines a composable function that could be reusable across multiple components without using any inner property or passing props:将
useTodo.js
todos
单独文件中,该文件定义了一个可组合的 function ,无需使用任何内部属性或传递道具即可跨多个组件重用:
import {ref} from 'vue'
const todos=ref([])
const useTodo= () => {
setTodos(_todos){
todos.value=_todos;
}
return {todos, setTodos}
}
export default useTodo
then import it in both parent todolist components然后在两个父 todolist 组件中导入它
parent component:父组件:
<todo-list />
...
import useTodo from './useTodo'
...
setup(){
const {todos, setTodos}=useTodo();
//use todos instead of your todos with ref
}
in todolist component:在 todolist 组件中:
...
import useTodo from './useTodo'
...
setup(){
const {todos, setTodos}=useTodo();
//use todos instead of props.todos
}
Another way to workaround this is emit an itemDeleted event from the todo-list, listen it from it's parent component, then remove the deleted item from the original passed todos Ref object in the listener.
解决此问题的另一种方法是从待办事项列表中发出一个 itemDeleted 事件,从它的父组件中侦听它,然后从侦听器中的原始传递的 todos Ref object 中删除已删除的项目。
This is the ideal way of solving this type of problem.这是解决此类问题的理想方法。
The Vue philosophy is props down, events up. Vue 的哲学是道具向下,事件向上。 See: https://medium.com/quick-code/vue-communication-patterns-an-intro-to-props-down-and-events-up-pattern-d53340d2c94
请参阅: https://medium.com/quick-code/vue-communication-patterns-an-intro-to-props-down-and-events-up-pattern-d53340d2c94
As components grow progressively more complex keeping the logic that actually edits the data in the same top level component that stores the data is preferable.随着组件变得越来越复杂,最好将实际编辑数据的逻辑保留在存储数据的同一顶级组件中。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.