Search 组件
<!-- <script setup >
import debounce from '@/uni_modules/uv-ui-tools/libs/function/debounce.js'
import { ref, computed, getCurrentInstance } from 'vue'
import EtDialog from '@/components/dialog'
const $emit = defineEmits(['input', 'clear', 'change', 'blur', 'focus', 'update:modelValue'])
const props = defineProps({
modelValue: [Number, String],
placeholder: String,
/* 百分比高度 */
height: {
type: Number,
default: 90
}
})
const { ctx } = getCurrentInstance()
const dialog = ref()
const value = ref(props.modelValue)
const input = (value) => {
$emit('input', value)
$emit('update:modelValue', value)
}
const clear = () => {
value.value = ''
$emit('input', '')
$emit('update:modelValue', '')
$emit('clear')
}
const blur = (value) => {
$emit('blur', value)
}
const focus = (e) => {
$emit('focus', e)
}
const change = (value) => {
$emit('change', value)
}
const handleFilter = () => {
dialog.value.open('bottom')
}
const close = () => {
dialog.value.close()
}
defineExpose({
close
})
</script> -->
<script>
import EtDialog from '@/components/dialog'
export default {
name: 'Search',
components: { EtDialog },
props: {
modelValue: [Number, String],
placeholder: String,
/* 百分比高度 */
height: {
type: Number,
default: 90
}
},
data() {
return {
innerValue: ''
}
},
created() {
// #ifdef VUE3
this.innerValue = this.modelValue
// #endif
},
watch: {
modelValue(newVal) {
this.innerValue = newVal
}
},
methods: {
onInput(value) {
this.innerValue = value
this.$nextTick(() => {
this.valueChange()
})
},
onClear() {
this.innerValue = ""
this.$nextTick(() => {
this.$emit("clear")
this.valueChange()
})
},
onBlur(value) {
this.$emit("blur", value)
},
onFocus() {
this.$emit("focus")
},
onFilter() {
this.$refs.dialog.open('bottom')
},
valueChange() {
const value = this.innerValue
this.$nextTick(() => {
this.$emit("input", value)
this.$emit("update:modelValue", value)
this.$emit("change", value)
})
}
}
}
</script>
<template>
<view class="filter-search">
<uni-easyinput prefixIcon="search" v-model="innerValue" :placeholder="placeholder" @input="onInput" @clear="onClear" @blur="onBlur" @focus="onFocus"></uni-easyinput>
<view class="uv-icon_box">
<uv-icon custom-prefix="et-icon" name="filtration" size="22" @click="onFilter"></uv-icon>
</view>
</view>
<et-dialog ref="dialog" title="筛选">
<slot />
</et-dialog>
</template>
<style scoped lang="scss">
.filter-search {
display: flex;
align-items: center;
padding-top: 3px;
.uv-icon_box {
margin-left: 8rpx;
}
.uni-popup {
}
}
</style>
使用组件
在Search 组件中不能嵌套 slot, 会导致出现Maximum recursive updates exceeded in component
<script>
import { defineComponent, ref, reactive } from 'vue'
import { onReady } from '@dcloudio/uni-app'
import Search from '@/components/Search'
export default defineComponent({
components: [Search],
setup() {
const title = ref('Hello')
const initParam = reactive({
title: undefined,
dateStr: undefined
})
const tableData = []
onReady(() => {
console.log('onReady')
})
function handleResetForm() { }
function handleQuery() { }
function handleInput() { }
function handleRow() { }
return {
title,
tableData,
initParam,
handleResetForm,
handleQuery,
handleInput,
handleRow
}
}
})
</script>
<template>
<view class="page-search">
<view class hover-class="none" hover-stop-propagation="false">{{initParam.title}}</view>
<Search ref="refSearch" placeholder="输入关键字" v-model="initParam.title" @input="handleInput">
<view class="page-table-form">
<uni-forms labelPosition="top" :modelValue="initParam" ref="refForm" labelWidth="100%" :rules="{}">
<uni-forms-item label="日期" prop="dateStr">
<uni-datetime-picker type="date" v-model="initParam.dateStr" placeholder="请选择" :border="false" />
</uni-forms-item>
</uni-forms>
<view class="et-dialog__footer">
<uv-button text="重置" @click="handleResetForm"></uv-button>
<uv-button type="primary" text="确定" @click="handleFormConfirm"></uv-button>
</view>
</view>
</Search>
</view>
</template>
4***@qq.com (作者)
好的,下面提供了代码。
2025-08-21 10:35