前言:实现录入书籍功能的过程
这次记录的是我实现录入书籍功能的过程。第一次写这个功能时,折腾了好几天,但这次只花了一个下午就搞定了。简单来说,这个功能的核心是将用户输入的数据传到页面本地的变量中,然后再将表单中的数据上传到云数据库。
添加录入书籍功能
在个人页面中,我添加了一个“录入书籍”的功能图标。点击这个图标后,页面需要跳转到“书籍录入”的页面。为了实现这个跳转功能,我使用了 navigator 包裹图标,顺利实现了点击跳转。
解决 v-model 报错问题
跳转到书籍录入页面后,发现有一个报错,看起来和我之前添加的“图片上传器”有关。之前我从官网了 uni-file-picker 的示例代码,但没仔细研究 v-model 的作用。
v-model 是 Vue.js 中的一个指令,用于在表单控件元素(如 input、select 等)和 Vue 实例的数据之间创建双向数据绑定。也就是说,表单控件的值发生变化时,Vue 实例中的数据也会相应更新,反之亦然。
报错的原因是我没有定义 imageValue 这个变量。接下来,我准备给表单添加更多功能,v-model 应该很快就能派上用场。
添加扫码功能
参考了官网的文档,我给 cm-input 组件补充了右侧图标的点击事件 scan。在 scanCode 函数内,this 不会指向页面 data() 中定义的变量。因此,要对本地的变量进行操作,需要使用 this.setData 的写法。
扫码之后,得到的书籍 ISBN 码会自动填写到表单中的 ISBN 这一项。需要注意的是,显示在表单上的数据其实是自定义组件 cm-input 中的 input 组件中的参数 value。
我使用 v-bind 将 value 绑定到了页面中的变量 in 上。这个绑定是单向的,也就是说,value 的修改会同步改变 in 值,但修改 in 不会影响 value。
信息的传递路径如下:
扫码得到的数据 => value => in => 显示在页面上的数据
但有一种情况需要注意:如果用户手动输入 ISBN 数据,value 不会更新。这样看来,页面中的局部变量 in 只是修改数据 value 的一个接口。
通过 ISBN 查询书籍信息
用户在扫描书籍条码成功,或者手动输入 ISBN 并按确定键之后,会自动触发 ISBN 的查询。对于 cm-input 组件,点击确定键后会触发的事件可以在 confirm 中设置。
进行 ISBN 搜索后,如果成功,就更新页面显示的数据;如果失败,就弹出提示,不更新数据。
图片文件上传
我之前自定义了一个组件 cm-file-picker,其实就是给 uni-file-picker 添加了一些格式。uni-file-picker 可以使用 success 来设置在文件上传成功时执行的事件。success 会在文件上传成功时返回文件的地址。在开通 uniCloud 服务空间的情况下,这些文件会默认上传到服务空间中。
因此,我只需要获取所有图片文件的地址,并在随后将这些地址上传到数据库就行了。这些地址,我使用一个本地变量 imageList 数组进行存放。同时,通过 ISBN 搜索到的书籍图片也可以添加到 imageList 数组中,预备上传到数据库。
显示通过 ISBN 搜索到的书籍图片
通过 ISBN 搜索到的书籍图片应该显示在“封面”这一栏里。我在自定义的 cm-file-picker 组件里面添加了一个 image 标签,image 中的组件仍然会受到父组件 flex 的影响,从而自动横向排列。
为了显示网络图片,我在 cm-file-picker 组件中添加了一个 image 组件,并新建了一个本地变量 coverImage 作为图片资源地址。默认情况下,这个变量显示的是默认书籍图片。之后,我稍微调整了 cm-file-picker 组件的 CSS 来优化大小和排版。最后,我添加了一个绑定图片点击行为的事件 previewImage,用来设置图片的预览。
扩大 cm-input 组件的右侧图标范围
在手机上操作时,发现点击扫码时会误触到旁边的输入框。为了解决这个问题,我决定把 cm-input 的图标范围扩大一点,避免误触。
将表单数据上传到数据库
我没有使用 form 组件来获取表单数据,因为发现用不了,目前还不清楚原因。不过,我将所有需要添加到数据库的数据包装成了一个 JS 对象,在点击“录入”按钮之后,这个对象会作为上传函数的参数。
我使用云函数作为上传数据的函数。在项目的 cloudfunctions 文件夹图标上右键,可以选择“新建云函数/云对象”。写好云函数后,记得上传云函数。
到此,录入书籍(尤其是新书)的功能就基本实现了。接下来,我会继续完善一些细节。














