mirror of
https://github.com/vbenjs/vben-admin-thin-next.git
synced 2025-01-23 09:40:22 +08:00
refactor(sys): change to setup syntax
This commit is contained in:
parent
66feb779a8
commit
bb89c5059c
@ -25,6 +25,7 @@ module.exports = defineConfig({
|
||||
'plugin:jest/recommended',
|
||||
],
|
||||
rules: {
|
||||
'vue/script-setup-uses-vars': 'error',
|
||||
'@typescript-eslint/ban-ts-ignore': 'off',
|
||||
'@typescript-eslint/explicit-function-return-type': 'off',
|
||||
'@typescript-eslint/no-explicit-any': 'off',
|
||||
@ -61,7 +62,6 @@ module.exports = defineConfig({
|
||||
'vue/singleline-html-element-content-newline': 'off',
|
||||
'vue/attribute-hyphenation': 'off',
|
||||
'vue/require-default-prop': 'off',
|
||||
'vue/script-setup-uses-vars': 'off',
|
||||
'vue/html-self-closing': [
|
||||
'error',
|
||||
{
|
||||
|
17
src/App.vue
17
src/App.vue
@ -6,23 +6,14 @@
|
||||
</ConfigProvider>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { defineComponent } from 'vue';
|
||||
<script lang="ts" setup>
|
||||
import { ConfigProvider } from 'ant-design-vue';
|
||||
import { AppProvider } from '/@/components/Application';
|
||||
import { useTitle } from '/@/hooks/web/useTitle';
|
||||
import { useLocale } from '/@/locales/useLocale';
|
||||
|
||||
export default defineComponent({
|
||||
name: 'App',
|
||||
components: { ConfigProvider, AppProvider },
|
||||
setup() {
|
||||
useTitle();
|
||||
// support Multi-language
|
||||
const { getAntdLocale } = useLocale();
|
||||
|
||||
// support Multi-language
|
||||
const { getAntdLocale } = useLocale();
|
||||
|
||||
return { getAntdLocale };
|
||||
},
|
||||
});
|
||||
useTitle();
|
||||
</script>
|
||||
|
@ -1,8 +1,8 @@
|
||||
<template>
|
||||
<Button v-bind="getBindValue" :class="getButtonClass" @click="onClick">
|
||||
<template #default="data">
|
||||
<template #default>
|
||||
<Icon :icon="preIcon" v-if="preIcon" :size="iconSize" />
|
||||
<slot v-bind="data"></slot>
|
||||
<slot></slot>
|
||||
<Icon :icon="postIcon" v-if="postIcon" :size="iconSize" />
|
||||
</template>
|
||||
</Button>
|
||||
|
@ -14,94 +14,85 @@
|
||||
<Description @register="registerDev" class="enter-y" />
|
||||
</PageWrapper>
|
||||
</template>
|
||||
<script lang="ts">
|
||||
import { defineComponent, h } from 'vue';
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { h } from 'vue';
|
||||
import { Tag } from 'ant-design-vue';
|
||||
import { PageWrapper } from '/@/components/Page';
|
||||
import { Description, DescItem, useDescription } from '/@/components/Description/index';
|
||||
|
||||
import { GITHUB_URL, SITE_URL, DOC_URL } from '/@/settings/siteSetting';
|
||||
export default defineComponent({
|
||||
name: 'AboutPage',
|
||||
components: { Description, PageWrapper },
|
||||
setup() {
|
||||
const { pkg, lastBuildTime } = __APP_INFO__;
|
||||
|
||||
const { dependencies, devDependencies, name, version } = pkg;
|
||||
const { pkg, lastBuildTime } = __APP_INFO__;
|
||||
|
||||
const schema: DescItem[] = [];
|
||||
const devSchema: DescItem[] = [];
|
||||
const { dependencies, devDependencies, name, version } = pkg;
|
||||
|
||||
const commonTagRender = (color: string) => (curVal) => h(Tag, { color }, () => curVal);
|
||||
const commonLinkRender = (text: string) => (href) => h('a', { href, target: '_blank' }, text);
|
||||
const schema: DescItem[] = [];
|
||||
const devSchema: DescItem[] = [];
|
||||
|
||||
const infoSchema: DescItem[] = [
|
||||
{
|
||||
label: '版本',
|
||||
field: 'version',
|
||||
render: commonTagRender('blue'),
|
||||
},
|
||||
{
|
||||
label: '最后编译时间',
|
||||
field: 'lastBuildTime',
|
||||
render: commonTagRender('blue'),
|
||||
},
|
||||
{
|
||||
label: '文档地址',
|
||||
field: 'doc',
|
||||
render: commonLinkRender('文档地址'),
|
||||
},
|
||||
{
|
||||
label: '预览地址',
|
||||
field: 'preview',
|
||||
render: commonLinkRender('预览地址'),
|
||||
},
|
||||
{
|
||||
label: 'Github',
|
||||
field: 'github',
|
||||
render: commonLinkRender('Github'),
|
||||
},
|
||||
];
|
||||
const commonTagRender = (color: string) => (curVal) => h(Tag, { color }, () => curVal);
|
||||
const commonLinkRender = (text: string) => (href) => h('a', { href, target: '_blank' }, text);
|
||||
|
||||
const infoData = {
|
||||
version,
|
||||
lastBuildTime,
|
||||
doc: DOC_URL,
|
||||
preview: SITE_URL,
|
||||
github: GITHUB_URL,
|
||||
};
|
||||
|
||||
Object.keys(dependencies).forEach((key) => {
|
||||
schema.push({ field: key, label: key });
|
||||
});
|
||||
|
||||
Object.keys(devDependencies).forEach((key) => {
|
||||
devSchema.push({ field: key, label: key });
|
||||
});
|
||||
|
||||
const [register] = useDescription({
|
||||
title: '生产环境依赖',
|
||||
data: dependencies,
|
||||
schema: schema,
|
||||
column: 3,
|
||||
});
|
||||
|
||||
const [registerDev] = useDescription({
|
||||
title: '开发环境依赖',
|
||||
data: devDependencies,
|
||||
schema: devSchema,
|
||||
column: 3,
|
||||
});
|
||||
|
||||
const [infoRegister] = useDescription({
|
||||
title: '项目信息',
|
||||
data: infoData,
|
||||
schema: infoSchema,
|
||||
column: 2,
|
||||
});
|
||||
|
||||
return { register, registerDev, infoRegister, name, GITHUB_URL };
|
||||
const infoSchema: DescItem[] = [
|
||||
{
|
||||
label: '版本',
|
||||
field: 'version',
|
||||
render: commonTagRender('blue'),
|
||||
},
|
||||
{
|
||||
label: '最后编译时间',
|
||||
field: 'lastBuildTime',
|
||||
render: commonTagRender('blue'),
|
||||
},
|
||||
{
|
||||
label: '文档地址',
|
||||
field: 'doc',
|
||||
render: commonLinkRender('文档地址'),
|
||||
},
|
||||
{
|
||||
label: '预览地址',
|
||||
field: 'preview',
|
||||
render: commonLinkRender('预览地址'),
|
||||
},
|
||||
{
|
||||
label: 'Github',
|
||||
field: 'github',
|
||||
render: commonLinkRender('Github'),
|
||||
},
|
||||
];
|
||||
|
||||
const infoData = {
|
||||
version,
|
||||
lastBuildTime,
|
||||
doc: DOC_URL,
|
||||
preview: SITE_URL,
|
||||
github: GITHUB_URL,
|
||||
};
|
||||
|
||||
Object.keys(dependencies).forEach((key) => {
|
||||
schema.push({ field: key, label: key });
|
||||
});
|
||||
|
||||
Object.keys(devDependencies).forEach((key) => {
|
||||
devSchema.push({ field: key, label: key });
|
||||
});
|
||||
|
||||
const [register] = useDescription({
|
||||
title: '生产环境依赖',
|
||||
data: dependencies,
|
||||
schema: schema,
|
||||
column: 3,
|
||||
});
|
||||
|
||||
const [registerDev] = useDescription({
|
||||
title: '开发环境依赖',
|
||||
data: devDependencies,
|
||||
schema: devSchema,
|
||||
column: 3,
|
||||
});
|
||||
|
||||
const [infoRegister] = useDescription({
|
||||
title: '项目信息',
|
||||
data: infoData,
|
||||
schema: infoSchema,
|
||||
column: 2,
|
||||
});
|
||||
</script>
|
||||
|
@ -3,40 +3,26 @@
|
||||
<Description :data="info" @register="register" />
|
||||
</BasicModal>
|
||||
</template>
|
||||
<script lang="ts">
|
||||
<script lang="ts" setup>
|
||||
import type { PropType } from 'vue';
|
||||
import type { ErrorLogInfo } from '/#/store';
|
||||
|
||||
import { defineComponent } from 'vue';
|
||||
import { defineProps } from 'vue';
|
||||
import { BasicModal } from '/@/components/Modal/index';
|
||||
import { Description, useDescription } from '/@/components/Description/index';
|
||||
|
||||
import { useI18n } from '/@/hooks/web/useI18n';
|
||||
|
||||
import { getDescSchema } from './data';
|
||||
|
||||
export default defineComponent({
|
||||
name: 'ErrorLogDetailModal',
|
||||
components: { BasicModal, Description },
|
||||
props: {
|
||||
info: {
|
||||
type: Object as PropType<ErrorLogInfo>,
|
||||
default: null,
|
||||
},
|
||||
},
|
||||
setup() {
|
||||
const { t } = useI18n();
|
||||
|
||||
const [register] = useDescription({
|
||||
column: 2,
|
||||
schema: getDescSchema()!,
|
||||
});
|
||||
|
||||
return {
|
||||
register,
|
||||
useI18n,
|
||||
t,
|
||||
};
|
||||
defineProps({
|
||||
info: {
|
||||
type: Object as PropType<ErrorLogInfo>,
|
||||
default: null,
|
||||
},
|
||||
});
|
||||
|
||||
const { t } = useI18n();
|
||||
|
||||
const [register] = useDescription({
|
||||
column: 2,
|
||||
schema: getDescSchema()!,
|
||||
});
|
||||
</script>
|
||||
|
@ -27,91 +27,66 @@
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
<script lang="ts" setup>
|
||||
import type { ErrorLogInfo } from '/#/store';
|
||||
|
||||
import { defineComponent, watch, ref, nextTick } from 'vue';
|
||||
|
||||
import { watch, ref, nextTick } from 'vue';
|
||||
import DetailModal from './DetailModal.vue';
|
||||
import { BasicTable, useTable, TableAction } from '/@/components/Table/index';
|
||||
|
||||
import { useModal } from '/@/components/Modal';
|
||||
import { useMessage } from '/@/hooks/web/useMessage';
|
||||
import { useI18n } from '/@/hooks/web/useI18n';
|
||||
|
||||
import { useErrorLogStore } from '/@/store/modules/errorLog';
|
||||
|
||||
import { fireErrorApi } from '/@/api/demo/error';
|
||||
|
||||
import { getColumns } from './data';
|
||||
|
||||
import { cloneDeep } from 'lodash-es';
|
||||
|
||||
export default defineComponent({
|
||||
name: 'ErrorHandler',
|
||||
components: { DetailModal, BasicTable, TableAction },
|
||||
setup() {
|
||||
const rowInfo = ref<ErrorLogInfo>();
|
||||
const imgList = ref<string[]>([]);
|
||||
const rowInfo = ref<ErrorLogInfo>();
|
||||
const imgList = ref<string[]>([]);
|
||||
|
||||
const { t } = useI18n();
|
||||
const errorLogStore = useErrorLogStore();
|
||||
const [register, { setTableData }] = useTable({
|
||||
title: t('sys.errorLog.tableTitle'),
|
||||
columns: getColumns(),
|
||||
actionColumn: {
|
||||
width: 80,
|
||||
title: 'Action',
|
||||
dataIndex: 'action',
|
||||
slots: { customRender: 'action' },
|
||||
},
|
||||
});
|
||||
const [registerModal, { openModal }] = useModal();
|
||||
|
||||
watch(
|
||||
() => errorLogStore.getErrorLogInfoList,
|
||||
(list) => {
|
||||
nextTick(() => {
|
||||
setTableData(cloneDeep(list));
|
||||
});
|
||||
},
|
||||
{
|
||||
immediate: true,
|
||||
}
|
||||
);
|
||||
const { createMessage } = useMessage();
|
||||
if (import.meta.env.DEV) {
|
||||
createMessage.info(t('sys.errorLog.enableMessage'));
|
||||
}
|
||||
// 查看详情
|
||||
function handleDetail(row: ErrorLogInfo) {
|
||||
rowInfo.value = row;
|
||||
openModal(true);
|
||||
}
|
||||
|
||||
function fireVueError() {
|
||||
throw new Error('fire vue error!');
|
||||
}
|
||||
|
||||
function fireResourceError() {
|
||||
imgList.value.push(`${new Date().getTime()}.png`);
|
||||
}
|
||||
|
||||
async function fireAjaxError() {
|
||||
await fireErrorApi();
|
||||
}
|
||||
|
||||
return {
|
||||
register,
|
||||
registerModal,
|
||||
handleDetail,
|
||||
fireVueError,
|
||||
fireResourceError,
|
||||
fireAjaxError,
|
||||
imgList,
|
||||
rowInfo,
|
||||
t,
|
||||
};
|
||||
const { t } = useI18n();
|
||||
const errorLogStore = useErrorLogStore();
|
||||
const [register, { setTableData }] = useTable({
|
||||
title: t('sys.errorLog.tableTitle'),
|
||||
columns: getColumns(),
|
||||
actionColumn: {
|
||||
width: 80,
|
||||
title: 'Action',
|
||||
dataIndex: 'action',
|
||||
slots: { customRender: 'action' },
|
||||
},
|
||||
});
|
||||
const [registerModal, { openModal }] = useModal();
|
||||
|
||||
watch(
|
||||
() => errorLogStore.getErrorLogInfoList,
|
||||
(list) => {
|
||||
nextTick(() => {
|
||||
setTableData(cloneDeep(list));
|
||||
});
|
||||
},
|
||||
{
|
||||
immediate: true,
|
||||
}
|
||||
);
|
||||
const { createMessage } = useMessage();
|
||||
if (import.meta.env.DEV) {
|
||||
createMessage.info(t('sys.errorLog.enableMessage'));
|
||||
}
|
||||
// 查看详情
|
||||
function handleDetail(row: ErrorLogInfo) {
|
||||
rowInfo.value = row;
|
||||
openModal(true);
|
||||
}
|
||||
|
||||
function fireVueError() {
|
||||
throw new Error('fire vue error!');
|
||||
}
|
||||
|
||||
function fireResourceError() {
|
||||
imgList.value.push(`${new Date().getTime()}.png`);
|
||||
}
|
||||
|
||||
async function fireAjaxError() {
|
||||
await fireErrorApi();
|
||||
}
|
||||
</script>
|
||||
|
@ -1,19 +1,14 @@
|
||||
<script lang="tsx">
|
||||
import type { PropType } from 'vue';
|
||||
|
||||
import { Result, Button } from 'ant-design-vue';
|
||||
import { defineComponent, ref, computed, unref } from 'vue';
|
||||
|
||||
import { ExceptionEnum } from '/@/enums/exceptionEnum';
|
||||
|
||||
import notDataSvg from '/@/assets/svg/no-data.svg';
|
||||
import netWorkSvg from '/@/assets/svg/net-error.svg';
|
||||
|
||||
import { useRoute } from 'vue-router';
|
||||
import { useDesign } from '/@/hooks/web/useDesign';
|
||||
import { useI18n } from '/@/hooks/web/useI18n';
|
||||
import { useGo, useRedo } from '/@/hooks/web/usePage';
|
||||
|
||||
import { PageEnum } from '/@/enums/pageEnum';
|
||||
|
||||
interface MapValue {
|
||||
|
@ -10,66 +10,50 @@
|
||||
</Spin>
|
||||
</div>
|
||||
</template>
|
||||
<script lang="ts">
|
||||
<script lang="ts" setup>
|
||||
import type { CSSProperties } from 'vue';
|
||||
import { defineComponent, ref, unref, computed } from 'vue';
|
||||
import { ref, unref, computed, defineProps } from 'vue';
|
||||
import { Spin } from 'ant-design-vue';
|
||||
|
||||
import { useWindowSizeFn } from '/@/hooks/event/useWindowSizeFn';
|
||||
|
||||
import { propTypes } from '/@/utils/propTypes';
|
||||
import { useDesign } from '/@/hooks/web/useDesign';
|
||||
import { useLayoutHeight } from '/@/layouts/default/content/useContentViewHeight';
|
||||
|
||||
export default defineComponent({
|
||||
name: 'IFrame',
|
||||
components: { Spin },
|
||||
props: {
|
||||
frameSrc: propTypes.string.def(''),
|
||||
},
|
||||
setup() {
|
||||
const loading = ref(true);
|
||||
const topRef = ref(50);
|
||||
const heightRef = ref(window.innerHeight);
|
||||
const frameRef = ref<HTMLFrameElement>();
|
||||
const { headerHeightRef } = useLayoutHeight();
|
||||
|
||||
const { prefixCls } = useDesign('iframe-page');
|
||||
useWindowSizeFn(calcHeight, 150, { immediate: true });
|
||||
|
||||
const getWrapStyle = computed((): CSSProperties => {
|
||||
return {
|
||||
height: `${unref(heightRef)}px`,
|
||||
};
|
||||
});
|
||||
|
||||
function calcHeight() {
|
||||
const iframe = unref(frameRef);
|
||||
if (!iframe) {
|
||||
return;
|
||||
}
|
||||
const top = headerHeightRef.value;
|
||||
topRef.value = top;
|
||||
heightRef.value = window.innerHeight - top;
|
||||
const clientHeight = document.documentElement.clientHeight - top;
|
||||
iframe.style.height = `${clientHeight}px`;
|
||||
}
|
||||
|
||||
function hideLoading() {
|
||||
loading.value = false;
|
||||
calcHeight();
|
||||
}
|
||||
|
||||
return {
|
||||
getWrapStyle,
|
||||
loading,
|
||||
frameRef,
|
||||
prefixCls,
|
||||
|
||||
hideLoading,
|
||||
};
|
||||
},
|
||||
defineProps({
|
||||
frameSrc: propTypes.string.def(''),
|
||||
});
|
||||
|
||||
const loading = ref(true);
|
||||
const topRef = ref(50);
|
||||
const heightRef = ref(window.innerHeight);
|
||||
const frameRef = ref<HTMLFrameElement>();
|
||||
const { headerHeightRef } = useLayoutHeight();
|
||||
|
||||
const { prefixCls } = useDesign('iframe-page');
|
||||
useWindowSizeFn(calcHeight, 150, { immediate: true });
|
||||
|
||||
const getWrapStyle = computed((): CSSProperties => {
|
||||
return {
|
||||
height: `${unref(heightRef)}px`,
|
||||
};
|
||||
});
|
||||
|
||||
function calcHeight() {
|
||||
const iframe = unref(frameRef);
|
||||
if (!iframe) {
|
||||
return;
|
||||
}
|
||||
const top = headerHeightRef.value;
|
||||
topRef.value = top;
|
||||
heightRef.value = window.innerHeight - top;
|
||||
const clientHeight = document.documentElement.clientHeight - top;
|
||||
iframe.style.height = `${clientHeight}px`;
|
||||
}
|
||||
|
||||
function hideLoading() {
|
||||
loading.value = false;
|
||||
calcHeight();
|
||||
}
|
||||
</script>
|
||||
<style lang="less" scoped>
|
||||
@prefix-cls: ~'@{namespace}-iframe-page';
|
||||
|
@ -92,84 +92,61 @@
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<script lang="ts">
|
||||
import { defineComponent, ref, computed } from 'vue';
|
||||
<script lang="ts" setup>
|
||||
import { ref, computed } from 'vue';
|
||||
import { Input } from 'ant-design-vue';
|
||||
|
||||
import { useUserStore } from '/@/store/modules/user';
|
||||
import { useLockStore } from '/@/store/modules/lock';
|
||||
import { useI18n } from '/@/hooks/web/useI18n';
|
||||
|
||||
import { useNow } from './useNow';
|
||||
import { useDesign } from '/@/hooks/web/useDesign';
|
||||
|
||||
import { LockOutlined } from '@ant-design/icons-vue';
|
||||
import headerImg from '/@/assets/images/header.jpg';
|
||||
|
||||
export default defineComponent({
|
||||
name: 'LockPage',
|
||||
components: { LockOutlined, InputPassword: Input.Password },
|
||||
const InputPassword = Input.Password;
|
||||
|
||||
setup() {
|
||||
const password = ref('');
|
||||
const loading = ref(false);
|
||||
const errMsg = ref(false);
|
||||
const showDate = ref(true);
|
||||
const password = ref('');
|
||||
const loading = ref(false);
|
||||
const errMsg = ref(false);
|
||||
const showDate = ref(true);
|
||||
|
||||
const { prefixCls } = useDesign('lock-page');
|
||||
const lockStore = useLockStore();
|
||||
const userStore = useUserStore();
|
||||
const { prefixCls } = useDesign('lock-page');
|
||||
const lockStore = useLockStore();
|
||||
const userStore = useUserStore();
|
||||
|
||||
const { ...state } = useNow(true);
|
||||
const { hour, month, minute, meridiem, year, day, week } = useNow(true);
|
||||
|
||||
const { t } = useI18n();
|
||||
const { t } = useI18n();
|
||||
|
||||
const userinfo = computed(() => {
|
||||
return userStore.getUserInfo || {};
|
||||
});
|
||||
|
||||
/**
|
||||
* @description: unLock
|
||||
*/
|
||||
async function unLock() {
|
||||
if (!password.value) {
|
||||
return;
|
||||
}
|
||||
let pwd = password.value;
|
||||
try {
|
||||
loading.value = true;
|
||||
const res = await lockStore.unLock(pwd);
|
||||
errMsg.value = !res;
|
||||
} finally {
|
||||
loading.value = false;
|
||||
}
|
||||
}
|
||||
|
||||
function goLogin() {
|
||||
userStore.logout(true);
|
||||
lockStore.resetLockInfo();
|
||||
}
|
||||
|
||||
function handleShowForm(show = false) {
|
||||
showDate.value = show;
|
||||
}
|
||||
|
||||
return {
|
||||
goLogin,
|
||||
userinfo,
|
||||
unLock,
|
||||
errMsg,
|
||||
loading,
|
||||
t,
|
||||
prefixCls,
|
||||
showDate,
|
||||
password,
|
||||
handleShowForm,
|
||||
headerImg,
|
||||
...state,
|
||||
};
|
||||
},
|
||||
const userinfo = computed(() => {
|
||||
return userStore.getUserInfo || {};
|
||||
});
|
||||
|
||||
/**
|
||||
* @description: unLock
|
||||
*/
|
||||
async function unLock() {
|
||||
if (!password.value) {
|
||||
return;
|
||||
}
|
||||
let pwd = password.value;
|
||||
try {
|
||||
loading.value = true;
|
||||
const res = await lockStore.unLock(pwd);
|
||||
errMsg.value = !res;
|
||||
} finally {
|
||||
loading.value = false;
|
||||
}
|
||||
}
|
||||
|
||||
function goLogin() {
|
||||
userStore.logout(true);
|
||||
lockStore.resetLockInfo();
|
||||
}
|
||||
|
||||
function handleShowForm(show = false) {
|
||||
showDate.value = show;
|
||||
}
|
||||
</script>
|
||||
<style lang="less" scoped>
|
||||
@prefix-cls: ~'@{namespace}-lock-page';
|
||||
|
@ -3,18 +3,11 @@
|
||||
<LockPage v-if="getIsLock" />
|
||||
</transition>
|
||||
</template>
|
||||
<script lang="ts">
|
||||
import { defineComponent, computed } from 'vue';
|
||||
<script lang="ts" setup>
|
||||
import { computed } from 'vue';
|
||||
import LockPage from './LockPage.vue';
|
||||
|
||||
import { useLockStore } from '/@/store/modules/lock';
|
||||
export default defineComponent({
|
||||
name: 'Lock',
|
||||
components: { LockPage },
|
||||
setup() {
|
||||
const lockStore = useLockStore();
|
||||
const getIsLock = computed(() => lockStore?.getLockInfo?.isLock ?? false);
|
||||
return { getIsLock };
|
||||
},
|
||||
});
|
||||
|
||||
const lockStore = useLockStore();
|
||||
const getIsLock = computed(() => lockStore?.getLockInfo?.isLock ?? false);
|
||||
</script>
|
||||
|
@ -32,58 +32,33 @@
|
||||
</Form>
|
||||
</template>
|
||||
</template>
|
||||
<script lang="ts">
|
||||
import { defineComponent, reactive, ref, computed, unref } from 'vue';
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { reactive, ref, computed, unref } from 'vue';
|
||||
import LoginFormTitle from './LoginFormTitle.vue';
|
||||
import { Form, Input, Button } from 'ant-design-vue';
|
||||
import { CountdownInput } from '/@/components/CountDown';
|
||||
|
||||
import { useI18n } from '/@/hooks/web/useI18n';
|
||||
import { useLoginState, useFormRules, LoginStateEnum } from './useLogin';
|
||||
|
||||
export default defineComponent({
|
||||
name: 'ForgetPasswordForm',
|
||||
components: {
|
||||
Button,
|
||||
Form,
|
||||
FormItem: Form.Item,
|
||||
Input,
|
||||
CountdownInput,
|
||||
LoginFormTitle,
|
||||
},
|
||||
setup() {
|
||||
const { t } = useI18n();
|
||||
const { handleBackLogin, getLoginState } = useLoginState();
|
||||
const { getFormRules } = useFormRules();
|
||||
const FormItem = Form.Item;
|
||||
const { t } = useI18n();
|
||||
const { handleBackLogin, getLoginState } = useLoginState();
|
||||
const { getFormRules } = useFormRules();
|
||||
|
||||
const formRef = ref();
|
||||
const loading = ref(false);
|
||||
const formRef = ref();
|
||||
const loading = ref(false);
|
||||
|
||||
const formData = reactive({
|
||||
account: '',
|
||||
mobile: '',
|
||||
sms: '',
|
||||
});
|
||||
|
||||
const getShow = computed(() => unref(getLoginState) === LoginStateEnum.RESET_PASSWORD);
|
||||
|
||||
async function handleReset() {
|
||||
const form = unref(formRef);
|
||||
if (!form) return;
|
||||
await form.resetFields();
|
||||
}
|
||||
|
||||
return {
|
||||
t,
|
||||
formRef,
|
||||
formData,
|
||||
getFormRules,
|
||||
handleReset,
|
||||
loading,
|
||||
handleBackLogin,
|
||||
getShow,
|
||||
};
|
||||
},
|
||||
const formData = reactive({
|
||||
account: '',
|
||||
mobile: '',
|
||||
sms: '',
|
||||
});
|
||||
|
||||
const getShow = computed(() => unref(getLoginState) === LoginStateEnum.RESET_PASSWORD);
|
||||
|
||||
async function handleReset() {
|
||||
const form = unref(formRef);
|
||||
if (!form) return;
|
||||
await form.resetFields();
|
||||
}
|
||||
</script>
|
||||
|
@ -61,9 +61,8 @@
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<script lang="ts">
|
||||
import { defineComponent, computed } from 'vue';
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { computed, defineProps } from 'vue';
|
||||
import { AppLogo } from '/@/components/Application';
|
||||
import { AppLocalePicker, AppDarkModeToggle } from '/@/components/Application';
|
||||
import LoginForm from './LoginForm.vue';
|
||||
@ -71,43 +70,23 @@
|
||||
import RegisterForm from './RegisterForm.vue';
|
||||
import MobileForm from './MobileForm.vue';
|
||||
import QrCodeForm from './QrCodeForm.vue';
|
||||
|
||||
import { useGlobSetting } from '/@/hooks/setting';
|
||||
import { useI18n } from '/@/hooks/web/useI18n';
|
||||
import { useDesign } from '/@/hooks/web/useDesign';
|
||||
import { useLocaleStore } from '/@/store/modules/locale';
|
||||
|
||||
export default defineComponent({
|
||||
name: 'Login',
|
||||
components: {
|
||||
AppLogo,
|
||||
LoginForm,
|
||||
ForgetPasswordForm,
|
||||
RegisterForm,
|
||||
MobileForm,
|
||||
QrCodeForm,
|
||||
AppLocalePicker,
|
||||
AppDarkModeToggle,
|
||||
},
|
||||
props: {
|
||||
sessionTimeout: {
|
||||
type: Boolean,
|
||||
},
|
||||
},
|
||||
setup() {
|
||||
const globSetting = useGlobSetting();
|
||||
const { prefixCls } = useDesign('login');
|
||||
const { t } = useI18n();
|
||||
const localeStore = useLocaleStore();
|
||||
|
||||
return {
|
||||
t,
|
||||
prefixCls,
|
||||
title: computed(() => globSetting?.title ?? ''),
|
||||
showLocale: localeStore.getShowPicker,
|
||||
};
|
||||
defineProps({
|
||||
sessionTimeout: {
|
||||
type: Boolean,
|
||||
},
|
||||
});
|
||||
|
||||
const globSetting = useGlobSetting();
|
||||
const { prefixCls } = useDesign('login');
|
||||
const { t } = useI18n();
|
||||
const localeStore = useLocaleStore();
|
||||
const showLocale = localeStore.getShowPicker;
|
||||
const title = computed(() => globSetting?.title ?? '');
|
||||
</script>
|
||||
<style lang="less">
|
||||
@prefix-cls: ~'@{namespace}-login';
|
||||
|
@ -81,8 +81,8 @@
|
||||
</div>
|
||||
</Form>
|
||||
</template>
|
||||
<script lang="ts">
|
||||
import { defineComponent, reactive, ref, toRaw, unref, computed } from 'vue';
|
||||
<script lang="ts" setup>
|
||||
import { reactive, ref, toRaw, unref, computed } from 'vue';
|
||||
|
||||
import { Checkbox, Form, Input, Row, Col, Button, Divider } from 'ant-design-vue';
|
||||
import {
|
||||
@ -102,92 +102,60 @@
|
||||
import { useDesign } from '/@/hooks/web/useDesign';
|
||||
//import { onKeyStroke } from '@vueuse/core';
|
||||
|
||||
export default defineComponent({
|
||||
name: 'LoginForm',
|
||||
components: {
|
||||
[Col.name]: Col,
|
||||
[Row.name]: Row,
|
||||
Checkbox,
|
||||
Button,
|
||||
Form,
|
||||
FormItem: Form.Item,
|
||||
Input,
|
||||
Divider,
|
||||
LoginFormTitle,
|
||||
InputPassword: Input.Password,
|
||||
GithubFilled,
|
||||
WechatFilled,
|
||||
AlipayCircleFilled,
|
||||
GoogleCircleFilled,
|
||||
TwitterCircleFilled,
|
||||
},
|
||||
setup() {
|
||||
const { t } = useI18n();
|
||||
const { notification, createErrorModal } = useMessage();
|
||||
const { prefixCls } = useDesign('login');
|
||||
const userStore = useUserStore();
|
||||
const ACol = Col;
|
||||
const ARow = Row;
|
||||
const FormItem = Form.Item;
|
||||
const InputPassword = Input.Password;
|
||||
const { t } = useI18n();
|
||||
const { notification, createErrorModal } = useMessage();
|
||||
const { prefixCls } = useDesign('login');
|
||||
const userStore = useUserStore();
|
||||
|
||||
const { setLoginState, getLoginState } = useLoginState();
|
||||
const { getFormRules } = useFormRules();
|
||||
const { setLoginState, getLoginState } = useLoginState();
|
||||
const { getFormRules } = useFormRules();
|
||||
|
||||
const formRef = ref();
|
||||
const loading = ref(false);
|
||||
const rememberMe = ref(false);
|
||||
const formRef = ref();
|
||||
const loading = ref(false);
|
||||
const rememberMe = ref(false);
|
||||
|
||||
const formData = reactive({
|
||||
account: 'vben',
|
||||
password: '123456',
|
||||
});
|
||||
|
||||
const { validForm } = useFormValid(formRef);
|
||||
|
||||
//onKeyStroke('Enter', handleLogin);
|
||||
|
||||
const getShow = computed(() => unref(getLoginState) === LoginStateEnum.LOGIN);
|
||||
|
||||
async function handleLogin() {
|
||||
const data = await validForm();
|
||||
if (!data) return;
|
||||
try {
|
||||
loading.value = true;
|
||||
const userInfo = await userStore.login(
|
||||
toRaw({
|
||||
password: data.password,
|
||||
username: data.account,
|
||||
mode: 'none', //不要默认的错误提示
|
||||
})
|
||||
);
|
||||
if (userInfo) {
|
||||
notification.success({
|
||||
message: t('sys.login.loginSuccessTitle'),
|
||||
description: `${t('sys.login.loginSuccessDesc')}: ${userInfo.realName}`,
|
||||
duration: 3,
|
||||
});
|
||||
}
|
||||
} catch (error) {
|
||||
createErrorModal({
|
||||
title: t('sys.api.errorTip'),
|
||||
content: error.message || t('sys.api.networkExceptionMsg'),
|
||||
getContainer: () => document.body.querySelector(`.${prefixCls}`) || document.body,
|
||||
});
|
||||
} finally {
|
||||
loading.value = false;
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
t,
|
||||
prefixCls,
|
||||
formRef,
|
||||
formData,
|
||||
getFormRules,
|
||||
rememberMe,
|
||||
handleLogin,
|
||||
loading,
|
||||
setLoginState,
|
||||
LoginStateEnum,
|
||||
getShow,
|
||||
};
|
||||
},
|
||||
const formData = reactive({
|
||||
account: 'vben',
|
||||
password: '123456',
|
||||
});
|
||||
|
||||
const { validForm } = useFormValid(formRef);
|
||||
|
||||
//onKeyStroke('Enter', handleLogin);
|
||||
|
||||
const getShow = computed(() => unref(getLoginState) === LoginStateEnum.LOGIN);
|
||||
|
||||
async function handleLogin() {
|
||||
const data = await validForm();
|
||||
if (!data) return;
|
||||
try {
|
||||
loading.value = true;
|
||||
const userInfo = await userStore.login(
|
||||
toRaw({
|
||||
password: data.password,
|
||||
username: data.account,
|
||||
mode: 'none', //不要默认的错误提示
|
||||
})
|
||||
);
|
||||
if (userInfo) {
|
||||
notification.success({
|
||||
message: t('sys.login.loginSuccessTitle'),
|
||||
description: `${t('sys.login.loginSuccessDesc')}: ${userInfo.realName}`,
|
||||
duration: 3,
|
||||
});
|
||||
}
|
||||
} catch (error) {
|
||||
createErrorModal({
|
||||
title: t('sys.api.errorTip'),
|
||||
content: error.message || t('sys.api.networkExceptionMsg'),
|
||||
getContainer: () => document.body.querySelector(`.${prefixCls}`) || document.body,
|
||||
});
|
||||
} finally {
|
||||
loading.value = false;
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
@ -3,33 +3,23 @@
|
||||
{{ getFormTitle }}
|
||||
</h2>
|
||||
</template>
|
||||
<script lang="ts">
|
||||
import { defineComponent, computed, unref } from 'vue';
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { computed, unref } from 'vue';
|
||||
import { useI18n } from '/@/hooks/web/useI18n';
|
||||
import { LoginStateEnum, useLoginState } from './useLogin';
|
||||
|
||||
export default defineComponent({
|
||||
name: 'LoginFormTitle',
|
||||
setup() {
|
||||
const { t } = useI18n();
|
||||
const { t } = useI18n();
|
||||
|
||||
const { getLoginState } = useLoginState();
|
||||
const { getLoginState } = useLoginState();
|
||||
|
||||
const getFormTitle = computed(() => {
|
||||
const titleObj = {
|
||||
[LoginStateEnum.RESET_PASSWORD]: t('sys.login.forgetFormTitle'),
|
||||
[LoginStateEnum.LOGIN]: t('sys.login.signInFormTitle'),
|
||||
[LoginStateEnum.REGISTER]: t('sys.login.signUpFormTitle'),
|
||||
[LoginStateEnum.MOBILE]: t('sys.login.mobileSignInFormTitle'),
|
||||
[LoginStateEnum.QR_CODE]: t('sys.login.qrSignInFormTitle'),
|
||||
};
|
||||
return titleObj[unref(getLoginState)];
|
||||
});
|
||||
|
||||
return {
|
||||
getFormTitle,
|
||||
};
|
||||
},
|
||||
const getFormTitle = computed(() => {
|
||||
const titleObj = {
|
||||
[LoginStateEnum.RESET_PASSWORD]: t('sys.login.forgetFormTitle'),
|
||||
[LoginStateEnum.LOGIN]: t('sys.login.signInFormTitle'),
|
||||
[LoginStateEnum.REGISTER]: t('sys.login.signUpFormTitle'),
|
||||
[LoginStateEnum.MOBILE]: t('sys.login.mobileSignInFormTitle'),
|
||||
[LoginStateEnum.QR_CODE]: t('sys.login.qrSignInFormTitle'),
|
||||
};
|
||||
return titleObj[unref(getLoginState)];
|
||||
});
|
||||
</script>
|
||||
|
@ -30,59 +30,34 @@
|
||||
</Form>
|
||||
</template>
|
||||
</template>
|
||||
<script lang="ts">
|
||||
import { defineComponent, reactive, ref, computed, unref } from 'vue';
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { reactive, ref, computed, unref } from 'vue';
|
||||
import { Form, Input, Button } from 'ant-design-vue';
|
||||
import { CountdownInput } from '/@/components/CountDown';
|
||||
import LoginFormTitle from './LoginFormTitle.vue';
|
||||
|
||||
import { useI18n } from '/@/hooks/web/useI18n';
|
||||
import { useLoginState, useFormRules, useFormValid, LoginStateEnum } from './useLogin';
|
||||
|
||||
export default defineComponent({
|
||||
name: 'MobileForm',
|
||||
components: {
|
||||
Button,
|
||||
Form,
|
||||
FormItem: Form.Item,
|
||||
Input,
|
||||
CountdownInput,
|
||||
LoginFormTitle,
|
||||
},
|
||||
setup() {
|
||||
const { t } = useI18n();
|
||||
const { handleBackLogin, getLoginState } = useLoginState();
|
||||
const { getFormRules } = useFormRules();
|
||||
const FormItem = Form.Item;
|
||||
const { t } = useI18n();
|
||||
const { handleBackLogin, getLoginState } = useLoginState();
|
||||
const { getFormRules } = useFormRules();
|
||||
|
||||
const formRef = ref();
|
||||
const loading = ref(false);
|
||||
const formRef = ref();
|
||||
const loading = ref(false);
|
||||
|
||||
const formData = reactive({
|
||||
mobile: '',
|
||||
sms: '',
|
||||
});
|
||||
|
||||
const { validForm } = useFormValid(formRef);
|
||||
|
||||
const getShow = computed(() => unref(getLoginState) === LoginStateEnum.MOBILE);
|
||||
|
||||
async function handleLogin() {
|
||||
const data = await validForm();
|
||||
if (!data) return;
|
||||
console.log(data);
|
||||
}
|
||||
|
||||
return {
|
||||
t,
|
||||
formRef,
|
||||
formData,
|
||||
getFormRules,
|
||||
handleLogin,
|
||||
loading,
|
||||
handleBackLogin,
|
||||
getShow,
|
||||
};
|
||||
},
|
||||
const formData = reactive({
|
||||
mobile: '',
|
||||
sms: '',
|
||||
});
|
||||
|
||||
const { validForm } = useFormValid(formRef);
|
||||
|
||||
const getShow = computed(() => unref(getLoginState) === LoginStateEnum.MOBILE);
|
||||
|
||||
async function handleLogin() {
|
||||
const data = await validForm();
|
||||
if (!data) return;
|
||||
console.log(data);
|
||||
}
|
||||
</script>
|
||||
|
@ -14,37 +14,18 @@
|
||||
</div>
|
||||
</template>
|
||||
</template>
|
||||
<script lang="ts">
|
||||
import { defineComponent, computed, unref } from 'vue';
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { computed, unref } from 'vue';
|
||||
import LoginFormTitle from './LoginFormTitle.vue';
|
||||
import { Button, Divider } from 'ant-design-vue';
|
||||
import { QrCode } from '/@/components/Qrcode/index';
|
||||
|
||||
import { useI18n } from '/@/hooks/web/useI18n';
|
||||
import { useLoginState, LoginStateEnum } from './useLogin';
|
||||
|
||||
const qrCodeUrl = 'https://vvbin.cn/next/login';
|
||||
export default defineComponent({
|
||||
name: 'QrCodeForm',
|
||||
components: {
|
||||
Button,
|
||||
QrCode,
|
||||
Divider,
|
||||
LoginFormTitle,
|
||||
},
|
||||
setup() {
|
||||
const { t } = useI18n();
|
||||
const { handleBackLogin, getLoginState } = useLoginState();
|
||||
|
||||
const getShow = computed(() => unref(getLoginState) === LoginStateEnum.QR_CODE);
|
||||
const { t } = useI18n();
|
||||
const { handleBackLogin, getLoginState } = useLoginState();
|
||||
|
||||
return {
|
||||
t,
|
||||
handleBackLogin,
|
||||
qrCodeUrl,
|
||||
getShow,
|
||||
};
|
||||
},
|
||||
});
|
||||
const getShow = computed(() => unref(getLoginState) === LoginStateEnum.QR_CODE);
|
||||
</script>
|
||||
|
@ -65,67 +65,40 @@
|
||||
</Form>
|
||||
</template>
|
||||
</template>
|
||||
<script lang="ts">
|
||||
import { defineComponent, reactive, ref, unref, computed } from 'vue';
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { reactive, ref, unref, computed } from 'vue';
|
||||
import LoginFormTitle from './LoginFormTitle.vue';
|
||||
import { Form, Input, Button, Checkbox } from 'ant-design-vue';
|
||||
import { StrengthMeter } from '/@/components/StrengthMeter';
|
||||
import { CountdownInput } from '/@/components/CountDown';
|
||||
|
||||
import { useI18n } from '/@/hooks/web/useI18n';
|
||||
import { useLoginState, useFormRules, useFormValid, LoginStateEnum } from './useLogin';
|
||||
|
||||
export default defineComponent({
|
||||
name: 'RegisterPasswordForm',
|
||||
components: {
|
||||
Button,
|
||||
Form,
|
||||
FormItem: Form.Item,
|
||||
Input,
|
||||
InputPassword: Input.Password,
|
||||
Checkbox,
|
||||
StrengthMeter,
|
||||
CountdownInput,
|
||||
LoginFormTitle,
|
||||
},
|
||||
setup() {
|
||||
const { t } = useI18n();
|
||||
const { handleBackLogin, getLoginState } = useLoginState();
|
||||
const FormItem = Form.Item;
|
||||
const InputPassword = Input.Password;
|
||||
const { t } = useI18n();
|
||||
const { handleBackLogin, getLoginState } = useLoginState();
|
||||
|
||||
const formRef = ref();
|
||||
const loading = ref(false);
|
||||
const formRef = ref();
|
||||
const loading = ref(false);
|
||||
|
||||
const formData = reactive({
|
||||
account: '',
|
||||
password: '',
|
||||
confirmPassword: '',
|
||||
mobile: '',
|
||||
sms: '',
|
||||
policy: false,
|
||||
});
|
||||
|
||||
const { getFormRules } = useFormRules(formData);
|
||||
const { validForm } = useFormValid(formRef);
|
||||
|
||||
const getShow = computed(() => unref(getLoginState) === LoginStateEnum.REGISTER);
|
||||
|
||||
async function handleRegister() {
|
||||
const data = await validForm();
|
||||
if (!data) return;
|
||||
console.log(data);
|
||||
}
|
||||
|
||||
return {
|
||||
t,
|
||||
formRef,
|
||||
formData,
|
||||
getFormRules,
|
||||
handleRegister,
|
||||
loading,
|
||||
handleBackLogin,
|
||||
getShow,
|
||||
};
|
||||
},
|
||||
const formData = reactive({
|
||||
account: '',
|
||||
password: '',
|
||||
confirmPassword: '',
|
||||
mobile: '',
|
||||
sms: '',
|
||||
policy: false,
|
||||
});
|
||||
|
||||
const { getFormRules } = useFormRules(formData);
|
||||
const { validForm } = useFormValid(formRef);
|
||||
|
||||
const getShow = computed(() => unref(getLoginState) === LoginStateEnum.REGISTER);
|
||||
|
||||
async function handleRegister() {
|
||||
const data = await validForm();
|
||||
if (!data) return;
|
||||
console.log(data);
|
||||
}
|
||||
</script>
|
||||
|
@ -5,47 +5,39 @@
|
||||
</div>
|
||||
</transition>
|
||||
</template>
|
||||
<script lang="ts">
|
||||
import { defineComponent, onBeforeUnmount, onMounted, ref } from 'vue';
|
||||
<script lang="ts" setup>
|
||||
import { onBeforeUnmount, onMounted, ref } from 'vue';
|
||||
import Login from './Login.vue';
|
||||
|
||||
import { useDesign } from '/@/hooks/web/useDesign';
|
||||
import { useUserStore } from '/@/store/modules/user';
|
||||
import { usePermissionStore } from '/@/store/modules/permission';
|
||||
import { useAppStore } from '/@/store/modules/app';
|
||||
import { PermissionModeEnum } from '/@/enums/appEnum';
|
||||
export default defineComponent({
|
||||
name: 'SessionTimeoutLogin',
|
||||
components: { Login },
|
||||
setup() {
|
||||
const { prefixCls } = useDesign('st-login');
|
||||
const userStore = useUserStore();
|
||||
const permissionStore = usePermissionStore();
|
||||
const appStore = useAppStore();
|
||||
const userId = ref<Nullable<number | string>>(0);
|
||||
|
||||
const isBackMode = () => {
|
||||
return appStore.getProjectConfig.permissionMode === PermissionModeEnum.BACK;
|
||||
};
|
||||
const { prefixCls } = useDesign('st-login');
|
||||
const userStore = useUserStore();
|
||||
const permissionStore = usePermissionStore();
|
||||
const appStore = useAppStore();
|
||||
const userId = ref<Nullable<number | string>>(0);
|
||||
|
||||
onMounted(() => {
|
||||
// 记录当前的UserId
|
||||
userId.value = userStore.getUserInfo?.userId;
|
||||
console.log('Mounted', userStore.getUserInfo);
|
||||
});
|
||||
const isBackMode = () => {
|
||||
return appStore.getProjectConfig.permissionMode === PermissionModeEnum.BACK;
|
||||
};
|
||||
|
||||
onBeforeUnmount(() => {
|
||||
if (userId.value && userId.value !== userStore.getUserInfo.userId) {
|
||||
// 登录的不是同一个用户,刷新整个页面以便丢弃之前用户的页面状态
|
||||
document.location.reload();
|
||||
} else if (isBackMode() && permissionStore.getLastBuildMenuTime === 0) {
|
||||
// 后台权限模式下,没有成功加载过菜单,就重新加载整个页面。这通常发生在会话过期后按F5刷新整个页面后载入了本模块这种场景
|
||||
document.location.reload();
|
||||
}
|
||||
});
|
||||
onMounted(() => {
|
||||
// 记录当前的UserId
|
||||
userId.value = userStore.getUserInfo?.userId;
|
||||
console.log('Mounted', userStore.getUserInfo);
|
||||
});
|
||||
|
||||
return { prefixCls };
|
||||
},
|
||||
onBeforeUnmount(() => {
|
||||
if (userId.value && userId.value !== userStore.getUserInfo.userId) {
|
||||
// 登录的不是同一个用户,刷新整个页面以便丢弃之前用户的页面状态
|
||||
document.location.reload();
|
||||
} else if (isBackMode() && permissionStore.getLastBuildMenuTime === 0) {
|
||||
// 后台权限模式下,没有成功加载过菜单,就重新加载整个页面。这通常发生在会话过期后按F5刷新整个页面后载入了本模块这种场景
|
||||
document.location.reload();
|
||||
}
|
||||
});
|
||||
</script>
|
||||
<style lang="less" scoped>
|
||||
|
@ -1,26 +1,19 @@
|
||||
<template>
|
||||
<div></div>
|
||||
</template>
|
||||
<script lang="ts">
|
||||
import { defineComponent, unref } from 'vue';
|
||||
<script lang="ts" setup>
|
||||
import { unref } from 'vue';
|
||||
import { useRouter } from 'vue-router';
|
||||
|
||||
export default defineComponent({
|
||||
name: 'Redirect',
|
||||
setup() {
|
||||
const { currentRoute, replace } = useRouter();
|
||||
const { currentRoute, replace } = useRouter();
|
||||
|
||||
const { params, query } = unref(currentRoute);
|
||||
const { path } = params;
|
||||
const { params, query } = unref(currentRoute);
|
||||
const { path } = params;
|
||||
|
||||
const _path = Array.isArray(path) ? path.join('/') : path;
|
||||
const _path = Array.isArray(path) ? path.join('/') : path;
|
||||
|
||||
replace({
|
||||
path: '/' + _path,
|
||||
query,
|
||||
});
|
||||
|
||||
return {};
|
||||
},
|
||||
replace({
|
||||
path: '/' + _path,
|
||||
query,
|
||||
});
|
||||
</script>
|
||||
|
Loading…
Reference in New Issue
Block a user