对于使用Vue表单有一些疑问:
- < form >内部项目适合分离出组件吗?
今天专案有一个表单,如下图:
- 每个项目的input/select/textarea都有各自的标题、错误消息、id、name,
- 每个组合有可能1~5个项目(input/select/textarea)组成,每个组合都有各自的Icon
- 每个项目(input/select/textarea)操作都会影响该组合的icon
这样的表单,单组合适合分离出component吗?
会想分离成component是因为需要为每个设置data值:focus: false
照上述需求,分离出一个有两项目的组合就30行
(使用Pug、bootstrap vue、vuelidate验证)
- 如果页面上有完全一样的表单,会同时出现,这样要如何自动带变量给component?
(用来更改内部组件id)
会出现在不同区块,不能用v-for带index值
还是只能手动调整带入的index值?
类似v-bine-index=‘1’、v-bine-index='2’之类
完全不拆分组件,本不相关的状态和逻辑就会耦合在一起,增加心智的负担;
拆分组件过细,原本相关的状态和逻辑就会分散到多处,增加记忆的负担。
该不该拆分组件、应该怎么拆,就是在这两个极端之间做平衡取舍,取自己最能接受的程度即可。
另外,如果有大量动态生成元素的需求(而不是在既定的元素组合——也就是模板——之间通过固定条件做选择),可以考虑 JSX。
文字使用不正确,造成不舒服感到很抱歉。
已修正询问内文,下次会注意的。
如果就一个项目在用,那自然是不用封装成组件啦。
如果有多个项目都在用这种表单,且存在拷贝粘贴拷贝粘贴拷贝粘贴这种繁琐的劳动量的时候呢,就需要考虑封装一个通用性组件啦。
嗯,这两者的确各有优势,不过我在实际复杂的表单(需要写多个v-if进行条件判断,多个组件组合之类的)开发中,还是习惯JSX更多一些,当然如果比较简单的表单(那种能一个v-if或者v-for搞定的),我更倾向于不使用JSX,直接用vue的指令去搞定。
假设你的数据结构是:
{
a: {
b: {
c: 111,
},
},
}
你对 a/b/c
赋值,当你的循环执行到最后一遍时,targetKey
是什么?
targetKey预计要是key值,如a.b.c。
有尝试改用Vue.set(),有成功update,但如果把值绑在radio上,就会出现多次更新。
页面上有几个就更新几次。
updateValue (state, { key, val }) {
console.log('updateValue');
const keySplit = key.split('/');
let targetKey = state;
for (let i = 0; i < keySplit.length - 1; i++) {
const currentKey = targetKey[keySplit[i]];
targetKey = currentKey;
}
Vue.set(targetKey, keySplit[keySplit.length - 1], val);
},
JSX或Vue本身的架构验证方式应该可行,现在有另外一个产生的问题:数据绑定。
因为在不同的Component,绑值通过Vuex另外就是双向绑定的值,因为所有的input都在不同层级的Component内,所以想说绑定的值都使用Store(Vuex)的方式去取值、更新值。
数据结构是长这样,要取值、推值的部分层级不一定一样:
state = {
a1: {
b1: {
c1: null
...以下N个
}
...以下N个
b2: null
}
...以下N个
}
内部推值的data形式
// component 内部
data = {
key: 'a1/b1/c1'
val: 'Name'
}
this.$store.commit('changeValue', data);
想说尝试使用跑循环找key值再推值,不晓得为什幺没用,也没有报错。
mutations: {
changeValue (state, { key, val }){
const keySplit = key.split('/');
let targetKey = state;
for (let i = 0; i < keySplit.length; i++) {
const currentKey = targetKey[keySplit[i]];
targetKey = currentKey;
}
targetKey = val;
}
}
key、val取的值是对的,targetKey抓到的值也是对的,但 “targetKey = val” 就是没用。
不过如果这样做负担会不会太大?
keyup, blur就更新值,一直跑循环,但好像也没有其它比较好的方式?
声明式 vs 半命令式(JSX 倒也不能完全算命令式)的区别。只能说各有利弊吧。
在 v-if 之外,Vue 还提供了 <component>
,其实也可以解决部分动态模板需求。只是模板毕竟是模板,灵活性比不上 render 函数。所以这也是个取舍吧。
PS: 但模板可以搞语法糖(doge)。而且 Vue 3.x 支持模板编译提示,我还是挺模板(doge x2)。