【问题标题】:How to change text inputs into tags, in an existing Vue 3 form, using a Tag Input Component?如何使用标签输入组件以现有的 Vue 3 形式将文本输入更改为标签?
【发布时间】:2021-11-23 03:32:28
【问题描述】:

我在 Vue 3 项目中有一个现有表单,它成功发布到 Cloud Firestore 数据库。

如何使用标签输入组件 like this两个 type="text" 输入字段更改为标签输入? 这是它的链接 @987654322 @

独立教程非常清晰且运行良好。我正在努力解决的是如何将其合并到现有的 Vue 3 表单中并继续将所有内容发布到 Firestore 数据库。

我从下面的“基本”代码中剥离了样式和许多其他输入字段:

<template>
  
<form @submit.prevent="handleSubmit" >

    <h3>What kind of pet?</h3>
    <div class="space-y-0">
        <select required name="pet_type" id="pet_type" v-model="pet_type">
          <option value="">Please select</option>
          <option value="cat">Cat</option>
          <option value="dog">Dog</option>
          <option value="wolverine">Wolverine</option>
        </select>
      </div>

      <hr>

      <div> <!-- Want to change this into the first tag input -->
        <h3>Pros</h3>
        <div for="petPros">What are 3 positive things about this pet?</div>
        <input type="text" placeholder="separate , with , commas" id="petPros" v-model="petPros">
        <label for="petPros">separate , with , commas</label>
      </div>

      <hr>

     <div> 
        <h3>Cons</h3>  <!-- Want to change this into a second tag input -->
        <div for="petCons">And what are 3 negative things about this pet?</div>
        <input type="text" placeholder="separate , with , commas" id="petPros" v-model="petCons">
        <label for="petCons">separate , with , commas</label>
      </div>

      <hr>


<h3>Privacy</h3>
      
      <div>
          <div>
            <input type="radio" id="Fullpublic" value="Fullpublic" name="reviewPrivacy" required v-model="reviewPrivacy">
            <label class="text-base inline-flex ml-4 align-bottom" for="Fullpublic">Public</label>
          </div>

          <div>
            <input type="radio" id="keepFullyPrivate" value="keepFullyPrivate" name="reviewPrivacy" required v-model="reviewPrivacy">
            <label class="text-base inline-flex ml-4 align-bottom" for="keepFullyPrivate">Private</label>
          </div>
      </div>

      <hr>

      <button v-if="!isPending" >Submit</button>
      <button v-else disabled>Saving...</button>
    </form>

</template>

<script>
import { ref } from 'vue'
import useStorage from '@/composables/useStorage'
import useCollection from '@/composables/useCollection'

export default {
    setup() {

    const { filePath, url, uploadImage } = useStorage()
    const { error, addDoc } = useCollection('reviews')
    const { user } = getUser()
    const router = useRouter()

    const pet_type = ref('')
    const petPros = ref('')
    const petCons = ref('')
    const reviewPrivacy = ref('')


    const file = ref(null)
    const fileError = ref(null)
    const isPending = ref(false)

    const handleSubmit = async () => {
      if (file.value) {
        isPending.value = true
        await uploadImage(file.value)
        const res = await addDoc({
          pet_type: pet_type.value,
          petPros: petPros.value,
          petCons: petCons.value,
          reviewPrivacy: reviewPrivacy.value,

          userId: user.value.uid,
          userName: user.value.displayName,

          createdAt: timestamp()
        })
        isPending.value = false
        if (!error.value) {
          router.push({ name: 'ReviewDetails', params: { id: res.id }})
        }
      }
    }

    // allowed file types
    const types = ['image/png', 'image/jpeg']

    const handleChange = (e) => {
      let selected = e.target.files[0]
      console.log(selected)

      if (selected && types.includes(selected.type)) {
        file.value = selected
        fileError.value = null
      } else {
        file.value = null
        fileError.value = 'Please select an image file (png, jpg or jpeg)'
      }
    }
    
    return { pet_type, petPros, petCons, reviewPrivacy, handleSubmit, fileError, handleChange, isPending }  
  }
}
</script>


<style>

</style>

感谢您的帮助!

【问题讨论】:

    标签: forms vue.js tags vue-component vuejs3


    【解决方案1】:
    1. 在表单中,将两个&lt;input type="text"&gt;s 替换为&lt;TagInput&gt;。保持v-model 相同,因为TabInput 实现v-model

      <!-- BEFORE -->
      <input type="text" placeholder="separate , with , commas" id="petPros" v-model="petPros">
      <input type="text" placeholder="separate , with , commas" id="petPros" v-model="petCons">
      
      <!-- AFTER -->
      <TagInput id="petPros" v-model="petPros" />
      <TagInput id="petCons" v-model="petCons" />
      
    2. 在表单组件中本地注册TagInput.vue

      import TagInput from "./TagInput.vue";
      
      export default {
        components: {
          TagInput,
        },
      }
      
    3. petProspetConsrefs的初始值更改为数组,因为TabInput输出输入标签值的字符串数组:

      // BEFORE
      const petPros = ref('')
      const petCons = ref('')
      
      // AFTER
      const petPros = ref([])
      const petCons = ref([])
      
    4. TabInput 通常会在点击 TAB 时添加标签,但您的占位符建议您要使用逗号键 ,。为此,请更新 @keydown 绑定中的修饰符:

      <!-- BEFORE -->
      <input v-model="newTag"
         @keydown.prevent.tab="addTag(newTag)"
      >
      
      <!-- AFTER -->
      <input v-model="newTag"
         @keydown.prevent.,="addTag(newTag)"
      >
      

    demo

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-10-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-02-24
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多