mirror of
https://github.com/element-plus/element-plus.git
synced 2025-12-19 09:09:40 +08:00
* docs: improve examples layout for narrow screens * docs: style related * style: [statistic] use utilities * style: [input] remove deep * style: [transitions] change style * refactor: [date-picker-panel] narrow refactor
199 lines
4.7 KiB
Vue
199 lines
4.7 KiB
Vue
<template>
|
|
<div class="demo-autocomplete">
|
|
<div class="demo-block">
|
|
<div class="demo-title">loading icon1</div>
|
|
<el-autocomplete
|
|
v-model="state"
|
|
:fetch-suggestions="querySearchAsync"
|
|
class="w-50"
|
|
placeholder="Please input"
|
|
@select="handleSelect"
|
|
>
|
|
<template #loading>
|
|
<svg class="circular" viewBox="0 0 50 50">
|
|
<circle class="path" cx="25" cy="25" r="20" fill="none" />
|
|
</svg>
|
|
</template>
|
|
</el-autocomplete>
|
|
</div>
|
|
<div class="demo-block">
|
|
<div class="demo-title">loading icon2</div>
|
|
<el-autocomplete
|
|
v-model="state"
|
|
:fetch-suggestions="querySearchAsync"
|
|
class="w-50"
|
|
placeholder="Please input"
|
|
@select="handleSelect"
|
|
>
|
|
<template #loading>
|
|
<el-icon class="is-loading">
|
|
<svg class="circular" viewBox="0 0 20 20">
|
|
<g
|
|
class="path2 loading-path"
|
|
stroke-width="0"
|
|
style="animation: none; stroke: none"
|
|
>
|
|
<circle r="3.375" class="dot1" rx="0" ry="0" />
|
|
<circle r="3.375" class="dot2" rx="0" ry="0" />
|
|
<circle r="3.375" class="dot4" rx="0" ry="0" />
|
|
<circle r="3.375" class="dot3" rx="0" ry="0" />
|
|
</g>
|
|
</svg>
|
|
</el-icon>
|
|
</template>
|
|
</el-autocomplete>
|
|
</div>
|
|
</div>
|
|
</template>
|
|
|
|
<script lang="ts" setup>
|
|
import { onMounted, ref } from 'vue'
|
|
|
|
const state = ref('')
|
|
|
|
interface LinkItem {
|
|
value: string
|
|
link: string
|
|
}
|
|
|
|
const links = ref<LinkItem[]>([])
|
|
|
|
const loadAll = () => {
|
|
return [
|
|
{ value: 'vue', link: 'https://github.com/vuejs/vue' },
|
|
{ value: 'element', link: 'https://github.com/ElemeFE/element' },
|
|
{ value: 'cooking', link: 'https://github.com/ElemeFE/cooking' },
|
|
{ value: 'mint-ui', link: 'https://github.com/ElemeFE/mint-ui' },
|
|
{ value: 'vuex', link: 'https://github.com/vuejs/vuex' },
|
|
{ value: 'vue-router', link: 'https://github.com/vuejs/vue-router' },
|
|
{ value: 'babel', link: 'https://github.com/babel/babel' },
|
|
]
|
|
}
|
|
|
|
let timeout: ReturnType<typeof setTimeout>
|
|
const querySearchAsync = (queryString: string, cb: (arg: any) => void) => {
|
|
const results = queryString
|
|
? links.value.filter(createFilter(queryString))
|
|
: links.value
|
|
|
|
clearTimeout(timeout)
|
|
timeout = setTimeout(() => {
|
|
cb(results)
|
|
}, 5000 * Math.random())
|
|
}
|
|
const createFilter = (queryString: string) => {
|
|
return (restaurant: LinkItem) => {
|
|
return (
|
|
restaurant.value.toLowerCase().indexOf(queryString.toLowerCase()) === 0
|
|
)
|
|
}
|
|
}
|
|
|
|
const handleSelect = (item: Record<string, any>) => {
|
|
console.log(item)
|
|
}
|
|
|
|
onMounted(() => {
|
|
links.value = loadAll()
|
|
})
|
|
</script>
|
|
|
|
<style scoped>
|
|
.demo-autocomplete {
|
|
display: flex;
|
|
flex-wrap: wrap;
|
|
gap: 2rem;
|
|
}
|
|
|
|
.demo-block {
|
|
display: flex;
|
|
flex-direction: column;
|
|
gap: 0.5rem;
|
|
}
|
|
|
|
.demo-title {
|
|
font-size: 0.875rem;
|
|
color: var(--el-text-color-secondary);
|
|
min-height: 2.5em;
|
|
display: flex;
|
|
align-items: center;
|
|
}
|
|
|
|
@media screen and (max-width: 768px) {
|
|
.demo-autocomplete {
|
|
gap: 1rem;
|
|
}
|
|
.demo-block {
|
|
width: 100%;
|
|
}
|
|
}
|
|
</style>
|
|
|
|
<style>
|
|
.circular {
|
|
display: inline;
|
|
height: 30px;
|
|
width: 30px;
|
|
animation: loading-rotate 2s linear infinite;
|
|
}
|
|
.path {
|
|
animation: loading-dash 1.5s ease-in-out infinite;
|
|
stroke-dasharray: 90, 150;
|
|
stroke-dashoffset: 0;
|
|
stroke-width: 2;
|
|
stroke: var(--el-color-primary);
|
|
stroke-linecap: round;
|
|
}
|
|
.loading-path .dot1 {
|
|
transform: translate(3.75px, 3.75px);
|
|
fill: var(--el-color-primary);
|
|
animation: custom-spin-move 1s infinite linear alternate;
|
|
opacity: 0.3;
|
|
}
|
|
.loading-path .dot2 {
|
|
transform: translate(calc(100% - 3.75px), 3.75px);
|
|
fill: var(--el-color-primary);
|
|
animation: custom-spin-move 1s infinite linear alternate;
|
|
opacity: 0.3;
|
|
animation-delay: 0.4s;
|
|
}
|
|
.loading-path .dot3 {
|
|
transform: translate(3.75px, calc(100% - 3.75px));
|
|
fill: var(--el-color-primary);
|
|
animation: custom-spin-move 1s infinite linear alternate;
|
|
opacity: 0.3;
|
|
animation-delay: 1.2s;
|
|
}
|
|
.loading-path .dot4 {
|
|
transform: translate(calc(100% - 3.75px), calc(100% - 3.75px));
|
|
fill: var(--el-color-primary);
|
|
animation: custom-spin-move 1s infinite linear alternate;
|
|
opacity: 0.3;
|
|
animation-delay: 0.8s;
|
|
}
|
|
@keyframes loading-rotate {
|
|
to {
|
|
transform: rotate(360deg);
|
|
}
|
|
}
|
|
@keyframes loading-dash {
|
|
0% {
|
|
stroke-dasharray: 1, 200;
|
|
stroke-dashoffset: 0;
|
|
}
|
|
50% {
|
|
stroke-dasharray: 90, 150;
|
|
stroke-dashoffset: -40px;
|
|
}
|
|
100% {
|
|
stroke-dasharray: 90, 150;
|
|
stroke-dashoffset: -120px;
|
|
}
|
|
}
|
|
@keyframes custom-spin-move {
|
|
to {
|
|
opacity: 1;
|
|
}
|
|
}
|
|
</style>
|