VUE 开发求助

52 天前
 andyshz

请问 VUE 佬们在开发大表单的时候怎么设计绑定对象的?直接在 data 中声明所有表单项来绑定吗?那岂不是会有很多冗余代码?而且如果多个组件都使用这个对象,对象在传递的时候是不是每个组件中又需要声明一次? 刚从后端学习前端,希望能有大哥指点指点,按照后端的逻辑,这个表单不是应该设计为一个对象,每个组件直接复用对象即可,传递也传递对象,但是现在开发过程中出现不少问题,搜了之后好像说不能绑定 js 的类对象。。。。。。

3289 次点击
所在节点    Vue.js
18 条回复
lyonbot
52 天前
你需要的是不是 store 或者说是全局状态管理?
andyshz
52 天前
并不全是吧,主要我只想要这个对象在一个模块中使用,并且希望做到的就是尽可能地减少冗余代码,我对这一块地设计不是很熟悉
VUEX 和 PINIA 可以是模块级的吗
Dlad
52 天前
1 、可以全局声明;
2 、每个页面都声明一次,代码冗余了,因为做到了按需加载,程序执行效率反而更好。
3 、我们项目中的实践是:element ui 打底,常用类型不自行开发了;复杂业务逻辑字段,定制成组件(我好兄弟用自己名字命名的组件,开始看着头痛,后来习惯了);整个表单需要复用,全局弹出呼出——表单、逻辑全复用了。
4 、有些变量,全局各处展示需要实时更新的,放在 pinia store 里面。

我不是职业搞前端的,对最佳实践了解有限。我们自研的 vue 项目按一般软件工程逻辑优化到这个程度。
M003
52 天前
方法 1. 父级声明出大对象,然后 v-model 将整个大对象 绑定到子组件;子组件内可以定义变量,也可以不声明变量,子组件可以监听到父组件传递给子组件的 value, 然后深拷贝覆盖子组件声明的变量(未声明直接赋值,当然必须声明个变量是 undefined ), 修改这个变量,监听变量变化,$emit 传递出去给父组件。

方法 2. 父组件声明出大对象,对象结构明确。给每个子组件只传递需要的对象中的参数,只修改父组件对象中的某个参数,这样不方便于别的组件读取其他变量。(传递方法和上面一样。)


就不用 store 了。

我这是野路子,自己写代码摸索的。
Elissa
52 天前
data 中一般放一个 form 对象,内部属性对应每个表单内容
```js
data: {
form: {
name: undefine,
age: undefine,
......
}
}
```

优先用组件库的表单组件,这样直接 v-model 绑定 form.xxx 到组件库的组件上

如果需要复杂填写,通过传参或将 form.xxx 传入自定义组件,组件内部自行实现 v-model 或通过事件总线修改值
hafuhafu
51 天前
工厂模式。你可以写一个函数用来生成这个对象,而不是直接定义对象。
SaigyoujiNono
51 天前
我一般 export form
然后 form: { ...form }
wangtian2020
51 天前
多层数据传递直接扔 pinia store 里,组件要的时候自己去取,想当于一个全局共享的 ref 对象。单层就随便传传了,看你自己怎么方便,不要教条
我甚至单层传递都不用 props 传,我用 ref 调用组件主动 expose 的方法,用方法传参一次性传递。
watch props 的操作我觉得很蠢
layxy
51 天前
我也是后端,如果页面复杂,尤其有分步操作,建议上状态管理(vue2 的 vuex 或 vue3 的 pinia),但是使用状态管理也有个操蛋的事情,状态读数据和写数据时分开的,虽然可以在 computed 中 get,set,但是这个机制我没搞明白如果获取的对象是个复杂嵌套对象,我修改深层的属性值,这种用法是否正确
heybwei
51 天前
其实你的问题描述得不是让人很明白,如果能贴一些大概的结构或伪代码就好了
chenluo0429
51 天前
如果你有一个大的表单对象,有很多字段,然后需要用不同的表单组件去提供对应字段的编辑,正确的实践是子组件只关注它要显示和修改的字段值,并不需要关心原生的大对象。
如果每个子组件都要关注原生的对象的话,应当用 provide/inject 实现局部的状态共享。如果状态是全局唯一的话,也可以使用 pinia 这种全局状态管理去做。
faceRollingKB
51 天前
表单设计不建议使用 vuex 或 pinia ,这两个都是用来管理全局变量的,管理局部模块化数据的话就有点吃力,我是使用 vue 自带的 providers ,再根据自己的想法封装了一套依赖注入来实现的,整体表单通过 FormModel 管理数据和表单项配置,并共享给整个组件树,每个表单项也都有专门的 FormControl 来对接表单的各种操作,但是从 0 到 1 的成本有点高,你要有心理准备
SchwarzeR
51 天前
vue3 如果需要局部状态管理,业务上存在大量复用有必要封装的话,并且不需要考虑 ssr 的情况下,可以通过声明一个 Composition api 的函数( hook )做一个局部的变量初始化,然后用在需要的地方。这个在 https://cn.vuejs.org/guide/reusability/composables 亦有记载

但是如果会涉及到 ssr 的话,pinia 也可以做局部的模块化声明,就是麻烦一点
```
// 需要传参根据情况改变内容上的时候就给函数加参数
function useXXXFormData() {

const onShow = ref(true)

const formContextState = reactive({
xxx:12123,
xxl:123,
process:123,
onSync: false
})

// 内部使用 vue 的生命周期 api 比如销毁时清理
onBeforeUnmount(() => {
console.log("unmounted!");

})


return {
onShow,
formContextState
}
}
```
直接拿代码给你比方?
在需要拿来初始化调用的时候直接
const formstate = useXXXFormData()

不知道我理解的正确不正确
faceRollingKB
51 天前
示例:

<script setup lang="ts">
const form = Provide(FormModel<TData>);
form.mode = FormMode.edit;
form.items = [
describeControl({
type: controlWrap('t-input'),
label: 'xxx:',
prop: 'yyy',
value: '',
validator: [FormValidator.required, FormValidator.max(50)],
options: {
placeholder: '请输入 xxx'
}
}),
];
form.resetData();
function onConfirm() {
form
.validate()
.then(() => {
return service.save(form.data);
})
.then(() => {
MessagePlugin.success('操作成功');
})
.catch((err) => {
MessagePlugin.error(err?.message || err);
});
};
</script>

<template>
<div v-if="form.data" v-grid.form="2" class="ph-20 gr-24 gc-12 mb-24">
<q-form-item prop="aaa"></q-form-item>
<q-form-item prop="bbb"></q-form-item>
<q-form-item v-if="form.data.bbb === '???'" prop="ccc"></q-form-item>
<q-form-item prop="ddd"></q-form-item>
</div>
</template>

<style scoped lang="less"></style>
chobitssp
51 天前
class + ref
xingyuc
51 天前
不同场景不同用法,写的再优雅也抵不过 AI 的冲击
jspatrick
51 天前
页面声明大对象,再 provide/inject ,跨页面考虑 store
wentx
51 天前
vibe 了。。 也不知道 cursor 是咋写的,但是能用

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/1149136

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX