fix(components): [select-v2] missing validate action when clear (#4892)

* fix(components): [select-v2] missing validate action when clear

- Fix the bug that missing validate when clear
- Add the same icon and style as the select component

* docs: [select-v2] fix demo render error
This commit is contained in:
Ryan2128
2021-12-22 17:37:42 +08:00
committed by GitHub
parent 56e3f01240
commit bbed5a5e96
13 changed files with 35 additions and 17 deletions

View File

@@ -22,6 +22,7 @@
<script lang="ts" setup>
import { ref } from 'vue'
const initials = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j']
const value1 = ref([])
const value2 = ref('')
@@ -29,5 +30,4 @@ const options = Array.from({ length: 1000 }).map((_, idx) => ({
value: `Option ${idx + 1}`,
label: `${initials[idx % 10]}${idx}`,
}))
const initials = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j']
</script>

View File

@@ -20,13 +20,13 @@
<script lang="ts" setup>
import { ref } from 'vue'
const initials = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j']
const value = ref('')
const options = Array.from({ length: 1000 }).map((_, idx) => ({
value: `Option ${idx + 1}`,
label: `${initials[idx % 10]}${idx}`,
}))
const initials = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j']
</script>
<style scoped>

View File

@@ -18,6 +18,7 @@
<script lang="ts" setup>
import { ref } from 'vue'
const initials = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j']
const value1 = ref([])
const value2 = ref('')
@@ -25,5 +26,4 @@ const options = Array.from({ length: 1000 }).map((_, idx) => ({
value: `Option ${idx + 1}`,
label: `${initials[idx % 10]}${idx}`,
}))
const initials = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j']
</script>

View File

@@ -18,11 +18,11 @@
<script lang="ts" setup>
import { ref } from 'vue'
const initials = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j']
const value = ref([])
const options = Array.from({ length: 1000 }).map((_, idx) => ({
value: `Option ${idx + 1}`,
label: `${initials[idx % 10]}${idx}`,
}))
const initials = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j']
</script>

View File

@@ -20,6 +20,7 @@
<script lang="ts" setup>
import { ref } from 'vue'
const initials = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j']
const value = ref([])
const options = Array.from({ length: 1000 }).map((_, idx) => ({
@@ -27,5 +28,4 @@ const options = Array.from({ length: 1000 }).map((_, idx) => ({
label: `${initials[idx % 10]}${idx}`,
disabled: idx % 10 === 0,
}))
const initials = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j']
</script>

View File

@@ -11,11 +11,11 @@
<script lang="ts" setup>
import { ref } from 'vue'
const initials = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j']
const value = ref([])
const options = Array.from({ length: 1000 }).map((_, idx) => ({
value: `Option${idx + 1}`,
label: `${initials[idx % 10]}${idx}`,
}))
const initials = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j']
</script>

View File

@@ -11,6 +11,7 @@
<script lang="ts" setup>
import { ref } from 'vue'
const initials = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j']
const value = ref([])
const options = Array.from({ length: 10 }).map((_, idx) => {
@@ -24,5 +25,4 @@ const options = Array.from({ length: 10 }).map((_, idx) => {
})),
}
})
const initials = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j']
</script>

View File

@@ -11,11 +11,11 @@
<script lang="ts" setup>
import { ref } from 'vue'
const initials = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j']
const value = ref([])
const options = Array.from({ length: 1000 }).map((_, idx) => ({
value: `Option ${idx + 1}`,
label: `${initials[idx % 10]}${idx}`,
}))
const initials = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j']
</script>

View File

@@ -10,6 +10,7 @@
<script lang="ts" setup>
import { ref } from 'vue'
const initials = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j']
const value = ref([])
const options = ref(
@@ -18,5 +19,4 @@ const options = ref(
label: `${initials[idx % 10]}${idx}`,
}))
)
const initials = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j']
</script>

View File

@@ -218,6 +218,12 @@
>
<component :is="clearIcon" />
</el-icon>
<el-icon
v-if="validateState && validateIcon"
class="el-input__icon el-input__validateIcon"
>
<component :is="validateIcon" />
</el-icon>
</span>
</div>
</template>

View File

@@ -4,16 +4,15 @@ import {
ref,
reactive,
nextTick,
inject,
onMounted,
onBeforeMount,
} from 'vue'
import { isArray, isFunction, isObject } from '@vue/shared'
import isEqual from 'lodash/isEqual'
import lodashDebounce from 'lodash/debounce'
import { elFormKey } from '@element-plus/tokens'
import { useLocale, useSize } from '@element-plus/hooks'
import { useFormItem, useLocale, useSize } from '@element-plus/hooks'
import { UPDATE_MODEL_EVENT, CHANGE_EVENT } from '@element-plus/utils/constants'
import { ValidateComponentsMap } from '@element-plus/utils/icon'
import {
addResizeListener,
removeResizeListener,
@@ -29,7 +28,6 @@ import { flattenOptions } from './util'
import { useInput } from './useInput'
import type { SelectProps } from './defaults'
import type { ExtractPropTypes, CSSProperties } from 'vue'
import type { ElFormContext } from '@element-plus/tokens'
import type { OptionType, Option } from './select.types'
const DEFAULT_INPUT_PLACEHOLDER = ''
@@ -42,7 +40,7 @@ const TAG_BASE_WIDTH = {
const useSelect = (props: ExtractPropTypes<typeof SelectProps>, emit) => {
// inject
const { t } = useLocale()
const elForm = inject(elFormKey, {} as ElFormContext)
const { form: elForm, formItem: elFormItem } = useFormItem()
const states = reactive({
inputValue: DEFAULT_INPUT_PLACEHOLDER,
@@ -86,7 +84,7 @@ const useSelect = (props: ExtractPropTypes<typeof SelectProps>, emit) => {
// the controller of the expanded popup
const expanded = ref(false)
const selectDisabled = computed(() => props.disabled || elForm.disabled)
const selectDisabled = computed(() => props.disabled || elForm?.disabled)
const popupHeight = computed(() => {
const totalHeight = filteredOptions.value.length * 34
@@ -122,6 +120,11 @@ const useSelect = (props: ExtractPropTypes<typeof SelectProps>, emit) => {
iconComponent.value && expanded.value ? 'is-reverse' : ''
)
const validateState = computed(() => elFormItem?.validateState || '')
const validateIcon = computed(
() => ValidateComponentsMap[validateState.value]
)
const debounce = computed(() => (props.remote ? 300 : 0))
// filteredOptions includes flatten the data into one dimensional array.
@@ -696,10 +699,13 @@ const useSelect = (props: ExtractPropTypes<typeof SelectProps>, emit) => {
watch(
() => props.modelValue,
(val) => {
(val, oldVal) => {
if (!val || val.toString() !== states.previousValue) {
initStates()
}
if (!isEqual(val, oldVal)) {
elFormItem?.validate?.('change')
}
},
{
deep: true,
@@ -768,6 +774,9 @@ const useSelect = (props: ExtractPropTypes<typeof SelectProps>, emit) => {
popperRef,
validateState,
validateIcon,
Effect,
// methods exports

View File

@@ -121,6 +121,7 @@
}
@include when(error) {
& .#{$namespace}-select-v2__wrapper,
& .#{$namespace}-input__inner,
& .#{$namespace}-textarea__inner {
&,

View File

@@ -196,11 +196,13 @@ $input-inline-start: map.get($input-padding-horizontal, 'default') !default;
}
@include e(suffix) {
display: inline-flex;
position: absolute;
right: 5px;
right: 12px;
height: 40px;
top: 50%;
transform: translateY(-50%);
color: var(--el-input-icon-color, map.get($input, 'icon-color'));
}
@include e(caret) {