完成下拉列表的实现
This commit is contained in:
parent
8f1153e739
commit
f82d972038
@ -1,15 +1,28 @@
|
||||
<template>
|
||||
<li><slot></slot></li>
|
||||
<li :ref="element" @click="onClick($event)">
|
||||
<slot></slot>
|
||||
</li>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import {defineComponent} from "vue";
|
||||
import {defineComponent, onMounted, onUpdated, ref} from "vue";
|
||||
|
||||
export default defineComponent({
|
||||
name: "POption",
|
||||
props:{
|
||||
value:{
|
||||
type: [String,Number,Object],
|
||||
props: {
|
||||
value: {
|
||||
type: [String, Number, Object],
|
||||
}
|
||||
},
|
||||
emits: ['select'],
|
||||
setup(props,context) {
|
||||
function onClick(e) {
|
||||
e.target.data = props.value
|
||||
}
|
||||
const element = ref<HTMLElement>()
|
||||
|
||||
return {
|
||||
element,onClick
|
||||
}
|
||||
}
|
||||
})
|
||||
|
@ -1,13 +1,14 @@
|
||||
<template>
|
||||
<div class="select-wrapper" :class="{active:isActive}" v-click-outside="onClose">
|
||||
<div class="select-box-wrapper" @click="isActive = !isActive">
|
||||
<div class="select-value">{{ selectValue }}<span class="placeholder">{{ placeholder }}</span></div>
|
||||
<div class="select-value">{{ selectValue }}<span v-if="!selectValue" class="placeholder">{{ placeholder }}</span>
|
||||
</div>
|
||||
<div class="icon-arrow">
|
||||
<ArrowDown class="icon-select-arrow"/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="select-options-wrapper">
|
||||
<ul>
|
||||
<ul @click="onSelect">
|
||||
<slot></slot>
|
||||
</ul>
|
||||
</div>
|
||||
@ -16,7 +17,7 @@
|
||||
|
||||
<script lang="ts">
|
||||
import ArrowDown from "../icon/ArrowDown.vue";
|
||||
import {ref} from "vue";
|
||||
import {defineComponent, nextTick, ref, SetupContext} from "vue";
|
||||
import {CHANGE_EVENT, UPDATE_MODEL_EVENT} from "../../service/constants";
|
||||
|
||||
export interface OptionItemType {
|
||||
@ -26,7 +27,7 @@ export interface OptionItemType {
|
||||
|
||||
// declare var OptionItemArray: OptionItemType[];
|
||||
|
||||
export default {
|
||||
export default defineComponent({
|
||||
name: "PSelect",
|
||||
components: {ArrowDown},
|
||||
props: {
|
||||
@ -34,6 +35,9 @@ export default {
|
||||
type: String,
|
||||
default: '请选择'
|
||||
},
|
||||
modelValue: {
|
||||
type: [String, Number, Object]
|
||||
}
|
||||
},
|
||||
emits: [
|
||||
UPDATE_MODEL_EVENT,
|
||||
@ -41,17 +45,35 @@ export default {
|
||||
'focus',
|
||||
'blur',
|
||||
],
|
||||
setup(props) {
|
||||
setup(props, ctx: SetupContext) {
|
||||
const selectValue = ref(props.modelValue)
|
||||
const isActive = ref(false)
|
||||
function onClose(){
|
||||
|
||||
function onSelect(e: MouseEvent) {
|
||||
// 原生dom操作
|
||||
const target = e.target as HTMLElement;
|
||||
if (target.tagName.toLowerCase() != 'li') return;
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
//
|
||||
const text = target.textContent
|
||||
selectValue.value = text
|
||||
const arr = [].slice.call (target.parentElement.children)
|
||||
arr.forEach(ele => (ele as HTMLElement).classList.remove("selected"))
|
||||
target.classList.add("selected")
|
||||
ctx.emit(UPDATE_MODEL_EVENT,target.data)
|
||||
onClose()
|
||||
}
|
||||
|
||||
function onClose() {
|
||||
isActive.value = false
|
||||
}
|
||||
|
||||
return {
|
||||
selectValue, isActive,onClose
|
||||
selectValue, isActive, onClose, onSelect
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
</script>
|
||||
|
||||
<style lang="less">
|
||||
@ -62,7 +84,8 @@ export default {
|
||||
.select-options-wrapper {
|
||||
display: block;
|
||||
}
|
||||
.select-box-wrapper{
|
||||
|
||||
.select-box-wrapper {
|
||||
border-color: var(--primary-color);
|
||||
box-shadow: 0 0 3px var(--primary-color);
|
||||
}
|
||||
|
@ -20,17 +20,16 @@
|
||||
</div>
|
||||
<hr>
|
||||
商品类型
|
||||
<p-select>
|
||||
<p-option value="1">普通商品</p-option>
|
||||
<p-option class="selected" value="2">精选商品</p-option>
|
||||
<p-option value="3">秒杀商品</p-option>
|
||||
<p-select v-model="select">
|
||||
<p-option v-for="op in options" :key="op.value" :value="op">{{ op.label }}</p-option>
|
||||
</p-select>
|
||||
{{ JSON.stringify(select) }}
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import PInput from "../components/input";
|
||||
import {reactive} from "vue";
|
||||
import {reactive, ref} from "vue";
|
||||
import PSelect from "../components/select/Select.vue";
|
||||
import POption from "../components/select/Option.vue";
|
||||
|
||||
@ -38,6 +37,12 @@ const data = reactive({
|
||||
a: '1',
|
||||
b: '2'
|
||||
})
|
||||
const options = [
|
||||
{value: 1, label: '普通商品'},
|
||||
{value: 2, label: '精选商品'},
|
||||
{value: 3, label: '秒杀商品'},
|
||||
]
|
||||
const select = ref()
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
Loading…
x
Reference in New Issue
Block a user