vue3+vant4中表单内嵌picker的默认值设置

头一次用vant就在表单默认值上费劲了,搞下来代码量比antd系列的代码量大。废话不说,直接上代码,将这三段代码直接复制到一个组件中即可看到效果。早上5点多就起来捣鼓这玩意,上午以为完成了,发出去一看居然有bug——picker滑动时表单数据同时被修改!于是经查,根据 https://www.cnblogs.com/Super-scarlett/p/17919981.html 又改了一版,见下:

环境版本
“vant”: “^4.9.1”,
“vue”: “^3.4.21”

<script setup lang="ts">
import { ref } from 'vue'
const 地支 = '子丑寅卯辰巳午未申酉戌亥'

// 用于picker的v-model的值必须是字符串,数字不行.
const years = Array(100).fill(0).map((_, index) => new Date().getFullYear() - index).map(item => ({ text: item + '' })).reverse()
const year = ref(['1980'])
const _year = ref(['1980'])
const months = Array(12).fill(0).map((_, index) => index + 1).map(item => ({ text: item + '' }))
const month = ref(['6'])
const _month = ref(['6'])
const dates = Array(30).fill(0).map((_, index) => index + 1).map(item => ({ text: item + '' }))
const date = ref(['15'])
const _date = ref(['15'])
const 时辰们 = Array(12).fill(0).map((_, index) => index + 1).map(item => {
  const text = 地支[item - 1] + '——' + (item === 1 ? '23点(昨)~1点' : `${item * 2 - 3}点~${item * 2 - 1}`)
  return { text }
})
const 时辰 = ref([时辰们[5].text])
const _时辰 = ref([时辰们[5].text])

const showYearPicker = ref(false)
const showMonthPicker = ref(false)
const showDatePicker = ref(false)
const show时辰Picker = ref(false)
const onYearConfirm = ({ selectedOptions }) => {
  year.value = selectedOptions[0]?.text
  showYearPicker.value = false
}
const onMonthConfirm = ({ selectedOptions }) => {
  month.value = selectedOptions[0]?.text
  showMonthPicker.value = false
}
const onDateConfirm = ({ selectedOptions }) => {
  date.value = selectedOptions[0]?.text
  showDatePicker.value = false
}
const on时辰Confirm = ({ selectedOptions }) => {
  时辰.value = selectedOptions[0]?.text
  show时辰Picker.value = false
}
const info = ref(null)

const 提交表单 = (values) => {
  info.value = values
  console.log('submit', values);
}
</script>
<template>
  <div class='p-home'>
    <h3>请输入农历出生信息</h3>
    <van-form @submit="提交表单">

      <van-field v-model="year" is-link readonly name="" label="年份" placeholder="点击选择年份"
        @click="showYearPicker = true" />
      <van-popup v-model:show="showYearPicker" position="bottom">
        <van-picker :columns-field-names='{ value: "text" }' v-model="_year" title="农历出生年份" :columns="years"
          @confirm="onYearConfirm" @cancel="showYearPicker = false" />
      </van-popup>

      <van-field v-model="month" is-link readonly name="" label="月份" placeholder="点击选择月份"
        @click="showMonthPicker = true" />
      <van-popup v-model:show="showMonthPicker" position="bottom">
        <van-picker :columns-field-names='{ value: "text" }' v-model="_month" title="农历出生月份" :columns="months"
          @confirm="onMonthConfirm" />
      </van-popup>

      <van-field v-model="date" is-link readonly name="" label="日期" placeholder="点击选择日期"
        @click="showDatePicker = true" />
      <van-popup v-model:show="showDatePicker" position="bottom">
        <van-picker :columns-field-names='{ value: "text" }' v-model="_date" title="农历出生日期" :columns="dates"
          @confirm="onDateConfirm" />
      </van-popup>

      <van-field v-model="时辰" is-link readonly name="" label="时辰" placeholder="点击选择时辰" @click="show时辰Picker = true" />
      <van-popup v-model:show="show时辰Picker" position="bottom">
        <van-picker :columns-field-names='{ value: "text" }' v-model="_时辰" title="农历出生时辰" :columns="时辰们"
          @confirm="on时辰Confirm" />
      </van-popup>
      <br />
      <van-button round block type="primary" native-type="submit">
        提交
      </van-button>
    </van-form>
    <br />
    <p><strong>{{info}}</strong></p>
  </div>
</template>
<style scoped>
.p-home {
  padding: 1rem;

  h3 {
    text-align: left;
    line-height: 3rem;
    font-weight: bold;
  }
}
</style>

如下为早晨第一次尝试,方法看似解决了问题,但出现了个严重bug,就是滑动picker时表单上的数据被同时改变了。

<script setup lang="ts">
import { ref } from 'vue'
const 地支 = '子丑寅卯辰巳午未申酉戌亥'

// 用于表单下picker的v-model的值必须是字符串,数字不行,而在单独的picker里可以
const years = Array(100).fill(0).map((_, index) => new Date().getFullYear() - index).map(item => ({ text: item + '' })).reverse()
const year = ref(['1980'])
const months = Array(12).fill(0).map((_, index) => index + 1).map(item => ({ text: item + '' }))
const month = ref(['6'])
const dates = Array(30).fill(0).map((_, index) => index + 1).map(item => ({ text: item + '' }))
const date = ref(['15'])
const 时辰们 = Array(12).fill(0).map((_, index) => index + 1).map(item => {
  const text = 地支[item - 1] + '——' + (item === 1 ? '23点(昨)~1点' : `${item * 2 - 3}点~${item * 2 - 1}`)
  return { text }
})
const 时辰 = ref([时辰们[5].text])

const showYearPicker = ref(false)
const showMonthPicker = ref(false)
const showDatePicker = ref(false)
const show时辰Picker = ref(false)

const info = ref(null)

const 提交表单 = (values) => {
  info.value = values
  console.log('submit', values);
}
</script>
<template>
  <div class='p-home'>
    <h3>请输入农历出生信息</h3>
    <van-form @submit="提交表单">

      <van-field v-model="year[0]" is-link readonly name="" label="年份" placeholder="点击选择年份"
        @click="showYearPicker = true" />
      <van-popup v-model:show="showYearPicker" position="bottom">
        <van-picker :columns-field-names='{ value: "text" }' v-model="year" title="农历出生年份" :columns="years"
          @confirm="showYearPicker=false" />
      </van-popup>

      <van-field v-model="month[0]" is-link readonly name="" label="月份" placeholder="点击选择月份"
        @click="showMonthPicker = true" />
      <van-popup v-model:show="showMonthPicker" position="bottom">
        <van-picker :columns-field-names='{ value: "text" }' v-model="month" title="农历出生月份" :columns="months"
          @confirm="showMonthPicker = false" />
      </van-popup>

      <van-field v-model="date[0]" is-link readonly name="" label="日期" placeholder="点击选择日期"
        @click="showDatePicker = true" />
      <van-popup v-model:show="showDatePicker" position="bottom">
        <van-picker :columns-field-names='{ value: "text" }' v-model="date" title="农历出生日期" :columns="dates"
          @confirm="showDatePicker = false" />
      </van-popup>

      <van-field v-model="时辰[0]" is-link readonly name="" label="时辰" placeholder="点击选择时辰"
        @click="show时辰Picker = true" />
      <van-popup v-model:show="show时辰Picker" position="bottom">
        <van-picker :columns-field-names='{ value: "text" }' v-model="时辰" title="农历出生时辰" :columns="时辰们"
          @confirm="show时辰Picker = false" />
      </van-popup>
      <br />
      <van-button round block type="primary" native-type="submit">
        提交
      </van-button>
    </van-form>
      <br />
    <p ><strong>{{info}}</strong></p>
  </div>
</template>
<style scoped>
.p-home {
  padding: 1rem;
  h3 {
    text-align: left;
    line-height: 3rem;
    /* font-weight: bold; */
  }
}
</style>

GitHub 加速计划 / vu / vue
207.55 K
33.66 K
下载
vuejs/vue: 是一个用于构建用户界面的 JavaScript 框架,具有简洁的语法和丰富的组件库,可以用于开发单页面应用程序和多页面应用程序。
最近提交(Master分支:2 个月前 )
73486cb5 * chore: fix link broken Signed-off-by: snoppy <michaleli@foxmail.com> * Update packages/template-compiler/README.md [skip ci] --------- Signed-off-by: snoppy <michaleli@foxmail.com> Co-authored-by: Eduardo San Martin Morote <posva@users.noreply.github.com> 4 个月前
e428d891 Updated Browser Compatibility reference. The previous currently returns HTTP 404. 5 个月前
Logo

旨在为数千万中国开发者提供一个无缝且高效的云端环境,以支持学习、使用和贡献开源项目。

更多推荐