This commit is contained in:
huzhushan 2021-04-19 19:47:17 +08:00
parent 77e94d2f3d
commit c5265e7fc2
43 changed files with 555 additions and 555 deletions

View File

@ -1,4 +1,4 @@
import request from '@/utils/request';
import request from '@/utils/request'
// 登录接口
export const Login = data => {
@ -6,13 +6,13 @@ export const Login = data => {
url: '/api/login',
method: 'post',
data,
});
};
})
}
// 获取登录用户信息
export const GetUserinfo = () => {
return request({
url: '/api/userinfo',
method: 'get',
});
};
})
}

View File

@ -1,9 +1,9 @@
import request from '@/utils/request';
import request from '@/utils/request'
// 获取菜单
export const GetMenus = () => {
return request({
url: '/api/menus',
method: 'get',
});
};
})
}

View File

@ -212,7 +212,7 @@
</div>
</template>
<script>
import { defineComponent, reactive, toRefs, onBeforeMount } from 'vue';
import { defineComponent, reactive, toRefs, onBeforeMount } from 'vue'
const formatDate = (date, format) => {
var obj = {
'M+': date.getMonth() + 1,
@ -222,12 +222,12 @@ const formatDate = (date, format) => {
's+': date.getSeconds(),
'q+': Math.floor((date.getMonth() + 3) / 3),
'S+': date.getMilliseconds(),
};
}
if (/(y+)/i.test(format)) {
format = format.replace(
RegExp.$1,
(date.getFullYear() + '').substr(4 - RegExp.$1.length)
);
)
}
for (var k in obj) {
if (new RegExp('(' + k + ')').test(format)) {
@ -236,25 +236,25 @@ const formatDate = (date, format) => {
RegExp.$1.length == 1
? obj[k]
: ('00' + obj[k]).substr(('' + obj[k]).length)
);
)
}
}
return format;
};
return format
}
const getSearchModel = search => {
const searchModel = {};
const searchModel = {}
if (search && search.fields) {
search.fields.forEach(item => {
switch (item.type) {
case 'checkbox':
case 'checkbox-button':
searchModel[item.name] = [];
break;
searchModel[item.name] = []
break
default:
break;
break
}
if (item.defaultValue !== undefined) {
searchModel[item.name] = item.defaultValue;
searchModel[item.name] = item.defaultValue
//
if (
(item.type === 'daterange' || item.type === 'datetimerange') &&
@ -262,14 +262,14 @@ const getSearchModel = search => {
Array.isArray(item.defaultValue)
) {
item.defaultValue.forEach((val, index) => {
searchModel[item.trueNames[index]] = val;
});
searchModel[item.trueNames[index]] = val
})
}
}
});
})
}
return searchModel
}
return searchModel;
};
export default defineComponent({
props: {
//
@ -316,43 +316,43 @@ export default defineComponent({
// 1transformtransform
// 2name
const optimizeFields = search => {
const searchModel = JSON.parse(JSON.stringify(state.searchModel));
const searchModel = JSON.parse(JSON.stringify(state.searchModel))
if (search && search.fields) {
search.fields.forEach(item => {
if (!searchModel.hasOwnProperty(item.name)) {
return;
return
}
if (item.transform) {
searchModel[item.name] = item.transform(searchModel[item.name]);
searchModel[item.name] = item.transform(searchModel[item.name])
}
if (
(item.type === 'daterange' || item.type === 'datetimerange') &&
!!item.trueNames
) {
delete searchModel[item.name];
delete searchModel[item.name]
}
});
})
}
return searchModel
}
return searchModel;
};
//
const getTableData = async () => {
state.loading = true;
const searchModel = optimizeFields(props.search);
state.loading = true
const searchModel = optimizeFields(props.search)
const { data, total } = await props.request({
pageNum: state.pageNum,
pageSize: state.pageSize,
...searchModel,
});
state.loading = false;
state.tableData = data;
state.total = total;
};
})
state.loading = false
state.tableData = data
state.total = total
}
onBeforeMount(() => {
getTableData();
});
getTableData()
})
const state = reactive({
searchModel: getSearchModel(props.search),
@ -366,80 +366,80 @@ export default defineComponent({
},
//
handleSearch() {
state.pageNum = 1;
getTableData();
state.pageNum = 1
getTableData()
},
//
handleReset() {
if (JSON.stringify(state.searchModel) === '{}') {
return;
return
}
state.pageNum = 1;
state.searchModel = getSearchModel(props.search);
getTableData();
state.pageNum = 1
state.searchModel = getSearchModel(props.search)
getTableData()
},
//
refresh() {
getTableData();
getTableData()
},
//
handleCurrentChange() {
getTableData();
getTableData()
},
// size
handleSizeChange() {
state.pageNum = 1;
getTableData();
state.pageNum = 1
getTableData()
},
//
handleSelectionChange(arr) {
emit('selectionChange', arr);
emit('selectionChange', arr)
},
//
filterHandler(value, row, column) {
const property = column['property'];
return row[property] === value;
const property = column['property']
return row[property] === value
},
//
handleDateChange(date, item, format) {
state.searchModel[item.name] = date ? formatDate(date, format) : '';
state.searchModel[item.name] = date ? formatDate(date, format) : ''
},
handleRangeChange(date, item, format) {
const arr = !!date && date.map(d => formatDate(d, format));
state.searchModel[item.name] = arr ? arr : [];
const arr = !!date && date.map(d => formatDate(d, format))
state.searchModel[item.name] = arr ? arr : []
if (!item.trueNames) {
return;
return
}
if (arr) {
arr.forEach((val, index) => {
state.searchModel[item.trueNames[index]] = val;
});
state.searchModel[item.trueNames[index]] = val
})
} else {
item.trueNames.forEach(key => {
delete state.searchModel[key];
});
delete state.searchModel[key]
})
}
},
});
})
if (typeof props.pagination === 'object') {
const { layout, pageSizes, style } = props.pagination;
const { layout, pageSizes, style } = props.pagination
state.paginationConfig = {
show: true,
layout: layout || 'total, sizes, prev, pager, next, jumper',
pageSizes: pageSizes || [10, 20, 30, 40, 50, 100],
style: style || {},
};
}
}
return {
...toRefs(state),
};
}
},
});
})
</script>
<style lang="scss" scoped>
.page-box {

View File

@ -5,7 +5,7 @@
</template>
<script>
import { defineComponent, computed } from 'vue';
import { defineComponent, computed } from 'vue'
export default defineComponent({
name: 'SvgIcon',
@ -20,10 +20,10 @@ export default defineComponent({
},
},
setup(props) {
const symbolId = computed(() => `#${props.prefix}-${props.name}`);
return { symbolId };
const symbolId = computed(() => `#${props.prefix}-${props.name}`)
return { symbolId }
},
});
})
</script>
<style lang="scss" scoped>

View File

@ -1,2 +1,2 @@
export { default as SvgIcon } from '@/components/SvgIcon/index.vue';
export { default as ProTable } from '@/components/ProTable/index.vue';
export { default as SvgIcon } from '@/components/SvgIcon/index.vue'
export { default as ProTable } from '@/components/ProTable/index.vue'

View File

@ -6,21 +6,21 @@
</router-view>
</template>
<script>
import { computed, defineComponent } from 'vue';
import { useRoute } from 'vue-router';
import { useStore } from 'vuex';
import { computed, defineComponent } from 'vue'
import { useRoute } from 'vue-router'
import { useStore } from 'vuex'
export default defineComponent({
setup() {
const store = useStore();
const route = useRoute();
const cacheList = computed(() => store.state.tags.cacheList);
const key = computed(() => route.fullPath);
const store = useStore()
const route = useRoute()
const cacheList = computed(() => store.state.tags.cacheList)
const key = computed(() => route.fullPath)
return {
cacheList,
key,
};
}
},
});
})
</script>

View File

@ -5,18 +5,18 @@
</template>
<script>
import { computed, defineComponent } from 'vue';
import { computed, defineComponent } from 'vue'
export default defineComponent({
props: ['title', 'icon'],
setup({ icon }) {
const isElementIcon = computed(() => icon && icon.startsWith('el-icon'));
const isElementIcon = computed(() => icon && icon.startsWith('el-icon'))
return {
isElementIcon,
};
}
},
});
})
</script>
<style lang="scss" scoped>
.icon {

View File

@ -5,18 +5,18 @@
</div>
</template>
<script>
import { defineComponent } from 'vue';
import { useRouter } from 'vue-router';
import { defineComponent } from 'vue'
import { useRouter } from 'vue-router'
export default defineComponent({
setup() {
const router = useRouter();
const router = useRouter()
const goHome = () => {
router.push('/');
};
return { goHome };
router.push('/')
}
return { goHome }
},
});
})
</script>
<style lang="scss" scoped>
.brand {

View File

@ -15,11 +15,11 @@
</el-scrollbar>
</template>
<script>
import { computed, defineComponent } from 'vue';
import Submenu from './Submenu.vue';
import { useStore } from 'vuex';
import { useRoute } from 'vue-router';
import config from './config/menu.module.scss';
import { computed, defineComponent } from 'vue'
import Submenu from './Submenu.vue'
import { useStore } from 'vuex'
import { useRoute } from 'vue-router'
import config from './config/menu.module.scss'
export default defineComponent({
components: {
@ -32,20 +32,20 @@ export default defineComponent({
},
},
setup() {
const route = useRoute();
const store = useStore();
const route = useRoute()
const store = useStore()
store.dispatch(
'menu/generateMenus',
store.state.account.userinfo && store.state.account.userinfo.role
);
)
return {
menus: computed(() => store.state.menu.menus),
activePath: computed(() => route.path),
variables: computed(() => config),
};
}
},
});
})
</script>
<style lang="scss">
// menu hover

View File

@ -15,8 +15,8 @@
</el-submenu>
</template>
<script>
import { defineComponent } from 'vue';
import Item from './Item.vue';
import { defineComponent } from 'vue'
import Item from './Item.vue'
export default defineComponent({
name: 'Submenu',
components: {
@ -32,5 +32,5 @@ export default defineComponent({
default: false,
},
},
});
})
</script>

View File

@ -10,10 +10,10 @@
</template>
<script>
import { defineComponent, computed } from 'vue';
import Logo from './Logo.vue';
import Menus from './Menus.vue';
import { useStore } from 'vuex';
import { defineComponent, computed } from 'vue'
import Logo from './Logo.vue'
import Menus from './Menus.vue'
import { useStore } from 'vuex'
export default defineComponent({
components: {
@ -21,21 +21,21 @@ export default defineComponent({
Menus,
},
setup() {
const store = useStore();
const collapse = computed(() => !!store.state.app.sidebar.collapse);
const device = computed(() => store.state.app.device);
const store = useStore()
const collapse = computed(() => !!store.state.app.sidebar.collapse)
const device = computed(() => store.state.app.device)
const closeSidebar = () => {
store.commit('app/setCollapse', 1);
};
store.commit('app/setCollapse', 1)
}
return {
collapse,
device,
closeSidebar,
};
}
},
});
})
</script>
<style lang="scss" scoped>

View File

@ -1,12 +1,12 @@
import { onMounted, onBeforeUnmount, reactive, toRefs, nextTick } from 'vue';
import { useRoute, useRouter } from 'vue-router';
import { useStore } from 'vuex';
import { isAffix } from './useTags';
import { onMounted, onBeforeUnmount, reactive, toRefs, nextTick } from 'vue'
import { useRoute, useRouter } from 'vue-router'
import { useStore } from 'vuex'
import { isAffix } from './useTags'
export const useContextMenu = tagList => {
const store = useStore();
const router = useRouter();
const route = useRoute();
const store = useStore()
const router = useRouter()
const route = useRoute()
const state = reactive({
visible: false,
@ -14,89 +14,89 @@ export const useContextMenu = tagList => {
left: 0,
selectedTag: {},
openMenu(tag, e) {
state.visible = true;
state.left = e.clientX;
state.top = e.clientY;
state.selectedTag = tag;
state.visible = true
state.left = e.clientX
state.top = e.clientY
state.selectedTag = tag
},
closeMenu() {
state.visible = false;
state.visible = false
},
refreshSelectedTag(tag) {
store.dispatch('tags/delCacheList', tag);
const { fullPath } = tag;
store.dispatch('tags/delCacheList', tag)
const { fullPath } = tag
nextTick(() => {
router.replace({
path: '/redirect' + fullPath,
});
});
})
})
},
closeTag(tag) {
if (isAffix(tag)) return;
if (isAffix(tag)) return
const closedTagIndex = tagList.value.findIndex(
item => item.fullPath === tag.fullPath
);
store.dispatch('tags/delTag', tag);
)
store.dispatch('tags/delTag', tag)
if (isActive(tag)) {
toLastTag(closedTagIndex - 1);
toLastTag(closedTagIndex - 1)
}
},
closeOtherTags() {
store.dispatch('tags/delOtherTags', state.selectedTag);
router.push(state.selectedTag);
store.dispatch('tags/delOtherTags', state.selectedTag)
router.push(state.selectedTag)
},
closeLeftTags() {
state.closeSomeTags('left');
state.closeSomeTags('left')
},
closeRightTags() {
state.closeSomeTags('right');
state.closeSomeTags('right')
},
closeSomeTags(direction) {
const index = tagList.value.findIndex(
item => item.fullPath === state.selectedTag.fullPath
);
)
if (
(direction === 'left' && index <= 0) ||
(direction === 'right' && index >= tagList.value.length - 1)
) {
return;
return
}
const needToClose =
direction === 'left'
? tagList.value.slice(0, index)
: tagList.value.slice(index + 1);
store.dispatch('tags/delSomeTags', needToClose);
router.push(state.selectedTag);
: tagList.value.slice(index + 1)
store.dispatch('tags/delSomeTags', needToClose)
router.push(state.selectedTag)
},
closeAllTags() {
store.dispatch('tags/delAllTags');
router.push('/');
store.dispatch('tags/delAllTags')
router.push('/')
},
});
})
const isActive = tag => {
return tag.fullPath === route.fullPath;
};
return tag.fullPath === route.fullPath
}
const toLastTag = lastTagIndex => {
const lastTag = tagList.value[lastTagIndex];
const lastTag = tagList.value[lastTagIndex]
if (lastTag) {
router.push(lastTag.fullPath);
router.push(lastTag.fullPath)
} else {
router.push('/');
router.push('/')
}
}
};
onMounted(() => {
document.addEventListener('click', state.closeMenu);
});
document.addEventListener('click', state.closeMenu)
})
onBeforeUnmount(() => {
document.removeEventListener('click', state.closeMenu);
});
document.removeEventListener('click', state.closeMenu)
})
return toRefs(state);
};
return toRefs(state)
}

View File

@ -1,41 +1,41 @@
import { ref } from 'vue';
import { ref } from 'vue'
export const useScrollbar = tagsItem => {
const scrollContainer = ref(null);
const scrollContainer = ref(null)
const handleScroll = e => {
const eventDelta = e.wheelDelta || -e.deltaY;
scrollContainer.value.wrap.scrollLeft -= eventDelta / 4;
};
const eventDelta = e.wheelDelta || -e.deltaY
scrollContainer.value.wrap.scrollLeft -= eventDelta / 4
}
const moveToTarget = currentTag => {
const containerWidth = scrollContainer.value.scrollbar.offsetWidth;
const scrollWrapper = scrollContainer.value.wrap;
const tagList = tagsItem.value;
const containerWidth = scrollContainer.value.scrollbar.offsetWidth
const scrollWrapper = scrollContainer.value.wrap
const tagList = tagsItem.value
let firstTag = null;
let lastTag = null;
let firstTag = null
let lastTag = null
if (tagList.length > 0) {
firstTag = tagList[0];
lastTag = tagList[tagList.length - 1];
firstTag = tagList[0]
lastTag = tagList[tagList.length - 1]
}
if (firstTag === currentTag) {
scrollWrapper.scrollLeft = 0;
scrollWrapper.scrollLeft = 0
} else if (lastTag === currentTag) {
scrollWrapper.scrollLeft = scrollWrapper.scrollWidth - containerWidth;
scrollWrapper.scrollLeft = scrollWrapper.scrollWidth - containerWidth
} else {
const el = currentTag.$el.nextElementSibling;
const el = currentTag.$el.nextElementSibling
scrollWrapper.scrollLeft =
el.offsetLeft + el.offsetWidth > containerWidth
? el.offsetLeft - el.offsetWidth
: 0;
: 0
}
}
};
return {
scrollContainer,
handleScroll,
moveToTarget,
};
};
}
}

View File

@ -1,94 +1,94 @@
import { useScrollbar } from './useScrollbar';
import { watch, computed, ref, nextTick, onBeforeMount } from 'vue';
import { useRouter } from 'vue-router';
import { useStore } from 'vuex';
import { useScrollbar } from './useScrollbar'
import { watch, computed, ref, nextTick, onBeforeMount } from 'vue'
import { useRouter } from 'vue-router'
import { useStore } from 'vuex'
export const isAffix = tag => {
return !!tag.meta && !!tag.meta.affix;
};
return !!tag.meta && !!tag.meta.affix
}
export const useTags = () => {
const store = useStore();
const router = useRouter();
const route = router.currentRoute;
const routes = computed(() => router.getRoutes());
const tagList = computed(() => store.state.tags.tagList);
const store = useStore()
const router = useRouter()
const route = router.currentRoute
const routes = computed(() => router.getRoutes())
const tagList = computed(() => store.state.tags.tagList)
const tagsItem = ref([]);
const tagsItem = ref([])
const setItemRef = (i, el) => {
tagsItem.value[i] = el;
};
tagsItem.value[i] = el
}
const scrollbar = useScrollbar(tagsItem);
const scrollbar = useScrollbar(tagsItem)
watch(
() => tagList.value.length,
() => {
tagsItem.value = [];
tagsItem.value = []
}
);
)
const filterAffixTags = routes => {
return routes.filter(route => isAffix(route));
};
return routes.filter(route => isAffix(route))
}
const initTags = () => {
const affixTags = filterAffixTags(routes.value);
const affixTags = filterAffixTags(routes.value)
for (const tag of affixTags) {
if (tag.name) {
store.dispatch('tags/addTagList', tag);
store.dispatch('tags/addTagList', tag)
}
}
}
};
const addTag = () => {
const tag = route.value;
const tag = route.value
if (!!tag.name && tag.matched[0].components.default.name === 'layout') {
store.dispatch('tags/addTag', tag);
store.dispatch('tags/addTag', tag)
}
}
};
const saveActivePosition = tag => {
const index = tagList.value.findIndex(
item => item.fullPath === tag.fullPath
);
)
store.dispatch('tags/saveActivePosition', Math.max(0, index));
};
store.dispatch('tags/saveActivePosition', Math.max(0, index))
}
const moveToCurrentTag = () => {
nextTick(() => {
for (const tag of tagsItem.value) {
if (!!tag && tag.to.path === route.value.path) {
scrollbar.moveToTarget(tag);
scrollbar.moveToTarget(tag)
if (tag.to.fullPath !== route.value.fullPath) {
store.dispatch('tags/updateTagList', route.value);
store.dispatch('tags/updateTagList', route.value)
}
break;
break
}
}
});
};
})
}
onBeforeMount(() => {
initTags();
addTag();
moveToCurrentTag();
});
initTags()
addTag()
moveToCurrentTag()
})
watch(route, (newRoute, oldRoute) => {
saveActivePosition(oldRoute); // 保存标签的位置
addTag();
moveToCurrentTag();
});
saveActivePosition(oldRoute) // 保存标签的位置
addTag()
moveToCurrentTag()
})
return {
tagList,
setItemRef,
isAffix,
...scrollbar,
};
};
}
}

View File

@ -46,28 +46,28 @@
</template>
<script>
import { defineComponent } from 'vue';
import { useTags } from './hooks/useTags';
import { useContextMenu } from './hooks/useContextMenu';
import { defineComponent } from 'vue'
import { useTags } from './hooks/useTags'
import { useContextMenu } from './hooks/useContextMenu'
export default defineComponent({
name: 'Tagsbar',
setup() {
const tags = useTags();
const contextMenu = useContextMenu(tags.tagList);
const tags = useTags()
const contextMenu = useContextMenu(tags.tagList)
const onScroll = e => {
tags.handleScroll(e);
contextMenu.closeMenu.value();
};
tags.handleScroll(e)
contextMenu.closeMenu.value()
}
return {
onScroll,
...tags,
...contextMenu,
};
}
},
});
})
</script>
<style lang="scss" scoped>

View File

@ -15,45 +15,45 @@
</el-breadcrumb>
</template>
<script>
import { defineComponent, computed, ref, onBeforeMount, watch } from 'vue';
import { useRouter } from 'vue-router';
import { useStore } from 'vuex';
import { defineComponent, computed, ref, onBeforeMount, watch } from 'vue'
import { useRouter } from 'vue-router'
import { useStore } from 'vuex'
export default defineComponent({
setup() {
const store = useStore();
const device = computed(() => store.state.app.device);
const router = useRouter();
const route = router.currentRoute; // 使useRoutewatch
const breadcrumbs = ref([]);
const store = useStore()
const device = computed(() => store.state.app.device)
const router = useRouter()
const route = router.currentRoute // 使useRoutewatch
const breadcrumbs = ref([])
const getBreadcrumbs = route => {
const home = [{ path: '/', meta: { title: '首页' } }];
const home = [{ path: '/', meta: { title: '首页' } }]
if (route.name === 'home') {
return home;
return home
} else {
const matched = route.matched.filter(
item => !!item.meta && !!item.meta.title
);
)
return [...home, ...matched];
return [...home, ...matched]
}
}
};
onBeforeMount(() => {
breadcrumbs.value = getBreadcrumbs(route.value);
});
breadcrumbs.value = getBreadcrumbs(route.value)
})
watch(route, newRoute => {
breadcrumbs.value = getBreadcrumbs(newRoute);
});
breadcrumbs.value = getBreadcrumbs(newRoute)
})
return {
device,
breadcrumbs,
};
}
},
});
})
</script>
<style lang="scss" scoped>

View File

@ -6,22 +6,22 @@
></i>
</template>
<script>
import { defineComponent, computed } from 'vue';
import { useStore } from 'vuex';
import { defineComponent, computed } from 'vue'
import { useStore } from 'vuex'
export default defineComponent({
setup() {
const store = useStore();
const collapse = computed(() => !!store.state.app.sidebar.collapse);
const store = useStore()
const collapse = computed(() => !!store.state.app.sidebar.collapse)
const handleToggleMenu = () => {
store.commit('app/setCollapse', +!collapse.value);
};
store.commit('app/setCollapse', +!collapse.value)
}
return {
collapse,
handleToggleMenu,
};
}
},
});
})
</script>
<style lang="scss" scoped>
.fold-btn {

View File

@ -21,26 +21,26 @@
</el-dropdown>
</template>
<script>
import { computed, defineComponent } from 'vue';
import { useStore } from 'vuex';
import { useRouter } from 'vue-router';
import { computed, defineComponent } from 'vue'
import { useStore } from 'vuex'
import { useRouter } from 'vue-router'
export default defineComponent({
setup() {
const store = useStore();
const router = useRouter();
const userinfo = computed(() => store.state.account.userinfo);
const store = useStore()
const router = useRouter()
const userinfo = computed(() => store.state.account.userinfo)
const logout = () => {
store.commit('app/clearToken');
store.commit('account/clearUserinfo');
store.dispatch('tags/delAllTags');
router.push('/login');
};
store.commit('app/clearToken')
store.commit('account/clearUserinfo')
store.dispatch('tags/delAllTags')
router.push('/login')
}
return {
userinfo,
logout,
};
}
},
});
})
</script>
<style lang="scss" scoped>

View File

@ -11,12 +11,12 @@
</div>
</template>
<script>
import { defineComponent, computed } from 'vue';
import Logo from '@/layout/components/Sidebar/Logo.vue';
import Hamburger from './Hamburger.vue';
import Breadcrumbs from './Breadcrumbs.vue';
import Userinfo from './Userinfo.vue';
import { useStore } from 'vuex';
import { defineComponent, computed } from 'vue'
import Logo from '@/layout/components/Sidebar/Logo.vue'
import Hamburger from './Hamburger.vue'
import Breadcrumbs from './Breadcrumbs.vue'
import Userinfo from './Userinfo.vue'
import { useStore } from 'vuex'
export default defineComponent({
components: {
@ -26,14 +26,14 @@ export default defineComponent({
Userinfo,
},
setup() {
const store = useStore();
const device = computed(() => store.state.app.device);
const store = useStore()
const device = computed(() => store.state.app.device)
return {
device,
};
}
},
});
})
</script>
<style lang="scss" scoped>
.header {

View File

@ -1,38 +1,38 @@
import { onBeforeMount, onBeforeUnmount /*watch*/ } from 'vue';
import { onBeforeMount, onBeforeUnmount /*watch*/ } from 'vue'
// import { useRouter } from 'vue-router';
import { useStore } from 'vuex';
import { useStore } from 'vuex'
const WIDTH = 768;
const WIDTH = 768
export const useResizeHandler = () => {
const store = useStore();
const store = useStore()
// const router = useRouter();
// const route = router.currentRoute;
const isMobile = () => {
return window.innerWidth < WIDTH;
};
return window.innerWidth < WIDTH
}
const resizeHandler = () => {
if (isMobile()) {
store.commit('app/setDevice', 'mobile');
store.commit('app/setCollapse', 1);
store.commit('app/setDevice', 'mobile')
store.commit('app/setCollapse', 1)
} else {
store.commit('app/setDevice', 'desktop');
store.commit('app/setCollapse', 0);
store.commit('app/setDevice', 'desktop')
store.commit('app/setCollapse', 0)
}
}
};
onBeforeMount(() => {
if (isMobile()) {
store.commit('app/setDevice', 'mobile');
store.commit('app/setCollapse', 1);
store.commit('app/setDevice', 'mobile')
store.commit('app/setCollapse', 1)
}
window.addEventListener('resize', resizeHandler);
});
window.addEventListener('resize', resizeHandler)
})
onBeforeUnmount(() => {
window.removeEventListener('resize', resizeHandler);
});
window.removeEventListener('resize', resizeHandler)
})
// // 监听路由的时候不能使用useRoute获取路由否则会有警告
// watch(route, () => {
@ -40,4 +40,4 @@ export const useResizeHandler = () => {
// store.commit('app/setCollapse', 1)
// }
// })
};
}

View File

@ -13,12 +13,12 @@
</div>
</template>
<script>
import { defineComponent } from 'vue';
import Sidebar from './components/Sidebar/index.vue';
import Topbar from './components/Topbar/index.vue';
import Tagsbar from './components/Tagsbar/index.vue';
import Content from './components/Content/index.vue';
import { useResizeHandler } from './hooks/useResizeHandler';
import { defineComponent } from 'vue'
import Sidebar from './components/Sidebar/index.vue'
import Topbar from './components/Topbar/index.vue'
import Tagsbar from './components/Tagsbar/index.vue'
import Content from './components/Content/index.vue'
import { useResizeHandler } from './hooks/useResizeHandler'
export default defineComponent({
name: 'layout',
@ -29,9 +29,9 @@ export default defineComponent({
Content,
},
setup() {
useResizeHandler();
useResizeHandler()
},
});
})
</script>
<style lang="scss" scoped>

View File

@ -1,35 +1,35 @@
import { createApp } from 'vue';
import App from './App.vue';
import { createApp } from 'vue'
import App from './App.vue'
const app = createApp(App);
const app = createApp(App)
// 引入element-plus
import ElementPlus from 'element-plus';
import './assets/style/element-variables.scss';
import ElementPlus from 'element-plus'
import './assets/style/element-variables.scss'
// 引入中文语言包
import 'dayjs/locale/zh-cn';
import locale from 'element-plus/lib/locale/lang/zh-cn';
import 'dayjs/locale/zh-cn'
import locale from 'element-plus/lib/locale/lang/zh-cn'
// 引入路由
import router from './router';
import router from './router'
// 引入store
import store from './store';
import store from './store'
// 权限控制
import './permission';
import './permission'
// 引入svg图标注册脚本
import 'vite-plugin-svg-icons/register';
import 'vite-plugin-svg-icons/register'
// 注册全局组件
import * as Components from './global-components';
import * as Components from './global-components'
Object.entries(Components).forEach(([key, component]) => {
app.component(key, component);
});
app.component(key, component)
})
app
.use(ElementPlus, { locale })
.use(store)
.use(router)
.mount('#app');
.mount('#app')

View File

@ -1,24 +1,24 @@
import router from '@/router';
import store from '@/store';
import { TOKEN } from '@/store/modules/app'; // TOKEN变量名
import router from '@/router'
import store from '@/store'
import { TOKEN } from '@/store/modules/app' // TOKEN变量名
const getPageTitle = title => {
const appTitle = store.state.app.title;
const appTitle = store.state.app.title
if (title) {
return `${title} - ${appTitle}`;
return `${title} - ${appTitle}`
}
return appTitle
}
return appTitle;
};
// 白名单里面是路由对象的name
const WhiteList = ['login', 'forbidden', 'server-error', 'not-found'];
const WhiteList = ['login', 'forbidden', 'server-error', 'not-found']
// vue-router4的路由守卫不再是通过next放行而是通过return返回true或false或者一个路由地址
router.beforeEach(async to => {
document.title = getPageTitle(!!to.meta && to.meta.title);
document.title = getPageTitle(!!to.meta && to.meta.title)
if (WhiteList.includes(to.name)) {
return true;
return true
}
if (!window.localStorage[TOKEN]) {
return {
@ -27,15 +27,15 @@ router.beforeEach(async to => {
redirect: to.path, // redirect是指登录之后可以跳回到redirect指定的页面
},
replace: true,
};
}
} else {
let userinfo = store.state.account.userinfo;
let userinfo = store.state.account.userinfo
if (!userinfo) {
try {
// 获取用户信息
userinfo = await store.dispatch('account/getUserinfo');
userinfo = await store.dispatch('account/getUserinfo')
} catch (err) {
return false;
return false
}
}
// 如果没有权限跳转到403页面
@ -44,7 +44,7 @@ router.beforeEach(async to => {
!!to.meta.roles &&
!to.meta.roles.includes(userinfo.role)
) {
return { path: '/403', replace: true };
return { path: '/403', replace: true }
}
}
});
})

View File

@ -1,14 +1,14 @@
// index.js
import { createRouter, createWebHashHistory } from 'vue-router';
import { createRouter, createWebHashHistory } from 'vue-router'
import redirect from './modules/redirect';
import error from './modules/error';
import login from './modules/login';
import home from './modules/home';
import test from './modules/test';
import redirect from './modules/redirect'
import error from './modules/error'
import login from './modules/login'
import home from './modules/home'
import test from './modules/test'
// 左侧菜单
export const allMenus = [...home, ...test];
export const allMenus = [...home, ...test]
const router = createRouter({
history: createWebHashHistory(),
@ -24,11 +24,11 @@ const router = createRouter({
],
scrollBehavior(to, from, savedPosition) {
if (savedPosition) {
return savedPosition;
return savedPosition
} else {
return { left: 0, top: 0 };
return { left: 0, top: 0 }
}
},
});
})
export default router;
export default router

View File

@ -1,15 +1,15 @@
import store from '@/store';
import store from '@/store'
const checkUserinfo = code => {
const userinfo = store.state.account.userinfo;
const userinfo = store.state.account.userinfo
if (userinfo) {
return `/error/${code}`;
return `/error/${code}`
}
return true
}
return true;
};
const Layout = () => import('@/layout/index.vue');
const Error = () => import('@/views/error/index.vue');
const Layout = () => import('@/layout/index.vue')
const Error = () => import('@/views/error/index.vue')
export default [
{
@ -53,7 +53,7 @@ export default [
error: '403',
},
beforeEnter() {
return checkUserinfo('403');
return checkUserinfo('403')
},
},
{
@ -64,7 +64,7 @@ export default [
error: '500',
},
beforeEnter() {
return checkUserinfo('500');
return checkUserinfo('500')
},
},
{
@ -75,7 +75,7 @@ export default [
error: '404',
},
beforeEnter() {
return checkUserinfo('404');
return checkUserinfo('404')
},
},
];
]

View File

@ -1,6 +1,6 @@
// home.js
const Layout = () => import('@/layout/index.vue');
const Home = () => import('@/views/home/index.vue');
const Layout = () => import('@/layout/index.vue')
const Home = () => import('@/views/home/index.vue')
export default [
{
@ -23,4 +23,4 @@ export default [
},
],
},
];
]

View File

@ -1,5 +1,5 @@
// login.js
const Login = () => import('@/views/login/index.vue');
const Login = () => import('@/views/login/index.vue')
export default [
{
@ -7,4 +7,4 @@ export default [
name: 'login',
component: Login,
},
];
]

View File

@ -1,5 +1,5 @@
const Layout = () => import('@/layout/index.vue');
const Redirect = () => import('@/views/redirect/index.vue');
const Layout = () => import('@/layout/index.vue')
const Redirect = () => import('@/views/redirect/index.vue')
export default [
{
@ -12,4 +12,4 @@ export default [
},
],
},
];
]

View File

@ -1,13 +1,13 @@
const Layout = () => import('@/layout/index.vue');
const List = () => import('@/views/test/index.vue');
const Add = () => import('@/views/test/Add.vue');
const Auth = () => import('@/views/test/Auth.vue');
const NoAuth = () => import('@/views/test/NoAuth.vue');
const Nest = () => import('@/views/test/Nest.vue');
const NestPage1 = () => import('@/views/test/nest/Page1.vue');
const NestPage2 = () => import('@/views/test/nest/Page2.vue');
const Iscache = () => import('@/views/test/Cache.vue');
const Nocache = () => import('@/views/test/Nocache.vue');
const Layout = () => import('@/layout/index.vue')
const List = () => import('@/views/test/index.vue')
const Add = () => import('@/views/test/Add.vue')
const Auth = () => import('@/views/test/Auth.vue')
const NoAuth = () => import('@/views/test/NoAuth.vue')
const Nest = () => import('@/views/test/Nest.vue')
const NestPage1 = () => import('@/views/test/nest/Page1.vue')
const NestPage2 = () => import('@/views/test/nest/Page2.vue')
const Iscache = () => import('@/views/test/Cache.vue')
const Nocache = () => import('@/views/test/Nocache.vue')
export default [
{
@ -109,4 +109,4 @@ export default [
},
],
},
];
]

View File

@ -1,9 +1,9 @@
//index.js
import { createStore } from 'vuex';
import app from './modules/app';
import account from './modules/account';
import menu from './modules/menu';
import tags from './modules/tags';
import { createStore } from 'vuex'
import app from './modules/app'
import account from './modules/account'
import menu from './modules/menu'
import tags from './modules/tags'
export default createStore({
modules: {
@ -12,4 +12,4 @@ export default createStore({
menu,
tags,
},
});
})

View File

@ -1,4 +1,4 @@
import { GetUserinfo } from '@/api/login';
import { GetUserinfo } from '@/api/login'
export default {
namespaced: true,
@ -8,21 +8,21 @@ export default {
mutations: {
// 保存用户信息
setUserinfo(state, data) {
state.userinfo = data;
state.userinfo = data
},
// 清除用户信息
clearUserinfo(state) {
state.userinfo = null;
state.userinfo = null
},
},
actions: {
// 获取用户信息
async getUserinfo({ commit }) {
const { code, data } = await GetUserinfo();
const { code, data } = await GetUserinfo()
if (+code === 200) {
commit('setUserinfo', data);
return Promise.resolve(data);
commit('setUserinfo', data)
return Promise.resolve(data)
}
},
},
};
}

View File

@ -1,6 +1,6 @@
import { getItem, setItem, removeItem } from '@/utils/storage'; //getItem和setItem是封装的操作localStorage的方法
export const TOKEN = 'VEA-TOKEN';
const COLLAPSE = 'VEA-COLLAPSE';
import { getItem, setItem, removeItem } from '@/utils/storage' //getItem和setItem是封装的操作localStorage的方法
export const TOKEN = 'VEA-TOKEN'
const COLLAPSE = 'VEA-COLLAPSE'
export default {
namespaced: true,
@ -14,28 +14,28 @@ export default {
},
mutations: {
setToken(state, data) {
state.authorization = data;
state.authorization = data
// 保存到localStorage
setItem(TOKEN, data);
setItem(TOKEN, data)
},
clearToken(state) {
state.authorization = '';
state.authorization = ''
removeItem(TOKEN);
removeItem(TOKEN)
},
setCollapse(state, data) {
state.sidebar.collapse = data;
state.sidebar.collapse = data
// 保存到localStorage
setItem(COLLAPSE, data);
setItem(COLLAPSE, data)
},
clearCollapse(state) {
state.sidebar.collapse = '';
state.sidebar.collapse = ''
removeItem(COLLAPSE);
removeItem(COLLAPSE)
},
setDevice(state, device) {
state.device = device;
state.device = device
},
},
actions: {},
};
}

View File

@ -1,23 +1,23 @@
import { allMenus } from '@/router';
import { allMenus } from '@/router'
// import { GetMenus } from '@/api/menu';
const hasPermission = (role, route) => {
if (!!route.meta && !!route.meta.roles && !route.meta.roles.includes(role)) {
return false;
return false
}
return true
}
return true;
};
const generateUrl = (path, parentPath) => {
return path.startsWith('/')
? path
: path
? `${parentPath}/${path}`
: parentPath;
};
: parentPath
}
const getFilterMenus = (arr, role, parentPath = '') => {
const menus = [];
const menus = []
arr.forEach(item => {
if (hasPermission(role, item) && !item.hidden) {
@ -25,20 +25,20 @@ const getFilterMenus = (arr, role, parentPath = '') => {
url: generateUrl(item.path, parentPath),
title: item.meta.title,
icon: item.icon,
};
}
if (item.children) {
if (item.children.length === 1) {
menu.url = generateUrl(item.children[0].path, menu.url);
menu.url = generateUrl(item.children[0].path, menu.url)
} else {
menu.children = getFilterMenus(item.children, role, menu.url);
menu.children = getFilterMenus(item.children, role, menu.url)
}
}
menus.push(menu);
menus.push(menu)
}
});
})
return menus;
};
return menus
}
export default {
namespaced: true,
@ -47,14 +47,14 @@ export default {
},
mutations: {
SET_MENUS(state, data) {
state.menus = data;
state.menus = data
},
},
actions: {
async generateMenus({ commit }, role) {
// 方式一:根据角色生成菜单
const menus = getFilterMenus(allMenus, role);
commit('SET_MENUS', menus);
const menus = getFilterMenus(allMenus, role)
commit('SET_MENUS', menus)
// // 方式二:从后台获取菜单
// const { code, data } = await GetMenus();
@ -63,4 +63,4 @@ export default {
// }
},
},
};
}

View File

@ -1,16 +1,16 @@
import { getItem, setItem, removeItem } from '@/utils/storage'; //getItem和setItem是封装的操作localStorage的方法
import { getItem, setItem, removeItem } from '@/utils/storage' //getItem和setItem是封装的操作localStorage的方法
const TAGLIST = 'VEA-TAGLIST';
const TAGLIST = 'VEA-TAGLIST'
const state = {
tagList: getItem(TAGLIST) || [],
cacheList: [],
activePosition: 0,
};
}
const mutations = {
ADD_TAG_LIST: (state, { path, fullPath, name, meta }) => {
if (state.tagList.some(v => v.path === path)) return false;
if (state.tagList.some(v => v.path === path)) return false
state.tagList.splice(
state.activePosition + 1,
@ -23,136 +23,136 @@ const mutations = {
fullPath: fullPath || path,
}
)
);
)
// 保存到localStorage
setItem(TAGLIST, state.tagList);
setItem(TAGLIST, state.tagList)
},
ADD_CACHE_LIST: (state, tag) => {
if (state.cacheList.includes(tag.name)) return;
if (state.cacheList.includes(tag.name)) return
if (!tag.meta.noCache) {
state.cacheList.push(tag.name);
state.cacheList.push(tag.name)
}
},
DEL_TAG_LIST: (state, tag) => {
state.tagList = state.tagList.filter(v => v.path !== tag.path);
state.tagList = state.tagList.filter(v => v.path !== tag.path)
// 保存到localStorage
setItem(TAGLIST, state.tagList);
setItem(TAGLIST, state.tagList)
},
DEL_CACHE_LIST: (state, tag) => {
state.cacheList = state.cacheList.filter(v => v !== tag.name);
state.cacheList = state.cacheList.filter(v => v !== tag.name)
},
DEL_OTHER_TAG_LIST: (state, tag) => {
state.tagList = state.tagList.filter(
v => !!v.meta.affix || v.path === tag.path
);
)
// 保存到localStorage
setItem(TAGLIST, state.tagList);
setItem(TAGLIST, state.tagList)
},
DEL_OTHER_CACHE_LIST: (state, tag) => {
state.cacheList = state.cacheList.filter(v => v === tag.name);
state.cacheList = state.cacheList.filter(v => v === tag.name)
},
DEL_SOME_TAG_LIST: (state, tags) => {
state.tagList = state.tagList.filter(
v => !!v.meta.affix || tags.every(tag => tag.path !== v.path)
);
)
// 保存到localStorage
setItem(TAGLIST, state.tagList);
setItem(TAGLIST, state.tagList)
},
DEL_SOME_CACHE_LIST: (state, tags) => {
state.cacheList = state.cacheList.filter(v =>
tags.every(tag => tag.name !== v)
);
)
},
DEL_ALL_TAG_LIST: state => {
state.tagList = state.tagList.filter(v => !!v.meta.affix);
state.tagList = state.tagList.filter(v => !!v.meta.affix)
// 保存到localStorage
removeItem(TAGLIST);
removeItem(TAGLIST)
},
DEL_ALL_CACHE_LIST: state => {
state.cacheList = [];
state.cacheList = []
},
UPDATE_TAG_LIST: (state, tag) => {
const index = state.tagList.findIndex(v => v.path === tag.path);
const index = state.tagList.findIndex(v => v.path === tag.path)
if (index > -1) {
state.tagList[index] = Object.assign({}, state.tagList[index], tag);
state.tagList[index] = Object.assign({}, state.tagList[index], tag)
// 保存到localStorage
setItem(TAGLIST, state.tagList);
setItem(TAGLIST, state.tagList)
}
},
SAVE_ACTIVE_POSITION: (state, index) => {
state.activePosition = index;
state.activePosition = index
},
};
}
const actions = {
saveActivePosition({ commit }, index) {
commit('SAVE_ACTIVE_POSITION', index);
commit('SAVE_ACTIVE_POSITION', index)
},
addTag({ dispatch }, tag) {
dispatch('addTagList', tag);
dispatch('addCacheList', tag);
dispatch('addTagList', tag)
dispatch('addCacheList', tag)
},
addTagList({ commit }, tag) {
commit('ADD_TAG_LIST', tag);
commit('ADD_TAG_LIST', tag)
},
addCacheList({ commit }, tag) {
commit('ADD_CACHE_LIST', tag);
commit('ADD_CACHE_LIST', tag)
},
delTag({ dispatch }, tag) {
dispatch('delTagList', tag);
dispatch('delCacheList', tag);
dispatch('delTagList', tag)
dispatch('delCacheList', tag)
},
delTagList({ commit }, tag) {
commit('DEL_TAG_LIST', tag);
commit('DEL_TAG_LIST', tag)
},
delCacheList({ commit }, tag) {
commit('DEL_CACHE_LIST', tag);
commit('DEL_CACHE_LIST', tag)
},
delOtherTags({ dispatch }, tag) {
dispatch('delOtherTagList', tag);
dispatch('delOtherCacheList', tag);
dispatch('delOtherTagList', tag)
dispatch('delOtherCacheList', tag)
},
delOtherTagList({ commit }, tag) {
commit('DEL_OTHER_TAG_LIST', tag);
commit('DEL_OTHER_TAG_LIST', tag)
},
delOtherCacheList({ commit }, tag) {
commit('DEL_OTHER_CACHE_LIST', tag);
commit('DEL_OTHER_CACHE_LIST', tag)
},
delSomeTags({ commit }, tags) {
commit('DEL_SOME_TAG_LIST', tags);
commit('DEL_SOME_CACHE_LIST', tags);
commit('DEL_SOME_TAG_LIST', tags)
commit('DEL_SOME_CACHE_LIST', tags)
},
delAllTags({ dispatch }) {
dispatch('delAllTagList');
dispatch('delAllCacheList');
dispatch('delAllTagList')
dispatch('delAllCacheList')
},
delAllTagList({ commit }) {
commit('DEL_ALL_TAG_LIST');
commit('DEL_ALL_TAG_LIST')
},
delAllCacheList({ commit }) {
commit('DEL_ALL_CACHE_LIST');
commit('DEL_ALL_CACHE_LIST')
},
updateTagList({ commit }, tag) {
commit('UPDATE_TAG_LIST', tag);
commit('UPDATE_TAG_LIST', tag)
},
};
}
export default {
namespaced: true,
state,
mutations,
actions,
};
}

View File

@ -1,34 +1,34 @@
import axios from 'axios';
import { ElMessage } from 'element-plus';
import store from '@/store';
import router from '@/router';
import axios from 'axios'
import { ElMessage } from 'element-plus'
import store from '@/store'
import router from '@/router'
const service = axios.create({
baseURL: '/',
timeout: 10000,
withCredentials: true,
});
})
// 拦截请求
service.interceptors.request.use(
config => {
const { authorization } = store.state.app;
const { authorization } = store.state.app
if (authorization) {
config.headers.Authorization = `Bearer ${authorization.token}`;
config.headers.Authorization = `Bearer ${authorization.token}`
}
return config;
return config
},
error => {
// console.log(error);
return Promise.reject(error);
return Promise.reject(error)
}
);
)
// 拦截响应
service.interceptors.response.use(
// 响应成功进入第1个函数该函数的参数是响应对象
response => {
return response.data;
return response.data
},
// 响应失败进入第2个函数该函数的参数是错误对象
async error => {
@ -36,12 +36,12 @@ service.interceptors.response.use(
// 响应拦截器中的 error 就是那个响应的错误对象
if (error.response && error.response.status === 401) {
// 校验是否有 refresh_token
const { authorization } = store.state.app;
const { authorization } = store.state.app
if (!authorization || !authorization.refresh_token) {
router.push('/login');
router.push('/login')
// 代码不要往后执行了
return Promise.reject(error);
return Promise.reject(error)
}
// 如果有refresh_token则请求获取新的 token
try {
@ -52,32 +52,32 @@ service.interceptors.response.use(
headers: {
Authorization: `Bearer ${authorization.refresh_token}`,
},
});
})
// 如果获取成功,则把新的 token 更新到容器中
// console.log('刷新 token 成功', res)
store.commit('app/setToken', {
token: res.data.data.token, // 最新获取的可用 token
refresh_token: authorization.refresh_token, // 还是原来的 refresh_token
});
})
// 把之前失败的用户请求继续发出去
// config 是一个对象,其中包含本次失败请求相关的那些配置信息,例如 url、method 都有
// return 把 request 的请求结果继续返回给发请求的具体位置
return service(error.config);
return service(error.config)
} catch (err) {
// 如果获取失败,直接跳转 登录页
// console.log('请求刷新 token 失败', err)
router.push('/login');
router.push('/login')
// 清除token
store.commit('app/clearToken');
return Promise.reject(error);
store.commit('app/clearToken')
return Promise.reject(error)
}
}
// console.dir(error) // 可在此进行错误上报
ElMessage.error(error.message);
ElMessage.error(error.message)
return Promise.reject(error);
return Promise.reject(error)
}
);
)
export default service;
export default service

View File

@ -1,20 +1,20 @@
export const getItem = name => {
const data = window.localStorage.getItem(name);
const data = window.localStorage.getItem(name)
try {
return JSON.parse(data);
return JSON.parse(data)
} catch (err) {
return data;
return data
}
}
};
export const setItem = (name, value) => {
if (typeof value === 'object') {
value = JSON.stringify(value);
value = JSON.stringify(value)
}
window.localStorage.setItem(name, value);
};
window.localStorage.setItem(name, value)
}
export const removeItem = name => {
window.localStorage.removeItem(name);
};
window.localStorage.removeItem(name)
}

View File

@ -21,11 +21,11 @@
</template>
<script>
import { defineComponent } from 'vue';
import { defineComponent } from 'vue'
export default defineComponent({
props: ['error'],
});
})
</script>
<style lang="scss" scoped>

View File

@ -3,12 +3,12 @@
</template>
<script>
import { defineComponent } from 'vue';
import { defineComponent } from 'vue'
export default defineComponent({
name: 'home',
setup() {},
});
})
</script>
<style lang="scss" scoped>

View File

@ -43,17 +43,17 @@ import {
toRefs,
ref,
computed,
} from 'vue';
import { Login } from '@/api/login';
import { useStore } from 'vuex';
import { useRouter, useRoute } from 'vue-router';
} from 'vue'
import { Login } from '@/api/login'
import { useStore } from 'vuex'
import { useRouter, useRoute } from 'vue-router'
export default defineComponent({
name: 'login',
setup() {
const { ctx } = getCurrentInstance(); // ctxvue2this
const store = useStore();
const router = useRouter();
const route = useRoute();
const { ctx } = getCurrentInstance() // ctxvue2this
const store = useStore()
const router = useRouter()
const route = useRoute()
const state = reactive({
model: {
userName: 'admin',
@ -78,34 +78,34 @@ export default defineComponent({
loginForm: ref(null),
submit: () => {
if (state.loading) {
return;
return
}
state.loginForm.validate(async valid => {
if (valid) {
state.loading = true;
const { code, data, message } = await Login(state.model);
state.loading = true
const { code, data, message } = await Login(state.model)
if (+code === 200) {
ctx.$message.success({
message: '登录成功',
duration: 1000,
});
const targetPath = route.query.redirect;
router.push(targetPath ? targetPath : '/');
store.commit('app/setToken', data);
})
const targetPath = route.query.redirect
router.push(targetPath ? targetPath : '/')
store.commit('app/setToken', data)
} else {
ctx.$message.error(message);
ctx.$message.error(message)
}
state.loading = false;
state.loading = false
}
});
})
},
});
})
return {
...toRefs(state),
};
}
},
});
})
</script>
<style lang="scss" scoped>

View File

@ -1,11 +1,11 @@
<script>
import { h } from 'vue';
import { h } from 'vue'
export default {
created() {
this.$router.replace(this.$route.fullPath.replace(/^\/redirect/, ''));
this.$router.replace(this.$route.fullPath.replace(/^\/redirect/, ''))
},
render() {
return h('div');
return h('div')
},
};
}
</script>

View File

@ -6,15 +6,15 @@
</dl>
</template>
<script>
import { defineComponent, onActivated } from 'vue';
import { defineComponent, onActivated } from 'vue'
export default defineComponent({
name: 'test-cache', // namename
setup() {
console.log('cache');
console.log('cache')
onActivated(() => {
console.log('onActivated');
});
console.log('onActivated')
})
},
});
})
</script>

View File

@ -6,12 +6,12 @@
</dl>
</template>
<script>
import { defineComponent } from 'vue';
import { defineComponent } from 'vue'
export default defineComponent({
name: 'test-no-cache', // namenamename
setup() {
console.log('nocache');
console.log('nocache')
},
});
})
</script>

View File

@ -32,7 +32,7 @@
</template>
<script>
import { defineComponent, reactive, ref, toRefs } from 'vue';
import { defineComponent, reactive, ref, toRefs } from 'vue'
export default defineComponent({
name: 'testList',
@ -210,15 +210,15 @@ export default defineComponent({
},
selectedItems: [],
batchDelete() {
console.log(state.selectedItems);
console.log(state.selectedItems)
},
//
handleSelectionChange(arr) {
state.selectedItems = arr;
state.selectedItems = arr
},
//
async getList(params) {
console.log(params);
console.log(params)
// params
const { data } = await new Promise(rs => {
setTimeout(() => {
@ -239,23 +239,23 @@ export default defineComponent({
],
total: 100,
},
});
}, 3000);
});
})
}, 3000)
})
// datatotal
return {
data: data.list,
total: +data.total,
};
}
},
});
const table = ref(null);
})
const table = ref(null)
const refresh = () => {
table.value.refresh();
};
table.value.refresh()
}
return { ...toRefs(state), refresh, table };
return { ...toRefs(state), refresh, table }
},
});
})
</script>