从Pinia Store传入的Props能否直接修改?Vue3组件实践疑问
Vue3 + Pinia 场景下组件更新 Store 的最佳实践疑问
我之前常用Vue2快速开发单文件应用,现在转用Vue3、多组件配合Pinia开发,想请教组件更新Store的基础知识。
按我之前的组件使用经验,永远不应该直接修改Props,但我在一个基础应用里给Props用v-model居然成功运行了。
我的代码情况
Pinia Store 定义
import { defineStore } from "pinia"; export default defineStore("form", { state: () => ({ screens: [ { fields: [ { type: "text", name: "name" }, { type: "email", name: "email" }, ], }, { fields: [ { type: "number", name: "age" }, { type: "date", name: "start_date" }, ], }, ], }), });
父表单组件代码
<template> <h1>Create a form</h1> <div class="stack form"> <AdminScreen v-for="(screen, s) in form.screens" :key="`screen-${s}`" class="admin-screen" > <AdminField v-for="(field, f) in screen.fields" :key="`field-${f}-${s}`" :field="field" /> </AdminScreen> </div> </template> <script setup> import useFormStore from "../../useFormStore.js"; import AdminField from "../../components/AdminField.vue"; import AdminScreen from "../../components/AdminScreen.vue"; const form = useFormStore(); </script>
AdminField 组件代码
<template> <label :for="`label-${id}`">Label</label> <input :id="`label-${id}`" type="text" v-model="field.label" @change="setKey()" /> </template> <script setup> // 假设 lettersAndNumbersOnly 是已定义的工具函数 const props = defineProps({ field: Object }); const setKey = () => { if (!props.field.key) { props.field.key = lettersAndNumbersOnly(props.field.label) .toLowerCase() .trim() .replaceAll(" ", "_"); } }; </script>
我的疑问
目前代码运行正常,但看了Vue单向数据流的相关内容后开始担心:
- 我这种直接修改Props里对象属性的做法是否可行?
- 如果不可行,最佳的重构方式是什么?
我研究过Pinia的修改逻辑,也考虑过两种方向:
- 给AdminField传递唯一ID,在组件里直接调用Store的方法修改状态
- 像Vue2那样用
emit,在父组件的AdminField节点上添加复杂监听器,比如<AdminField @updated="$store.commit({screenIndex: s, fieldIndex: f})" />来更新Store
不确定哪种方式更符合Vue3+Pinia的最佳实践?
内容的提问来源于stack exchange,提问作者Djave
相关产品推荐
相关产品推荐

