业务画面:<template>
<my-form ref="forRef" :model="data">
<my-form-item label="产品名称" prop="name">
<my-input v-model="data.name" :rules="[
{ required: true, message: '请输入产品名称', trigger: 'blur' },
{ max: 10, maxMessage: '产品名称不能超过10个汉字' }
]" />
</my-form-item>
<my-form-item label="产品描述" prop="age">
<my-input v-model="data.age" :rules="[
{ required: true, message: '请输入产品描述', trigger: 'blur' },
{ max: 10, maxMessage: '姓名不能超过200个汉字' }
]" />
</my-form-item>
<my-form-item label="性别" prop="sex" :rules="[{ required: true, message: '请选择性别', trigger: 'change' },]">
<my-select v-model="data.sex">
<my-option v-for="item in sexOptions" :label="item.lable" :value="item.value" />
</my-select>
</my-form-item>
<my-form-item label="产品单价" prop="price">
<my-input v-model="data.price" :rules="[
{ required: true, message: '请输入产品单价', trigger: 'blur' },
{ min: 0, message: '产品单价不能小于0', trigger: 'blur' },
{ max: 10000, message: '产品单价不能超过10000', trigger: 'blur' }
]" />
</my-form-item>
<my-form-item label="产品库存" prop="stock">
<my-input v-model="data.stock" :rules="[
{ required: true, message: '请输入产品库存', trigger: 'blur' },
{ min: 0, message: '产品库存不能小于0', trigger: 'blur' },
{ max: 10000, message: '产品库存不能超过10000', trigger: 'blur' }
]" />
</my-form-item>
<my-form-item label="生产厂家" prop="manufacturer">
<my-input v-model="data.manufacturer" :rules="[
{ required: true, message: '请输入生产厂家', trigger: 'blur' },
]" />
</my-form-item>
</my-form>
{{ data }}
<button @click="checkForm">提交</button>
<button @click="clearForm">清空</button>
</template>
<script setup>
import myForm from '@/components/myForm';
import myFormItem from '@/components/myForm/myFormItem';
import MyInput from '@/components/input';
import MySelect from '@/components/mySelect';
import MyOption from '@/components/mySelect/myOption';
const forRef = ref()
const sexOptions = reactive([{ lable: "男", value: 1 }, { lable: "女", value: 2 }])
const data = reactive({
name: "",
age: "",
sex: "",
price: "",
stock: "",
manufacturer: "",
formCheck: null
})
function checkForm() {
data.formCheck = forRef.value.validate()
}
function clearForm() {
forRef.value.resetField()
}
const rules = reactive({
name: [
{ required: true, message: '请输入产品名称', trigger: 'blur' },
{ max: 10, message: '长度超过10位', trigger: 'blur' },
],
description: [
{ required: true, message: '请输入产品描述', trigger: 'blur' },
{ max: 200, message: '长度超过200位', trigger: 'blur' },
],
category: [
{ required: true, message: '请选择产品分类', trigger: 'change' },
],
});
</script> select:<template>
<div class="select">
<button class="trigger" @click="toggleMenu">
{{ selectedLabel || placeholder }}
<span class="arrow" :class="{ 'rotated': isOpen }">▼</span>
</button>
<div class="menu" :class="{ 'menu_open': isOpen }">
<template v-for="item in selectOptions">
<div class="option" @click="handleClick(item)" :class="{ 'selected': item.selected }">
<span>{{ item.label }}</span>
<!-- <span class="left-content">{{ item.label }}</span> -->
</div>
</template>
</div>
</div>
<slot></slot>
</template>
<script setup>
const model = defineModel()
const selectedLabel = ref('')
const selectOptions = ref([])
const isOpen = ref(false)
const props = defineProps({
placeholder: {
type: String,
default: '请选择'
},
options: {
type: Array,
default: []
}
})
const emit = defineEmits(['change'])
function handleClick(item) {
model.value = item.value
toggleMenu()
}
function setOtherOptionDefault(value) {
selectOptions.value.forEach(item => {
if (item.value != value) {
item.selected = false
} else {
item.selected = true
}
})
}
function toggleMenu() {
isOpen.value = !isOpen.value
}
provide('pushOptions', item => {
selectOptions.value.push(item)
})
watch(
() => model, // 监听的属性
(newVal, oldVal) => { // 变化时的回调函数
if (newVal != null && newVal != undefined && newVal.value != null && newVal.value != undefined) {
selectOptions.value.forEach(item => {
if (item.value == newVal.value) {
selectedLabel.value = item.label
setOtherOptionDefault(newVal.value)
}
})
} else {
selectedLabel.value = ""
}
},
{ deep: true }
);
onMounted(() => {
if (props.options.length > 0) {
selectOptions.value = props.options
}
selectOptions.value.forEach(item => {
if (item.value == model.value) {
selectedLabel.value = item.label
setOtherOptionDefault(model.value)
}
})
})
</script>
<style scoped lang="scss">
.option {
width: 100%;
padding: 3px 0px 3px 0px;
&:hover {
background-color: #fa0808;
}
span {
margin-left: 15px;
font-size: 14px;
user-select: none;
}
}
.selected {
color: #409eff;
}
.select {
position: relative;
width: 200px;
}
.trigger {
width: 100%;
padding: 8px 12px;
border: 1px solid #ccc;
background-color: #fff;
text-align: left;
cursor: pointer;
}
.arrow {
float: right;
transition: transform 0.3s ease;
}
.arrow.rotated {
transform: rotate(180deg);
}
.menu {
position: absolute;
top: 100%;
left: 0;
width: calc(100% - 1px);
height: 0px;
overflow-x: auto !important;
overflow-y: auto !important;
border: 1px solid #ccc;
border-top: none;
background: white;
z-index: 10;
transition: height 0.3s ease;
&::-webkit-scrollbar {
width: 5px;
/* 垂直滚动条宽度 */
height: 5px;
/* 水平滚动条高度(可选) */
}
/* 滚动条滑块部分 */
&::-webkit-scrollbar-thumb {
background-color: rgba(0, 0, 0, 0.3);
border-radius: 4px;
}
/* 滚动条轨道 */
&::-webkit-scrollbar-track {
background-color: #f1f1f1;
}
}
.menu.menu_open {
height: 100px !important;
}
.fade-enter-active,
.fade-leave-active {
transition: opacity 0.2s;
}
.fade-enter-from,
.fade-leave-to {
opacity: 0;
}
</style> 子组件:<template>
</template>
<script setup>
const props = defineProps({
label: {
type: String,
required: true
},
value: {
type: [String, Number],
required: true
},
})
const pushOptions = inject('pushOptions')
onMounted(() => {
pushOptions && pushOptions({ value: props.value, label: props.label, selected: false },)
})
</script>
我想像验证输入框一样判断下拉框是否选择
最新发布