arco-design / arco-design-vue

A Vue.js 3 UI Library based on Arco Design
https://arco.design/vue
MIT License
2.73k stars 536 forks source link

选择器 Select 使用疑问 #2220

Open besscroft opened 1 year ago

besscroft commented 1 year ago

Basic Info

Extra info

代码地址,希望能对复现问题带来帮助。

What is expected?

预期效果是点击提交时,能够正确打印出值:

const handleSubmit = (formEl: FormInstance) => {
  console.log(addStorageForm)
}

目前下拉框的值渲染正常,但是点击之后,框框里面依旧是空白,只显示提示语,并且表单校验提示没填入数据。而且 addStorageForm.region 的值似乎没有发生变化。 如果改成这样就可以,但是这样表单验证似乎会失效:

<a-form-item field="region" label="Region" :help="region.description" required>
  <a-select
    placeholder="请选择 Bucket 地域的 Region"
    :loading="loading"
  >
    <a-option v-for="region in regionList" :key="region" :label="region" :value="region" @click="() => { addStorageForm.region = region }">
      {{ region }}
    </a-option>
  </a-select>
</a-form-item>

Steps to reproduce

下面是最小示例问题代码,对应的 model-value (v-model) 绑定值和 input-value (v-model) 输入框的值似乎没有达到预期效果,我不确定是使用问题还是 bug。

<script setup lang="ts">
import { Message } from '@arco-design/web-vue'
import type { FormInstance } from '@arco-design/web-vue'
import type { Storage } from '~/api/interface/storage'
import { getAwsRegions, storageAdd } from '~/api/modules/storage'

const { t } = useI18n()
const router = useRouter()
const formRef = ref<FormInstance>()
const loading = ref<boolean>(false)
const regionList = ref<Array<String>>()
const addStorageForm = reactive({
  /** 存储名称 */
  name: '',
  /** 存储 key */
  storageKey: '',
  /** 备注 */
  remark: '',
  endpoint: '',
  region: '',
  accessKey: '',
  secretKey: '',
  bucketName: '',
  mount_path: '',
})

const handleSubmit = (formEl: FormInstance) => {
  console.log(addStorageForm)
}

onMounted(() => {
  loading.value = true
  getAwsRegions().then((res) => {
    regionList.value = res.data
    loading.value = false
  }).catch((err) => {
    Message.error(err.message)
    loading.value = false
  })
})
</script>

<template>
  <div
    :style="{
      boxSizing: 'border-box',
      width: '100%',
      padding: '0.25rem',
      height: '100%',
      backgroundColor: 'var(--color-fill-2)',
    }"
  >
    <a-card hoverable :style="{ height: '100%', padding: '0.25rem' }" :title="t('tip.cardTitle')">
      <template #extra>
        <a-space>
          <a-button type="primary" @click="handleSubmit(formRef)">{{ t('button.submit') }}</a-button>
        </a-space>
      </template>
      <GoBack />
      <br>
      <a-row>
        <a-col :xs="1" :sm="6" :md="6" :lg="6" :xl="6" :xxl="6" />
        <a-col :xs="22" :sm="12" :md="12" :lg="12" :xl="12" :xxl="12">
          <a-form ref="formRef" :model="addStorageForm" layout="vertical">
            <a-form-item field="region" label="Region" :help="region.description" required>
              <a-select
                placeholder="请选择 Bucket 地域的 Region"
                :loading="loading"
                :model-value="addStorageForm.region"
                :input-value="addStorageForm.region"
              >
                <a-option v-for="region in regionList" :key="region" :label="region" :value="region" />
              </a-select>
            </a-form-item>
          </a-form>
        </a-col>
        <a-col :xs="1" :sm="6" :md="6" :lg="6" :xl="6" :xxl="6" />
      </a-row>
    </a-card>
  </div>
</template>

<style scoped>

</style>

<route lang="yaml">
meta:
  layout: admin
</route>

最后,如果需要提供其它信息,我会尽量提供。希望社区能看看问题,谢谢~

kaikaibenkai commented 1 year ago

@besscroft

Vue 中,:v-bind 的简写,是单向数据流,不会更改传入的 ref 的值。 如果需要双向数据流,Vue3 中提供 v-model 实现。 即:

              <a-select
                 placeholder="请选择 Bucket 地域的 Region"
                 :loading="loading"
-                :model-value="addStorageForm.region"
+                v-model="addStorageForm.region"
                 :input-value="addStorageForm.region"
               >
                 <a-option v-for="region in regionList" :key="region" :label="region" :value="region" />
               </a-select>
besscroft commented 1 year ago

@kaikaibenkai 感谢你的回复。文档里面括号显示了 v-model,我理解的是它们可能就是一样的作用。 image

kaikaibenkai commented 1 year ago

@kaikaibenkai 感谢你的回复。文档里面括号显示了 v-model,我理解的是它们可能就是一样的作用。 image

这里 (v-model) 的作用是声明这个 prop 可以使用 v-model 语法,并不能改变 Vue 原有语法设定