2024-12-30
前言:今天这篇日志记录了我添加表单选择器的过程。中途我发现了 picker 组件可以通过改变 value 值来改变聚焦的条目。
添加选择器
接下来,我准备做选择器,类似这样:

我可以使用picker组件实现这种效果。但picker只包括了从底部弹出的这个选择器,并不包括触发弹出的组件和显示数据的组件。
因此,可以使用我之前写好的 cm-input 组件(“cm”是“common”的缩写,hhh),它可以通过中间的input组件显示数据,也可以通过点击右侧的图标触发弹出事件。
<template>
<!-- ... -->
<picker @change="bindPickerChange_type" :value="type_i" :range="types">
<cm-input title="分类" placeholder="请选择书籍分类" r_icon="down" :value="types[type_i]" :disabled="true"></cm-input>
</picker>
<!-- ... -->
</template>
<script>
export default {
name:"cm-input",
data() {
return {
types: ['未分类', '文学', '考研', '四级'],
type_i: 0,
// ...
methods: {
bindPickerChange_type: function(e) {
console.log('picker发送选择改变,携带值为:' + e.detail.value)
this.type_i= e.detail.value
},
// ...
这个辅助组件可以包裹在picker里面。可以通过点击包裹在picker中的组件来触发picker的弹出。
这样看来,不需要专门为cm-input的右图标加上触发picker的事件了,这个图标只起到提示的作用。cm-input现在只负责显示picker的数值(以及保持统一的排版)。
picker的数据范围是 range 数组确定的,而 value 的值表示选择了 range 中的第几个。上下滑动 picker 改变选中的数据时,value 也在响应这种变化。
那么,“选中哪个数据”是和value的值双向绑定的吗?以上图为例,我能通过选中“小说”来改变 value 的值;但如果我将value的值改为1,选择器会不会聚焦“小说”这一项?
我想做个实验。我添加了一个按钮,用来将与 value 绑定的变量 type_i 增加一。( type_i 是类型数组types的索引)

点击按钮增加 type_i (也就是 value )的值,再点击“分类”所在的cm-input,效果如下:

可以发现 picker 组件也跟着改变了聚焦的数据条目。
那么,这是不是说明,我通过这个表单提交了一份数据到数据库,当我想根据数据库里的这份数据让表单回到填写时的状态,可以直接通过改变 value 的值来实现。这样,如果想再次编辑这一份数据,就不用从头开始滑动 picker 了。
之前我编写上一个小程序时,遇到了这样一个问题:表单上显示的数据与实际提交的数据不一致。比如,将数据库中的 type_i 赋值给表单的 type_i 之后,表单聚焦的对象并不是 type_i 所对应的(我使用的是 vant-weapp )。这回我要解决这个问题。
我又使用相同的方法添加了几个 picker 。每个 picker 似乎都需要一个单独的函数来保证 type_i (也就是 value 的值)随着 picker 选中对象的改变而改变:
// ...
bindPickerChange_type: function(e) {
console.log('picker发送选择改变,携带值为:' + e.detail.value)
this.type_i= e.detail.value
},
bindPickerChange_area: function(e) {
console.log('picker发送选择改变,携带值为:' + e.detail.value)
this.area_i= e.detail.value
},
bindPickerChange_shelf: function(e) {
console.log('picker发送选择改变,携带值为:' + e.detail.value)
this.shelf_i= e.detail.value
}
// ...
我不知道有没有更好的方式来处理这几个重复的函数。
我添加了“区域”和“货架号”的 picker ,像这样:
<!-- ... -->
<picker @change="bindPickerChange_area" :value="area_i" :range="areas">
<cm-input title="区域" placeholder="请选择馆藏区域" r_icon="down" :value="areas[area_i]" :disabled="true"></cm-input>
</picker>
<picker @change="bindPickerChange_shelf" :value="shelf_i" :range="shelves[area_i]">
<cm-input title="货架号" placeholder="请选择摆放书籍的货架号" r_icon="down" :value="shelves[area_i][shelf_i]" :disabled="true"></cm-input>
</picker>
<!-- ... -->
我有一个特殊的需求:货架号会随着区域的改变而改变。因此我将各个不同区域的货架号数组用一个货架号数组的数组套了起来,这样我就可以使用 shelves[area_i][shelf_i]这样的写法来进行数据的绑定了。(上一个小程序,我为此单开了一个函数……)
这是目前实现的效果:


2176

被折叠的 条评论
为什么被折叠?



