升级到 vue3
This commit is contained in:
@@ -0,0 +1,108 @@
|
||||
<template>
|
||||
<div :class="$style.control">
|
||||
<button type="button" :class="[$style.btn, $style.min]" :tips="$t('min')" @click="min">
|
||||
<svg :class="$style.controlBtniIcon" version="1.1" xmlns="http://www.w3.org/2000/svg" xlink="http://www.w3.org/1999/xlink" width="100%" viewBox="0 0 24 24" space="preserve">
|
||||
<use xlink:href="#icon-window-minimize"></use>
|
||||
</svg>
|
||||
</button>
|
||||
<button type="button" :class="[$style.btn, $style.close]" :tips="$t('close')" @click="close">
|
||||
<svg :class="$style.controlBtniIcon" version="1.1" xmlns="http://www.w3.org/2000/svg" xlink="http://www.w3.org/1999/xlink" width="100%" viewBox="0 0 24 24" space="preserve">
|
||||
<use xlink:href="#icon-window-close"></use>
|
||||
</svg>
|
||||
</button>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { base as eventBaseName } from '@renderer/event/names'
|
||||
// import { getRandom } from '../../utils'
|
||||
|
||||
export default {
|
||||
setup() {
|
||||
return {
|
||||
min() {
|
||||
window.eventHub.emit(eventBaseName.min)
|
||||
},
|
||||
max() {
|
||||
window.eventHub.emit(eventBaseName.max)
|
||||
},
|
||||
close() {
|
||||
window.eventHub.emit(eventBaseName.close)
|
||||
},
|
||||
}
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
|
||||
|
||||
<style lang="less" module>
|
||||
@import '@renderer/assets/styles/layout.less';
|
||||
|
||||
@control-btn-width: @height-toolbar * .26;
|
||||
|
||||
.control {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
height: 100%;
|
||||
left: 15px;
|
||||
-webkit-app-region: no-drag;
|
||||
padding: 0 @control-btn-width * 1.5;
|
||||
&:hover {
|
||||
.controlBtniIcon {
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
|
||||
.btn {
|
||||
display: flex;
|
||||
position: relative;
|
||||
width: @control-btn-width;
|
||||
height: @control-btn-width;
|
||||
background: none;
|
||||
border: none;
|
||||
outline: none;
|
||||
padding: 1px;
|
||||
cursor: pointer;
|
||||
border-radius: 50%;
|
||||
color: @color-theme_2;
|
||||
|
||||
+ .btn {
|
||||
margin-left: @control-btn-width * 1.2;
|
||||
}
|
||||
|
||||
&.min {
|
||||
background-color: @color-minBtn;
|
||||
}
|
||||
&.max {
|
||||
background-color: @color-maxBtn;
|
||||
}
|
||||
&.close {
|
||||
background-color: @color-closeBtn;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.controlBtniIcon {
|
||||
opacity: 0;
|
||||
transition: opacity 0.2s ease-in-out;
|
||||
}
|
||||
|
||||
each(@themes, {
|
||||
:global(#root.@{value}) {
|
||||
.btn {
|
||||
color: ~'@{color-@{value}-theme_2}';
|
||||
|
||||
&.min {
|
||||
background-color: ~'@{color-@{value}-minBtn}';
|
||||
}
|
||||
&.max {
|
||||
background-color: ~'@{color-@{value}-maxBtn}';
|
||||
}
|
||||
&.close {
|
||||
background-color: ~'@{color-@{value}-closeBtn}';
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
</style>
|
||||
@@ -0,0 +1,109 @@
|
||||
<template>
|
||||
<material-search-input @event="handleEvent" :list="tipList" :visibleList="visibleList" v-model="searchText" />
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import music from '@renderer/utils/music'
|
||||
import { debounce } from '@renderer/utils'
|
||||
import {
|
||||
ref,
|
||||
useRoute,
|
||||
useGetter,
|
||||
watch,
|
||||
useRefGetter,
|
||||
useRouter,
|
||||
nextTick,
|
||||
useCommit,
|
||||
} from '@renderer/utils/vueTools'
|
||||
|
||||
export default {
|
||||
setup() {
|
||||
const searchText = ref('')
|
||||
const visibleList = ref(false)
|
||||
const tipList = ref([])
|
||||
let isFocused = false
|
||||
|
||||
const route = useRoute()
|
||||
const router = useRouter()
|
||||
|
||||
const setting = useGetter('setting')
|
||||
|
||||
const clearSearchList = useCommit('search', 'clearList')
|
||||
|
||||
watch(() => route.name, (newValue, oldValue) => {
|
||||
if (newValue.name != 'search') {
|
||||
if (setting.odc.isAutoClearSearchInput && searchText.value) searchText.value = ''
|
||||
if (setting.odc.isAutoClearSearchList) clearSearchList()
|
||||
}
|
||||
})
|
||||
|
||||
const storeSearchText = useRefGetter('search', 'searchText')
|
||||
watch(storeSearchText, (newValue, oldValue) => {
|
||||
searchText.value = newValue
|
||||
if (newValue !== searchText.value) searchText.value = newValue
|
||||
})
|
||||
watch(searchText, () => {
|
||||
handleTipSearch()
|
||||
})
|
||||
|
||||
|
||||
const tipSearch = debounce(() => {
|
||||
if (searchText.value === '') {
|
||||
tipList.value = []
|
||||
music[setting.search.tempSearchSource].tempSearch.cancelTempSearch()
|
||||
return
|
||||
}
|
||||
music[setting.search.tempSearchSource].tempSearch.search(searchText.value).then(list => {
|
||||
tipList.value = list
|
||||
}).catch(() => {})
|
||||
}, 50)
|
||||
|
||||
const handleTipSearch = () => {
|
||||
if (!visibleList.value && isFocused) visibleList.value = true
|
||||
tipSearch()
|
||||
}
|
||||
|
||||
const handleSearch = () => {
|
||||
if (visibleList.value) visibleList.value = false
|
||||
setTimeout(() => {
|
||||
router.push({
|
||||
path: 'search',
|
||||
query: {
|
||||
text: searchText.value,
|
||||
},
|
||||
}).catch(_ => _)
|
||||
}, 200)
|
||||
}
|
||||
|
||||
const handleEvent = ({ action, data }) => {
|
||||
switch (action) {
|
||||
case 'focus':
|
||||
isFocused = true
|
||||
if (!visibleList.value) visibleList.value = true
|
||||
if (searchText.value) handleTipSearch()
|
||||
break
|
||||
case 'blur':
|
||||
isFocused = false
|
||||
setTimeout(() => {
|
||||
if (visibleList.value) visibleList.value = false
|
||||
}, 50)
|
||||
break
|
||||
case 'submit':
|
||||
handleSearch()
|
||||
break
|
||||
case 'listClick':
|
||||
searchText.value = tipList[data]
|
||||
nextTick(handleSearch)
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
searchText,
|
||||
visibleList,
|
||||
tipList,
|
||||
handleEvent,
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
</script>
|
||||
@@ -0,0 +1,65 @@
|
||||
<template>
|
||||
<div :class="[$style.toolbar, setting.controlBtnPosition == 'left' ? $style.controlBtnLeft : $style.controlBtnRight]">
|
||||
<SearchInput />
|
||||
<div :class="$style.logo" v-if="setting.controlBtnPosition == 'left'">L X</div>
|
||||
<ControlBtns v-else />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { mapGetters } from 'vuex'
|
||||
|
||||
import ControlBtns from './ControlBtns'
|
||||
import SearchInput from './SearchInput'
|
||||
|
||||
export default {
|
||||
components: { SearchInput, ControlBtns },
|
||||
computed: {
|
||||
...mapGetters(['setting']),
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
|
||||
<style lang="less" module>
|
||||
@import '@renderer/assets/styles/layout.less';
|
||||
|
||||
.toolbar {
|
||||
display: flex;
|
||||
height: @height-toolbar;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
padding-left: 15px;
|
||||
-webkit-app-region: drag;
|
||||
z-index: 2;
|
||||
|
||||
&.controlBtnLeft {
|
||||
.control {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
&.controlBtnRight {
|
||||
justify-content: space-between;
|
||||
}
|
||||
}
|
||||
|
||||
.logo {
|
||||
box-sizing: border-box;
|
||||
padding: 0 @height-toolbar * .4;
|
||||
height: @height-toolbar;
|
||||
color: @color-theme;
|
||||
flex: none;
|
||||
text-align: center;
|
||||
line-height: @height-toolbar;
|
||||
font-weight: bold;
|
||||
// -webkit-app-region: no-drag;
|
||||
}
|
||||
|
||||
each(@themes, {
|
||||
:global(#root.@{value}) {
|
||||
.logo {
|
||||
color: ~'@{color-@{value}-theme}';
|
||||
}
|
||||
}
|
||||
})
|
||||
</style>
|
||||
Reference in New Issue
Block a user