简体   繁体   English

如何更改在 vue3 中作为 props 传递的原始值?

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM