由于某種原因,我很想用 deboand 創建一個自動完成輸入,但我無法讓它正常作業。我可以從下拉串列中選擇一個建議并在螢屏上短暫顯示,但隨后它會與輸入本身一起重置。
我很確定錯誤來自selectSuggestion函式的最后一行來清除valueInner,但是一旦選擇了值就清除輸入是我想要的。但是,我不希望在此之后清除所選值。
它可以是selectSuggestionfunction 和watchon的組合valueInner,但我也需要它watch來使 debounce 作業。
關于如何解決這個問題的任何想法?
CodeSandbox 鏈接: https ://codesandbox.io/s/stoic-forest-7w19oj?file=/src/components/Autocomplete.vue
應用程式.vue
<template>
<Autocomplete v-model="text" :suggestions="['something','hairstyle','cheese']"/>
<p>Selected Suggestion:{{text}}</p>
</template>
<script lang="ts">
import { defineComponent, ref } from "vue";
import Autocomplete from '../src/components/Autocomplete'
export default defineComponent({
name: "App",
setup(){
const text = ref('')
return { text }
},
components: {
Autocomplete,
Autocomplete2,
},
});
</script>
<style>
#app {
font-family: Avenir, Helvetica, Arial, sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
text-align: center;
color: #2c3e50;
margin-top: 60px;
}
</style>
自動完成
<template>
<input
ref="inputRef"
v-model="valueInner"
:disabled="disabled || undefined"
:placeholder="placeholder"
:readonly="readonly || undefined"
:required="required || undefined"
:autofocus="autofocus"
:autocomplete="autocomplete"
:suggestions="suggestions"
/>
<ul v-if="filterSuggestions.length">
<li>
Showing {{ filterSuggestions.length }} of {{ suggestions.length }} results
</li>
<li
v-for="suggestion in filterSuggestions"
:key="suggestion"
@click="selectSuggestion(suggestion)"
>
{{ suggestion}}
</li>
</ul>
</template>
<script lang="ts">
import {
defineComponent,
ref,
onMounted,
nextTick,
watch,
PropType,
computed,
} from 'vue'
export default defineComponent({
name: 'Autocomplete',
inheritAttrs: false,
props: {
label: {
type: String,
},
disabled: { type: Boolean, default: false },
placeholder: { type: String },
readonly: { type: Boolean },
required: { type: Boolean },
modelValue: { type: [String, Number], default: '' },
autocomplete: { type: Boolean, default: false },
suggestions: {
type: Array as PropType<string[]>,
default: ['Hamburger', 'Fries', 'Peanuts'],
},
debounce: { type: Number, default: undefined },
},
emits: ['update:modelValue'],
setup(props, { emit }) {
let debounceInner = 0
if (typeof props.debounce === 'number') {
debounceInner = props.debounce
} debounceInner = 1000
const inputRef = ref<HTMLElement | null>(null)
const isFocused = ref(false)
watch(isFocused, (oldVal, newVal) => {
console.log(`isFocused → `, isFocused)
})
let timeout: any = null
const valueInner = ref<any>(props.modelValue)
console.log(valueInner.value)
watch(valueInner, (newVal, oldVal) => {
const debounceMs = debounceInner
if (debounceMs > 0) {
clearTimeout(timeout)
timeout = setTimeout(() => emitInput(newVal), debounceMs)
} else {
emitInput(newVal)
}
})
function emitInput(newVal: any) {
let payload = newVal
emit('update:modelValue', payload)
}
let selectedSuggestion = ref('')
const suggestions = ['United States', 'Japan', 'Italy', 'Australia', 'Germany', 'Poland', 'Ukraine']
const filterSuggestions = computed(() => {
if (valueInner.value === '') {
return []
}
let matches = 0
return suggestions.filter((suggestion) =>{
if (
suggestion.toLowerCase().includes(valueInner.value.toLowerCase())
&& matches < 10
) {
matches
return suggestion
}
})
})
const selectSuggestion = (suggestion) => {
selectedSuggestion.value = suggestion
emitInput(suggestion)
valueInner.value = ''
}
function emitInput(newVal: any) {
let payload = newVal
emit('update:modelValue', payload)
}
watch(valueInner, (newVal, oldVal) => {
const debounceMs = debounceInner
if (debounceMs > 0) {
clearTimeout(timeout)
timeout = setTimeout(() => emitInput(newVal), debounceMs)
} else {
emitInput(newVal)
}
})
return {
inputRef,
valueInner,
suggestions,
filterSuggestions,
selectSuggestion,
selectedSuggestion,
}
},
})
</script>
<style lang="sass" scoped>
li
list-style: none
</style>
uj5u.com熱心網友回復:
該錯誤確實來自 clearing valueInner.value,這會觸發其上的監視,它將空白值作為update:modelValue事件資料發出,從而覆寫模型值。
一個快速的解決方法是null在重置時使用而不是空字串(以區分內部清除與用戶輸入)valueInner.value:
const selectSuggestion = (suggestion) => {
selectedSuggestion.value = suggestion
emitInput(suggestion)
valueInner.value = null ??
}
然后在手表中,如果新值是null因為我們不需要發出它,則立即回傳:
watch(valueInner, (newVal, oldVal) => {
if (newVal === null) return
?
/* handle new value */
})
此外, in filterSuggestions,當值為 falsy 時回傳一個空陣列(包括null或空字串):
const filterSuggestions = computed(() => {
??
if (!valueInner.value) {
return []
}
?
})
演示
轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/436137.html
標籤:打字稿 Vue.js 自动完成 Vuejs3 vue-composition-api
上一篇:鍵入基于另一個屬性值的鍵名
