update
This commit is contained in:
parent
77e94d2f3d
commit
c5265e7fc2
@ -1,4 +1,4 @@
|
|||||||
import request from '@/utils/request';
|
import request from '@/utils/request'
|
||||||
|
|
||||||
// 登录接口
|
// 登录接口
|
||||||
export const Login = data => {
|
export const Login = data => {
|
||||||
@ -6,13 +6,13 @@ export const Login = data => {
|
|||||||
url: '/api/login',
|
url: '/api/login',
|
||||||
method: 'post',
|
method: 'post',
|
||||||
data,
|
data,
|
||||||
});
|
})
|
||||||
};
|
}
|
||||||
|
|
||||||
// 获取登录用户信息
|
// 获取登录用户信息
|
||||||
export const GetUserinfo = () => {
|
export const GetUserinfo = () => {
|
||||||
return request({
|
return request({
|
||||||
url: '/api/userinfo',
|
url: '/api/userinfo',
|
||||||
method: 'get',
|
method: 'get',
|
||||||
});
|
})
|
||||||
};
|
}
|
||||||
|
|||||||
@ -1,9 +1,9 @@
|
|||||||
import request from '@/utils/request';
|
import request from '@/utils/request'
|
||||||
|
|
||||||
// 获取菜单
|
// 获取菜单
|
||||||
export const GetMenus = () => {
|
export const GetMenus = () => {
|
||||||
return request({
|
return request({
|
||||||
url: '/api/menus',
|
url: '/api/menus',
|
||||||
method: 'get',
|
method: 'get',
|
||||||
});
|
})
|
||||||
};
|
}
|
||||||
|
|||||||
@ -212,7 +212,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<script>
|
<script>
|
||||||
import { defineComponent, reactive, toRefs, onBeforeMount } from 'vue';
|
import { defineComponent, reactive, toRefs, onBeforeMount } from 'vue'
|
||||||
const formatDate = (date, format) => {
|
const formatDate = (date, format) => {
|
||||||
var obj = {
|
var obj = {
|
||||||
'M+': date.getMonth() + 1,
|
'M+': date.getMonth() + 1,
|
||||||
@ -222,12 +222,12 @@ const formatDate = (date, format) => {
|
|||||||
's+': date.getSeconds(),
|
's+': date.getSeconds(),
|
||||||
'q+': Math.floor((date.getMonth() + 3) / 3),
|
'q+': Math.floor((date.getMonth() + 3) / 3),
|
||||||
'S+': date.getMilliseconds(),
|
'S+': date.getMilliseconds(),
|
||||||
};
|
}
|
||||||
if (/(y+)/i.test(format)) {
|
if (/(y+)/i.test(format)) {
|
||||||
format = format.replace(
|
format = format.replace(
|
||||||
RegExp.$1,
|
RegExp.$1,
|
||||||
(date.getFullYear() + '').substr(4 - RegExp.$1.length)
|
(date.getFullYear() + '').substr(4 - RegExp.$1.length)
|
||||||
);
|
)
|
||||||
}
|
}
|
||||||
for (var k in obj) {
|
for (var k in obj) {
|
||||||
if (new RegExp('(' + k + ')').test(format)) {
|
if (new RegExp('(' + k + ')').test(format)) {
|
||||||
@ -236,25 +236,25 @@ const formatDate = (date, format) => {
|
|||||||
RegExp.$1.length == 1
|
RegExp.$1.length == 1
|
||||||
? obj[k]
|
? obj[k]
|
||||||
: ('00' + obj[k]).substr(('' + obj[k]).length)
|
: ('00' + obj[k]).substr(('' + obj[k]).length)
|
||||||
);
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return format;
|
return format
|
||||||
};
|
}
|
||||||
const getSearchModel = search => {
|
const getSearchModel = search => {
|
||||||
const searchModel = {};
|
const searchModel = {}
|
||||||
if (search && search.fields) {
|
if (search && search.fields) {
|
||||||
search.fields.forEach(item => {
|
search.fields.forEach(item => {
|
||||||
switch (item.type) {
|
switch (item.type) {
|
||||||
case 'checkbox':
|
case 'checkbox':
|
||||||
case 'checkbox-button':
|
case 'checkbox-button':
|
||||||
searchModel[item.name] = [];
|
searchModel[item.name] = []
|
||||||
break;
|
break
|
||||||
default:
|
default:
|
||||||
break;
|
break
|
||||||
}
|
}
|
||||||
if (item.defaultValue !== undefined) {
|
if (item.defaultValue !== undefined) {
|
||||||
searchModel[item.name] = item.defaultValue;
|
searchModel[item.name] = item.defaultValue
|
||||||
// 日期范围和时间范围真实变量默认值
|
// 日期范围和时间范围真实变量默认值
|
||||||
if (
|
if (
|
||||||
(item.type === 'daterange' || item.type === 'datetimerange') &&
|
(item.type === 'daterange' || item.type === 'datetimerange') &&
|
||||||
@ -262,14 +262,14 @@ const getSearchModel = search => {
|
|||||||
Array.isArray(item.defaultValue)
|
Array.isArray(item.defaultValue)
|
||||||
) {
|
) {
|
||||||
item.defaultValue.forEach((val, index) => {
|
item.defaultValue.forEach((val, index) => {
|
||||||
searchModel[item.trueNames[index]] = val;
|
searchModel[item.trueNames[index]] = val
|
||||||
});
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
})
|
||||||
|
}
|
||||||
|
return searchModel
|
||||||
}
|
}
|
||||||
return searchModel;
|
|
||||||
};
|
|
||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
props: {
|
props: {
|
||||||
// 请求数据的方法
|
// 请求数据的方法
|
||||||
@ -316,43 +316,43 @@ export default defineComponent({
|
|||||||
// 1、如果搜索配置有transform处理函数,执行transform
|
// 1、如果搜索配置有transform处理函数,执行transform
|
||||||
// 2、删除日期范围默认的name字段
|
// 2、删除日期范围默认的name字段
|
||||||
const optimizeFields = search => {
|
const optimizeFields = search => {
|
||||||
const searchModel = JSON.parse(JSON.stringify(state.searchModel));
|
const searchModel = JSON.parse(JSON.stringify(state.searchModel))
|
||||||
if (search && search.fields) {
|
if (search && search.fields) {
|
||||||
search.fields.forEach(item => {
|
search.fields.forEach(item => {
|
||||||
if (!searchModel.hasOwnProperty(item.name)) {
|
if (!searchModel.hasOwnProperty(item.name)) {
|
||||||
return;
|
return
|
||||||
}
|
}
|
||||||
if (item.transform) {
|
if (item.transform) {
|
||||||
searchModel[item.name] = item.transform(searchModel[item.name]);
|
searchModel[item.name] = item.transform(searchModel[item.name])
|
||||||
}
|
}
|
||||||
if (
|
if (
|
||||||
(item.type === 'daterange' || item.type === 'datetimerange') &&
|
(item.type === 'daterange' || item.type === 'datetimerange') &&
|
||||||
!!item.trueNames
|
!!item.trueNames
|
||||||
) {
|
) {
|
||||||
delete searchModel[item.name];
|
delete searchModel[item.name]
|
||||||
}
|
}
|
||||||
});
|
})
|
||||||
|
}
|
||||||
|
return searchModel
|
||||||
}
|
}
|
||||||
return searchModel;
|
|
||||||
};
|
|
||||||
|
|
||||||
// 请求列表数据
|
// 请求列表数据
|
||||||
const getTableData = async () => {
|
const getTableData = async () => {
|
||||||
state.loading = true;
|
state.loading = true
|
||||||
const searchModel = optimizeFields(props.search);
|
const searchModel = optimizeFields(props.search)
|
||||||
const { data, total } = await props.request({
|
const { data, total } = await props.request({
|
||||||
pageNum: state.pageNum,
|
pageNum: state.pageNum,
|
||||||
pageSize: state.pageSize,
|
pageSize: state.pageSize,
|
||||||
...searchModel,
|
...searchModel,
|
||||||
});
|
})
|
||||||
state.loading = false;
|
state.loading = false
|
||||||
state.tableData = data;
|
state.tableData = data
|
||||||
state.total = total;
|
state.total = total
|
||||||
};
|
}
|
||||||
|
|
||||||
onBeforeMount(() => {
|
onBeforeMount(() => {
|
||||||
getTableData();
|
getTableData()
|
||||||
});
|
})
|
||||||
|
|
||||||
const state = reactive({
|
const state = reactive({
|
||||||
searchModel: getSearchModel(props.search),
|
searchModel: getSearchModel(props.search),
|
||||||
@ -366,80 +366,80 @@ export default defineComponent({
|
|||||||
},
|
},
|
||||||
// 搜索
|
// 搜索
|
||||||
handleSearch() {
|
handleSearch() {
|
||||||
state.pageNum = 1;
|
state.pageNum = 1
|
||||||
getTableData();
|
getTableData()
|
||||||
},
|
},
|
||||||
// 重置函数
|
// 重置函数
|
||||||
handleReset() {
|
handleReset() {
|
||||||
if (JSON.stringify(state.searchModel) === '{}') {
|
if (JSON.stringify(state.searchModel) === '{}') {
|
||||||
return;
|
return
|
||||||
}
|
}
|
||||||
state.pageNum = 1;
|
state.pageNum = 1
|
||||||
state.searchModel = getSearchModel(props.search);
|
state.searchModel = getSearchModel(props.search)
|
||||||
getTableData();
|
getTableData()
|
||||||
},
|
},
|
||||||
// 刷新
|
// 刷新
|
||||||
refresh() {
|
refresh() {
|
||||||
getTableData();
|
getTableData()
|
||||||
},
|
},
|
||||||
|
|
||||||
// 当前页变化
|
// 当前页变化
|
||||||
handleCurrentChange() {
|
handleCurrentChange() {
|
||||||
getTableData();
|
getTableData()
|
||||||
},
|
},
|
||||||
// 改变每页size数量
|
// 改变每页size数量
|
||||||
handleSizeChange() {
|
handleSizeChange() {
|
||||||
state.pageNum = 1;
|
state.pageNum = 1
|
||||||
getTableData();
|
getTableData()
|
||||||
},
|
},
|
||||||
// 全选
|
// 全选
|
||||||
handleSelectionChange(arr) {
|
handleSelectionChange(arr) {
|
||||||
emit('selectionChange', arr);
|
emit('selectionChange', arr)
|
||||||
},
|
},
|
||||||
// 过滤方法
|
// 过滤方法
|
||||||
filterHandler(value, row, column) {
|
filterHandler(value, row, column) {
|
||||||
const property = column['property'];
|
const property = column['property']
|
||||||
return row[property] === value;
|
return row[property] === value
|
||||||
},
|
},
|
||||||
// 日期范围
|
// 日期范围
|
||||||
handleDateChange(date, item, format) {
|
handleDateChange(date, item, format) {
|
||||||
state.searchModel[item.name] = date ? formatDate(date, format) : '';
|
state.searchModel[item.name] = date ? formatDate(date, format) : ''
|
||||||
},
|
},
|
||||||
handleRangeChange(date, item, format) {
|
handleRangeChange(date, item, format) {
|
||||||
const arr = !!date && date.map(d => formatDate(d, format));
|
const arr = !!date && date.map(d => formatDate(d, format))
|
||||||
state.searchModel[item.name] = arr ? arr : [];
|
state.searchModel[item.name] = arr ? arr : []
|
||||||
|
|
||||||
if (!item.trueNames) {
|
if (!item.trueNames) {
|
||||||
return;
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if (arr) {
|
if (arr) {
|
||||||
arr.forEach((val, index) => {
|
arr.forEach((val, index) => {
|
||||||
state.searchModel[item.trueNames[index]] = val;
|
state.searchModel[item.trueNames[index]] = val
|
||||||
});
|
})
|
||||||
} else {
|
} else {
|
||||||
item.trueNames.forEach(key => {
|
item.trueNames.forEach(key => {
|
||||||
delete state.searchModel[key];
|
delete state.searchModel[key]
|
||||||
});
|
})
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
});
|
})
|
||||||
|
|
||||||
if (typeof props.pagination === 'object') {
|
if (typeof props.pagination === 'object') {
|
||||||
const { layout, pageSizes, style } = props.pagination;
|
const { layout, pageSizes, style } = props.pagination
|
||||||
state.paginationConfig = {
|
state.paginationConfig = {
|
||||||
show: true,
|
show: true,
|
||||||
layout: layout || 'total, sizes, prev, pager, next, jumper',
|
layout: layout || 'total, sizes, prev, pager, next, jumper',
|
||||||
pageSizes: pageSizes || [10, 20, 30, 40, 50, 100],
|
pageSizes: pageSizes || [10, 20, 30, 40, 50, 100],
|
||||||
style: style || {},
|
style: style || {},
|
||||||
};
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
...toRefs(state),
|
...toRefs(state),
|
||||||
};
|
}
|
||||||
},
|
},
|
||||||
});
|
})
|
||||||
</script>
|
</script>
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
.page-box {
|
.page-box {
|
||||||
|
|||||||
@ -5,7 +5,7 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import { defineComponent, computed } from 'vue';
|
import { defineComponent, computed } from 'vue'
|
||||||
|
|
||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
name: 'SvgIcon',
|
name: 'SvgIcon',
|
||||||
@ -20,10 +20,10 @@ export default defineComponent({
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
setup(props) {
|
setup(props) {
|
||||||
const symbolId = computed(() => `#${props.prefix}-${props.name}`);
|
const symbolId = computed(() => `#${props.prefix}-${props.name}`)
|
||||||
return { symbolId };
|
return { symbolId }
|
||||||
},
|
},
|
||||||
});
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
|
|||||||
@ -1,2 +1,2 @@
|
|||||||
export { default as SvgIcon } from '@/components/SvgIcon/index.vue';
|
export { default as SvgIcon } from '@/components/SvgIcon/index.vue'
|
||||||
export { default as ProTable } from '@/components/ProTable/index.vue';
|
export { default as ProTable } from '@/components/ProTable/index.vue'
|
||||||
|
|||||||
@ -6,21 +6,21 @@
|
|||||||
</router-view>
|
</router-view>
|
||||||
</template>
|
</template>
|
||||||
<script>
|
<script>
|
||||||
import { computed, defineComponent } from 'vue';
|
import { computed, defineComponent } from 'vue'
|
||||||
import { useRoute } from 'vue-router';
|
import { useRoute } from 'vue-router'
|
||||||
import { useStore } from 'vuex';
|
import { useStore } from 'vuex'
|
||||||
|
|
||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
setup() {
|
setup() {
|
||||||
const store = useStore();
|
const store = useStore()
|
||||||
const route = useRoute();
|
const route = useRoute()
|
||||||
const cacheList = computed(() => store.state.tags.cacheList);
|
const cacheList = computed(() => store.state.tags.cacheList)
|
||||||
const key = computed(() => route.fullPath);
|
const key = computed(() => route.fullPath)
|
||||||
|
|
||||||
return {
|
return {
|
||||||
cacheList,
|
cacheList,
|
||||||
key,
|
key,
|
||||||
};
|
}
|
||||||
},
|
},
|
||||||
});
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@ -5,18 +5,18 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import { computed, defineComponent } from 'vue';
|
import { computed, defineComponent } from 'vue'
|
||||||
|
|
||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
props: ['title', 'icon'],
|
props: ['title', 'icon'],
|
||||||
setup({ icon }) {
|
setup({ icon }) {
|
||||||
const isElementIcon = computed(() => icon && icon.startsWith('el-icon'));
|
const isElementIcon = computed(() => icon && icon.startsWith('el-icon'))
|
||||||
|
|
||||||
return {
|
return {
|
||||||
isElementIcon,
|
isElementIcon,
|
||||||
};
|
}
|
||||||
},
|
},
|
||||||
});
|
})
|
||||||
</script>
|
</script>
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
.icon {
|
.icon {
|
||||||
|
|||||||
@ -5,18 +5,18 @@
|
|||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<script>
|
<script>
|
||||||
import { defineComponent } from 'vue';
|
import { defineComponent } from 'vue'
|
||||||
import { useRouter } from 'vue-router';
|
import { useRouter } from 'vue-router'
|
||||||
|
|
||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
setup() {
|
setup() {
|
||||||
const router = useRouter();
|
const router = useRouter()
|
||||||
const goHome = () => {
|
const goHome = () => {
|
||||||
router.push('/');
|
router.push('/')
|
||||||
};
|
}
|
||||||
return { goHome };
|
return { goHome }
|
||||||
},
|
},
|
||||||
});
|
})
|
||||||
</script>
|
</script>
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
.brand {
|
.brand {
|
||||||
|
|||||||
@ -15,11 +15,11 @@
|
|||||||
</el-scrollbar>
|
</el-scrollbar>
|
||||||
</template>
|
</template>
|
||||||
<script>
|
<script>
|
||||||
import { computed, defineComponent } from 'vue';
|
import { computed, defineComponent } from 'vue'
|
||||||
import Submenu from './Submenu.vue';
|
import Submenu from './Submenu.vue'
|
||||||
import { useStore } from 'vuex';
|
import { useStore } from 'vuex'
|
||||||
import { useRoute } from 'vue-router';
|
import { useRoute } from 'vue-router'
|
||||||
import config from './config/menu.module.scss';
|
import config from './config/menu.module.scss'
|
||||||
|
|
||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
components: {
|
components: {
|
||||||
@ -32,20 +32,20 @@ export default defineComponent({
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
setup() {
|
setup() {
|
||||||
const route = useRoute();
|
const route = useRoute()
|
||||||
const store = useStore();
|
const store = useStore()
|
||||||
store.dispatch(
|
store.dispatch(
|
||||||
'menu/generateMenus',
|
'menu/generateMenus',
|
||||||
store.state.account.userinfo && store.state.account.userinfo.role
|
store.state.account.userinfo && store.state.account.userinfo.role
|
||||||
);
|
)
|
||||||
|
|
||||||
return {
|
return {
|
||||||
menus: computed(() => store.state.menu.menus),
|
menus: computed(() => store.state.menu.menus),
|
||||||
activePath: computed(() => route.path),
|
activePath: computed(() => route.path),
|
||||||
variables: computed(() => config),
|
variables: computed(() => config),
|
||||||
};
|
}
|
||||||
},
|
},
|
||||||
});
|
})
|
||||||
</script>
|
</script>
|
||||||
<style lang="scss">
|
<style lang="scss">
|
||||||
// menu hover
|
// menu hover
|
||||||
|
|||||||
@ -15,8 +15,8 @@
|
|||||||
</el-submenu>
|
</el-submenu>
|
||||||
</template>
|
</template>
|
||||||
<script>
|
<script>
|
||||||
import { defineComponent } from 'vue';
|
import { defineComponent } from 'vue'
|
||||||
import Item from './Item.vue';
|
import Item from './Item.vue'
|
||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
name: 'Submenu',
|
name: 'Submenu',
|
||||||
components: {
|
components: {
|
||||||
@ -32,5 +32,5 @@ export default defineComponent({
|
|||||||
default: false,
|
default: false,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
});
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@ -10,10 +10,10 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import { defineComponent, computed } from 'vue';
|
import { defineComponent, computed } from 'vue'
|
||||||
import Logo from './Logo.vue';
|
import Logo from './Logo.vue'
|
||||||
import Menus from './Menus.vue';
|
import Menus from './Menus.vue'
|
||||||
import { useStore } from 'vuex';
|
import { useStore } from 'vuex'
|
||||||
|
|
||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
components: {
|
components: {
|
||||||
@ -21,21 +21,21 @@ export default defineComponent({
|
|||||||
Menus,
|
Menus,
|
||||||
},
|
},
|
||||||
setup() {
|
setup() {
|
||||||
const store = useStore();
|
const store = useStore()
|
||||||
const collapse = computed(() => !!store.state.app.sidebar.collapse);
|
const collapse = computed(() => !!store.state.app.sidebar.collapse)
|
||||||
const device = computed(() => store.state.app.device);
|
const device = computed(() => store.state.app.device)
|
||||||
|
|
||||||
const closeSidebar = () => {
|
const closeSidebar = () => {
|
||||||
store.commit('app/setCollapse', 1);
|
store.commit('app/setCollapse', 1)
|
||||||
};
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
collapse,
|
collapse,
|
||||||
device,
|
device,
|
||||||
closeSidebar,
|
closeSidebar,
|
||||||
};
|
}
|
||||||
},
|
},
|
||||||
});
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
|
|||||||
@ -1,12 +1,12 @@
|
|||||||
import { onMounted, onBeforeUnmount, reactive, toRefs, nextTick } from 'vue';
|
import { onMounted, onBeforeUnmount, reactive, toRefs, nextTick } from 'vue'
|
||||||
import { useRoute, useRouter } from 'vue-router';
|
import { useRoute, useRouter } from 'vue-router'
|
||||||
import { useStore } from 'vuex';
|
import { useStore } from 'vuex'
|
||||||
import { isAffix } from './useTags';
|
import { isAffix } from './useTags'
|
||||||
|
|
||||||
export const useContextMenu = tagList => {
|
export const useContextMenu = tagList => {
|
||||||
const store = useStore();
|
const store = useStore()
|
||||||
const router = useRouter();
|
const router = useRouter()
|
||||||
const route = useRoute();
|
const route = useRoute()
|
||||||
|
|
||||||
const state = reactive({
|
const state = reactive({
|
||||||
visible: false,
|
visible: false,
|
||||||
@ -14,89 +14,89 @@ export const useContextMenu = tagList => {
|
|||||||
left: 0,
|
left: 0,
|
||||||
selectedTag: {},
|
selectedTag: {},
|
||||||
openMenu(tag, e) {
|
openMenu(tag, e) {
|
||||||
state.visible = true;
|
state.visible = true
|
||||||
state.left = e.clientX;
|
state.left = e.clientX
|
||||||
state.top = e.clientY;
|
state.top = e.clientY
|
||||||
state.selectedTag = tag;
|
state.selectedTag = tag
|
||||||
},
|
},
|
||||||
closeMenu() {
|
closeMenu() {
|
||||||
state.visible = false;
|
state.visible = false
|
||||||
},
|
},
|
||||||
refreshSelectedTag(tag) {
|
refreshSelectedTag(tag) {
|
||||||
store.dispatch('tags/delCacheList', tag);
|
store.dispatch('tags/delCacheList', tag)
|
||||||
const { fullPath } = tag;
|
const { fullPath } = tag
|
||||||
nextTick(() => {
|
nextTick(() => {
|
||||||
router.replace({
|
router.replace({
|
||||||
path: '/redirect' + fullPath,
|
path: '/redirect' + fullPath,
|
||||||
});
|
})
|
||||||
});
|
})
|
||||||
},
|
},
|
||||||
closeTag(tag) {
|
closeTag(tag) {
|
||||||
if (isAffix(tag)) return;
|
if (isAffix(tag)) return
|
||||||
|
|
||||||
const closedTagIndex = tagList.value.findIndex(
|
const closedTagIndex = tagList.value.findIndex(
|
||||||
item => item.fullPath === tag.fullPath
|
item => item.fullPath === tag.fullPath
|
||||||
);
|
)
|
||||||
store.dispatch('tags/delTag', tag);
|
store.dispatch('tags/delTag', tag)
|
||||||
if (isActive(tag)) {
|
if (isActive(tag)) {
|
||||||
toLastTag(closedTagIndex - 1);
|
toLastTag(closedTagIndex - 1)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
closeOtherTags() {
|
closeOtherTags() {
|
||||||
store.dispatch('tags/delOtherTags', state.selectedTag);
|
store.dispatch('tags/delOtherTags', state.selectedTag)
|
||||||
router.push(state.selectedTag);
|
router.push(state.selectedTag)
|
||||||
},
|
},
|
||||||
closeLeftTags() {
|
closeLeftTags() {
|
||||||
state.closeSomeTags('left');
|
state.closeSomeTags('left')
|
||||||
},
|
},
|
||||||
closeRightTags() {
|
closeRightTags() {
|
||||||
state.closeSomeTags('right');
|
state.closeSomeTags('right')
|
||||||
},
|
},
|
||||||
closeSomeTags(direction) {
|
closeSomeTags(direction) {
|
||||||
const index = tagList.value.findIndex(
|
const index = tagList.value.findIndex(
|
||||||
item => item.fullPath === state.selectedTag.fullPath
|
item => item.fullPath === state.selectedTag.fullPath
|
||||||
);
|
)
|
||||||
|
|
||||||
if (
|
if (
|
||||||
(direction === 'left' && index <= 0) ||
|
(direction === 'left' && index <= 0) ||
|
||||||
(direction === 'right' && index >= tagList.value.length - 1)
|
(direction === 'right' && index >= tagList.value.length - 1)
|
||||||
) {
|
) {
|
||||||
return;
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
const needToClose =
|
const needToClose =
|
||||||
direction === 'left'
|
direction === 'left'
|
||||||
? tagList.value.slice(0, index)
|
? tagList.value.slice(0, index)
|
||||||
: tagList.value.slice(index + 1);
|
: tagList.value.slice(index + 1)
|
||||||
store.dispatch('tags/delSomeTags', needToClose);
|
store.dispatch('tags/delSomeTags', needToClose)
|
||||||
router.push(state.selectedTag);
|
router.push(state.selectedTag)
|
||||||
},
|
},
|
||||||
closeAllTags() {
|
closeAllTags() {
|
||||||
store.dispatch('tags/delAllTags');
|
store.dispatch('tags/delAllTags')
|
||||||
router.push('/');
|
router.push('/')
|
||||||
},
|
},
|
||||||
});
|
})
|
||||||
|
|
||||||
const isActive = tag => {
|
const isActive = tag => {
|
||||||
return tag.fullPath === route.fullPath;
|
return tag.fullPath === route.fullPath
|
||||||
};
|
}
|
||||||
|
|
||||||
const toLastTag = lastTagIndex => {
|
const toLastTag = lastTagIndex => {
|
||||||
const lastTag = tagList.value[lastTagIndex];
|
const lastTag = tagList.value[lastTagIndex]
|
||||||
if (lastTag) {
|
if (lastTag) {
|
||||||
router.push(lastTag.fullPath);
|
router.push(lastTag.fullPath)
|
||||||
} else {
|
} else {
|
||||||
router.push('/');
|
router.push('/')
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
document.addEventListener('click', state.closeMenu);
|
document.addEventListener('click', state.closeMenu)
|
||||||
});
|
})
|
||||||
|
|
||||||
onBeforeUnmount(() => {
|
onBeforeUnmount(() => {
|
||||||
document.removeEventListener('click', state.closeMenu);
|
document.removeEventListener('click', state.closeMenu)
|
||||||
});
|
})
|
||||||
|
|
||||||
return toRefs(state);
|
return toRefs(state)
|
||||||
};
|
}
|
||||||
|
|||||||
@ -1,41 +1,41 @@
|
|||||||
import { ref } from 'vue';
|
import { ref } from 'vue'
|
||||||
|
|
||||||
export const useScrollbar = tagsItem => {
|
export const useScrollbar = tagsItem => {
|
||||||
const scrollContainer = ref(null);
|
const scrollContainer = ref(null)
|
||||||
|
|
||||||
const handleScroll = e => {
|
const handleScroll = e => {
|
||||||
const eventDelta = e.wheelDelta || -e.deltaY;
|
const eventDelta = e.wheelDelta || -e.deltaY
|
||||||
scrollContainer.value.wrap.scrollLeft -= eventDelta / 4;
|
scrollContainer.value.wrap.scrollLeft -= eventDelta / 4
|
||||||
};
|
}
|
||||||
|
|
||||||
const moveToTarget = currentTag => {
|
const moveToTarget = currentTag => {
|
||||||
const containerWidth = scrollContainer.value.scrollbar.offsetWidth;
|
const containerWidth = scrollContainer.value.scrollbar.offsetWidth
|
||||||
const scrollWrapper = scrollContainer.value.wrap;
|
const scrollWrapper = scrollContainer.value.wrap
|
||||||
const tagList = tagsItem.value;
|
const tagList = tagsItem.value
|
||||||
|
|
||||||
let firstTag = null;
|
let firstTag = null
|
||||||
let lastTag = null;
|
let lastTag = null
|
||||||
|
|
||||||
if (tagList.length > 0) {
|
if (tagList.length > 0) {
|
||||||
firstTag = tagList[0];
|
firstTag = tagList[0]
|
||||||
lastTag = tagList[tagList.length - 1];
|
lastTag = tagList[tagList.length - 1]
|
||||||
}
|
}
|
||||||
if (firstTag === currentTag) {
|
if (firstTag === currentTag) {
|
||||||
scrollWrapper.scrollLeft = 0;
|
scrollWrapper.scrollLeft = 0
|
||||||
} else if (lastTag === currentTag) {
|
} else if (lastTag === currentTag) {
|
||||||
scrollWrapper.scrollLeft = scrollWrapper.scrollWidth - containerWidth;
|
scrollWrapper.scrollLeft = scrollWrapper.scrollWidth - containerWidth
|
||||||
} else {
|
} else {
|
||||||
const el = currentTag.$el.nextElementSibling;
|
const el = currentTag.$el.nextElementSibling
|
||||||
scrollWrapper.scrollLeft =
|
scrollWrapper.scrollLeft =
|
||||||
el.offsetLeft + el.offsetWidth > containerWidth
|
el.offsetLeft + el.offsetWidth > containerWidth
|
||||||
? el.offsetLeft - el.offsetWidth
|
? el.offsetLeft - el.offsetWidth
|
||||||
: 0;
|
: 0
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
scrollContainer,
|
scrollContainer,
|
||||||
handleScroll,
|
handleScroll,
|
||||||
moveToTarget,
|
moveToTarget,
|
||||||
};
|
}
|
||||||
};
|
}
|
||||||
|
|||||||
@ -1,94 +1,94 @@
|
|||||||
import { useScrollbar } from './useScrollbar';
|
import { useScrollbar } from './useScrollbar'
|
||||||
import { watch, computed, ref, nextTick, onBeforeMount } from 'vue';
|
import { watch, computed, ref, nextTick, onBeforeMount } from 'vue'
|
||||||
import { useRouter } from 'vue-router';
|
import { useRouter } from 'vue-router'
|
||||||
import { useStore } from 'vuex';
|
import { useStore } from 'vuex'
|
||||||
|
|
||||||
export const isAffix = tag => {
|
export const isAffix = tag => {
|
||||||
return !!tag.meta && !!tag.meta.affix;
|
return !!tag.meta && !!tag.meta.affix
|
||||||
};
|
}
|
||||||
|
|
||||||
export const useTags = () => {
|
export const useTags = () => {
|
||||||
const store = useStore();
|
const store = useStore()
|
||||||
const router = useRouter();
|
const router = useRouter()
|
||||||
const route = router.currentRoute;
|
const route = router.currentRoute
|
||||||
const routes = computed(() => router.getRoutes());
|
const routes = computed(() => router.getRoutes())
|
||||||
const tagList = computed(() => store.state.tags.tagList);
|
const tagList = computed(() => store.state.tags.tagList)
|
||||||
|
|
||||||
const tagsItem = ref([]);
|
const tagsItem = ref([])
|
||||||
|
|
||||||
const setItemRef = (i, el) => {
|
const setItemRef = (i, el) => {
|
||||||
tagsItem.value[i] = el;
|
tagsItem.value[i] = el
|
||||||
};
|
}
|
||||||
|
|
||||||
const scrollbar = useScrollbar(tagsItem);
|
const scrollbar = useScrollbar(tagsItem)
|
||||||
|
|
||||||
watch(
|
watch(
|
||||||
() => tagList.value.length,
|
() => tagList.value.length,
|
||||||
() => {
|
() => {
|
||||||
tagsItem.value = [];
|
tagsItem.value = []
|
||||||
}
|
}
|
||||||
);
|
)
|
||||||
|
|
||||||
const filterAffixTags = routes => {
|
const filterAffixTags = routes => {
|
||||||
return routes.filter(route => isAffix(route));
|
return routes.filter(route => isAffix(route))
|
||||||
};
|
}
|
||||||
|
|
||||||
const initTags = () => {
|
const initTags = () => {
|
||||||
const affixTags = filterAffixTags(routes.value);
|
const affixTags = filterAffixTags(routes.value)
|
||||||
|
|
||||||
for (const tag of affixTags) {
|
for (const tag of affixTags) {
|
||||||
if (tag.name) {
|
if (tag.name) {
|
||||||
store.dispatch('tags/addTagList', tag);
|
store.dispatch('tags/addTagList', tag)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
|
||||||
|
|
||||||
const addTag = () => {
|
const addTag = () => {
|
||||||
const tag = route.value;
|
const tag = route.value
|
||||||
if (!!tag.name && tag.matched[0].components.default.name === 'layout') {
|
if (!!tag.name && tag.matched[0].components.default.name === 'layout') {
|
||||||
store.dispatch('tags/addTag', tag);
|
store.dispatch('tags/addTag', tag)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
|
||||||
|
|
||||||
const saveActivePosition = tag => {
|
const saveActivePosition = tag => {
|
||||||
const index = tagList.value.findIndex(
|
const index = tagList.value.findIndex(
|
||||||
item => item.fullPath === tag.fullPath
|
item => item.fullPath === tag.fullPath
|
||||||
);
|
)
|
||||||
|
|
||||||
store.dispatch('tags/saveActivePosition', Math.max(0, index));
|
store.dispatch('tags/saveActivePosition', Math.max(0, index))
|
||||||
};
|
}
|
||||||
|
|
||||||
const moveToCurrentTag = () => {
|
const moveToCurrentTag = () => {
|
||||||
nextTick(() => {
|
nextTick(() => {
|
||||||
for (const tag of tagsItem.value) {
|
for (const tag of tagsItem.value) {
|
||||||
if (!!tag && tag.to.path === route.value.path) {
|
if (!!tag && tag.to.path === route.value.path) {
|
||||||
scrollbar.moveToTarget(tag);
|
scrollbar.moveToTarget(tag)
|
||||||
|
|
||||||
if (tag.to.fullPath !== route.value.fullPath) {
|
if (tag.to.fullPath !== route.value.fullPath) {
|
||||||
store.dispatch('tags/updateTagList', route.value);
|
store.dispatch('tags/updateTagList', route.value)
|
||||||
}
|
}
|
||||||
break;
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
})
|
||||||
};
|
}
|
||||||
|
|
||||||
onBeforeMount(() => {
|
onBeforeMount(() => {
|
||||||
initTags();
|
initTags()
|
||||||
addTag();
|
addTag()
|
||||||
moveToCurrentTag();
|
moveToCurrentTag()
|
||||||
});
|
})
|
||||||
|
|
||||||
watch(route, (newRoute, oldRoute) => {
|
watch(route, (newRoute, oldRoute) => {
|
||||||
saveActivePosition(oldRoute); // 保存标签的位置
|
saveActivePosition(oldRoute) // 保存标签的位置
|
||||||
addTag();
|
addTag()
|
||||||
moveToCurrentTag();
|
moveToCurrentTag()
|
||||||
});
|
})
|
||||||
|
|
||||||
return {
|
return {
|
||||||
tagList,
|
tagList,
|
||||||
setItemRef,
|
setItemRef,
|
||||||
isAffix,
|
isAffix,
|
||||||
...scrollbar,
|
...scrollbar,
|
||||||
};
|
}
|
||||||
};
|
}
|
||||||
|
|||||||
@ -46,28 +46,28 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import { defineComponent } from 'vue';
|
import { defineComponent } from 'vue'
|
||||||
import { useTags } from './hooks/useTags';
|
import { useTags } from './hooks/useTags'
|
||||||
import { useContextMenu } from './hooks/useContextMenu';
|
import { useContextMenu } from './hooks/useContextMenu'
|
||||||
|
|
||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
name: 'Tagsbar',
|
name: 'Tagsbar',
|
||||||
setup() {
|
setup() {
|
||||||
const tags = useTags();
|
const tags = useTags()
|
||||||
const contextMenu = useContextMenu(tags.tagList);
|
const contextMenu = useContextMenu(tags.tagList)
|
||||||
|
|
||||||
const onScroll = e => {
|
const onScroll = e => {
|
||||||
tags.handleScroll(e);
|
tags.handleScroll(e)
|
||||||
contextMenu.closeMenu.value();
|
contextMenu.closeMenu.value()
|
||||||
};
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
onScroll,
|
onScroll,
|
||||||
...tags,
|
...tags,
|
||||||
...contextMenu,
|
...contextMenu,
|
||||||
};
|
}
|
||||||
},
|
},
|
||||||
});
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
|
|||||||
@ -15,45 +15,45 @@
|
|||||||
</el-breadcrumb>
|
</el-breadcrumb>
|
||||||
</template>
|
</template>
|
||||||
<script>
|
<script>
|
||||||
import { defineComponent, computed, ref, onBeforeMount, watch } from 'vue';
|
import { defineComponent, computed, ref, onBeforeMount, watch } from 'vue'
|
||||||
import { useRouter } from 'vue-router';
|
import { useRouter } from 'vue-router'
|
||||||
import { useStore } from 'vuex';
|
import { useStore } from 'vuex'
|
||||||
|
|
||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
setup() {
|
setup() {
|
||||||
const store = useStore();
|
const store = useStore()
|
||||||
const device = computed(() => store.state.app.device);
|
const device = computed(() => store.state.app.device)
|
||||||
const router = useRouter();
|
const router = useRouter()
|
||||||
const route = router.currentRoute; // 这里不使用useRoute获取当前路由,否则下面watch监听路由的时候会有警告
|
const route = router.currentRoute // 这里不使用useRoute获取当前路由,否则下面watch监听路由的时候会有警告
|
||||||
const breadcrumbs = ref([]);
|
const breadcrumbs = ref([])
|
||||||
|
|
||||||
const getBreadcrumbs = route => {
|
const getBreadcrumbs = route => {
|
||||||
const home = [{ path: '/', meta: { title: '首页' } }];
|
const home = [{ path: '/', meta: { title: '首页' } }]
|
||||||
if (route.name === 'home') {
|
if (route.name === 'home') {
|
||||||
return home;
|
return home
|
||||||
} else {
|
} else {
|
||||||
const matched = route.matched.filter(
|
const matched = route.matched.filter(
|
||||||
item => !!item.meta && !!item.meta.title
|
item => !!item.meta && !!item.meta.title
|
||||||
);
|
)
|
||||||
|
|
||||||
return [...home, ...matched];
|
return [...home, ...matched]
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
|
||||||
|
|
||||||
onBeforeMount(() => {
|
onBeforeMount(() => {
|
||||||
breadcrumbs.value = getBreadcrumbs(route.value);
|
breadcrumbs.value = getBreadcrumbs(route.value)
|
||||||
});
|
})
|
||||||
|
|
||||||
watch(route, newRoute => {
|
watch(route, newRoute => {
|
||||||
breadcrumbs.value = getBreadcrumbs(newRoute);
|
breadcrumbs.value = getBreadcrumbs(newRoute)
|
||||||
});
|
})
|
||||||
|
|
||||||
return {
|
return {
|
||||||
device,
|
device,
|
||||||
breadcrumbs,
|
breadcrumbs,
|
||||||
};
|
}
|
||||||
},
|
},
|
||||||
});
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
|
|||||||
@ -6,22 +6,22 @@
|
|||||||
></i>
|
></i>
|
||||||
</template>
|
</template>
|
||||||
<script>
|
<script>
|
||||||
import { defineComponent, computed } from 'vue';
|
import { defineComponent, computed } from 'vue'
|
||||||
import { useStore } from 'vuex';
|
import { useStore } from 'vuex'
|
||||||
|
|
||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
setup() {
|
setup() {
|
||||||
const store = useStore();
|
const store = useStore()
|
||||||
const collapse = computed(() => !!store.state.app.sidebar.collapse);
|
const collapse = computed(() => !!store.state.app.sidebar.collapse)
|
||||||
const handleToggleMenu = () => {
|
const handleToggleMenu = () => {
|
||||||
store.commit('app/setCollapse', +!collapse.value);
|
store.commit('app/setCollapse', +!collapse.value)
|
||||||
};
|
}
|
||||||
return {
|
return {
|
||||||
collapse,
|
collapse,
|
||||||
handleToggleMenu,
|
handleToggleMenu,
|
||||||
};
|
}
|
||||||
},
|
},
|
||||||
});
|
})
|
||||||
</script>
|
</script>
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
.fold-btn {
|
.fold-btn {
|
||||||
|
|||||||
@ -21,26 +21,26 @@
|
|||||||
</el-dropdown>
|
</el-dropdown>
|
||||||
</template>
|
</template>
|
||||||
<script>
|
<script>
|
||||||
import { computed, defineComponent } from 'vue';
|
import { computed, defineComponent } from 'vue'
|
||||||
import { useStore } from 'vuex';
|
import { useStore } from 'vuex'
|
||||||
import { useRouter } from 'vue-router';
|
import { useRouter } from 'vue-router'
|
||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
setup() {
|
setup() {
|
||||||
const store = useStore();
|
const store = useStore()
|
||||||
const router = useRouter();
|
const router = useRouter()
|
||||||
const userinfo = computed(() => store.state.account.userinfo);
|
const userinfo = computed(() => store.state.account.userinfo)
|
||||||
const logout = () => {
|
const logout = () => {
|
||||||
store.commit('app/clearToken');
|
store.commit('app/clearToken')
|
||||||
store.commit('account/clearUserinfo');
|
store.commit('account/clearUserinfo')
|
||||||
store.dispatch('tags/delAllTags');
|
store.dispatch('tags/delAllTags')
|
||||||
router.push('/login');
|
router.push('/login')
|
||||||
};
|
}
|
||||||
return {
|
return {
|
||||||
userinfo,
|
userinfo,
|
||||||
logout,
|
logout,
|
||||||
};
|
}
|
||||||
},
|
},
|
||||||
});
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
|
|||||||
@ -11,12 +11,12 @@
|
|||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<script>
|
<script>
|
||||||
import { defineComponent, computed } from 'vue';
|
import { defineComponent, computed } from 'vue'
|
||||||
import Logo from '@/layout/components/Sidebar/Logo.vue';
|
import Logo from '@/layout/components/Sidebar/Logo.vue'
|
||||||
import Hamburger from './Hamburger.vue';
|
import Hamburger from './Hamburger.vue'
|
||||||
import Breadcrumbs from './Breadcrumbs.vue';
|
import Breadcrumbs from './Breadcrumbs.vue'
|
||||||
import Userinfo from './Userinfo.vue';
|
import Userinfo from './Userinfo.vue'
|
||||||
import { useStore } from 'vuex';
|
import { useStore } from 'vuex'
|
||||||
|
|
||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
components: {
|
components: {
|
||||||
@ -26,14 +26,14 @@ export default defineComponent({
|
|||||||
Userinfo,
|
Userinfo,
|
||||||
},
|
},
|
||||||
setup() {
|
setup() {
|
||||||
const store = useStore();
|
const store = useStore()
|
||||||
const device = computed(() => store.state.app.device);
|
const device = computed(() => store.state.app.device)
|
||||||
|
|
||||||
return {
|
return {
|
||||||
device,
|
device,
|
||||||
};
|
}
|
||||||
},
|
},
|
||||||
});
|
})
|
||||||
</script>
|
</script>
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
.header {
|
.header {
|
||||||
|
|||||||
@ -1,38 +1,38 @@
|
|||||||
import { onBeforeMount, onBeforeUnmount /*watch*/ } from 'vue';
|
import { onBeforeMount, onBeforeUnmount /*watch*/ } from 'vue'
|
||||||
// import { useRouter } from 'vue-router';
|
// import { useRouter } from 'vue-router';
|
||||||
import { useStore } from 'vuex';
|
import { useStore } from 'vuex'
|
||||||
|
|
||||||
const WIDTH = 768;
|
const WIDTH = 768
|
||||||
export const useResizeHandler = () => {
|
export const useResizeHandler = () => {
|
||||||
const store = useStore();
|
const store = useStore()
|
||||||
// const router = useRouter();
|
// const router = useRouter();
|
||||||
// const route = router.currentRoute;
|
// const route = router.currentRoute;
|
||||||
|
|
||||||
const isMobile = () => {
|
const isMobile = () => {
|
||||||
return window.innerWidth < WIDTH;
|
return window.innerWidth < WIDTH
|
||||||
};
|
}
|
||||||
|
|
||||||
const resizeHandler = () => {
|
const resizeHandler = () => {
|
||||||
if (isMobile()) {
|
if (isMobile()) {
|
||||||
store.commit('app/setDevice', 'mobile');
|
store.commit('app/setDevice', 'mobile')
|
||||||
store.commit('app/setCollapse', 1);
|
store.commit('app/setCollapse', 1)
|
||||||
} else {
|
} else {
|
||||||
store.commit('app/setDevice', 'desktop');
|
store.commit('app/setDevice', 'desktop')
|
||||||
store.commit('app/setCollapse', 0);
|
store.commit('app/setCollapse', 0)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
|
||||||
|
|
||||||
onBeforeMount(() => {
|
onBeforeMount(() => {
|
||||||
if (isMobile()) {
|
if (isMobile()) {
|
||||||
store.commit('app/setDevice', 'mobile');
|
store.commit('app/setDevice', 'mobile')
|
||||||
store.commit('app/setCollapse', 1);
|
store.commit('app/setCollapse', 1)
|
||||||
}
|
}
|
||||||
window.addEventListener('resize', resizeHandler);
|
window.addEventListener('resize', resizeHandler)
|
||||||
});
|
})
|
||||||
|
|
||||||
onBeforeUnmount(() => {
|
onBeforeUnmount(() => {
|
||||||
window.removeEventListener('resize', resizeHandler);
|
window.removeEventListener('resize', resizeHandler)
|
||||||
});
|
})
|
||||||
|
|
||||||
// // 监听路由的时候不能使用useRoute获取路由,否则会有警告
|
// // 监听路由的时候不能使用useRoute获取路由,否则会有警告
|
||||||
// watch(route, () => {
|
// watch(route, () => {
|
||||||
@ -40,4 +40,4 @@ export const useResizeHandler = () => {
|
|||||||
// store.commit('app/setCollapse', 1)
|
// store.commit('app/setCollapse', 1)
|
||||||
// }
|
// }
|
||||||
// })
|
// })
|
||||||
};
|
}
|
||||||
|
|||||||
@ -13,12 +13,12 @@
|
|||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<script>
|
<script>
|
||||||
import { defineComponent } from 'vue';
|
import { defineComponent } from 'vue'
|
||||||
import Sidebar from './components/Sidebar/index.vue';
|
import Sidebar from './components/Sidebar/index.vue'
|
||||||
import Topbar from './components/Topbar/index.vue';
|
import Topbar from './components/Topbar/index.vue'
|
||||||
import Tagsbar from './components/Tagsbar/index.vue';
|
import Tagsbar from './components/Tagsbar/index.vue'
|
||||||
import Content from './components/Content/index.vue';
|
import Content from './components/Content/index.vue'
|
||||||
import { useResizeHandler } from './hooks/useResizeHandler';
|
import { useResizeHandler } from './hooks/useResizeHandler'
|
||||||
|
|
||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
name: 'layout',
|
name: 'layout',
|
||||||
@ -29,9 +29,9 @@ export default defineComponent({
|
|||||||
Content,
|
Content,
|
||||||
},
|
},
|
||||||
setup() {
|
setup() {
|
||||||
useResizeHandler();
|
useResizeHandler()
|
||||||
},
|
},
|
||||||
});
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
|
|||||||
30
src/main.js
30
src/main.js
@ -1,35 +1,35 @@
|
|||||||
import { createApp } from 'vue';
|
import { createApp } from 'vue'
|
||||||
import App from './App.vue';
|
import App from './App.vue'
|
||||||
|
|
||||||
const app = createApp(App);
|
const app = createApp(App)
|
||||||
|
|
||||||
// 引入element-plus
|
// 引入element-plus
|
||||||
import ElementPlus from 'element-plus';
|
import ElementPlus from 'element-plus'
|
||||||
import './assets/style/element-variables.scss';
|
import './assets/style/element-variables.scss'
|
||||||
// 引入中文语言包
|
// 引入中文语言包
|
||||||
import 'dayjs/locale/zh-cn';
|
import 'dayjs/locale/zh-cn'
|
||||||
import locale from 'element-plus/lib/locale/lang/zh-cn';
|
import locale from 'element-plus/lib/locale/lang/zh-cn'
|
||||||
|
|
||||||
// 引入路由
|
// 引入路由
|
||||||
import router from './router';
|
import router from './router'
|
||||||
|
|
||||||
// 引入store
|
// 引入store
|
||||||
import store from './store';
|
import store from './store'
|
||||||
|
|
||||||
// 权限控制
|
// 权限控制
|
||||||
import './permission';
|
import './permission'
|
||||||
|
|
||||||
// 引入svg图标注册脚本
|
// 引入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]) => {
|
Object.entries(Components).forEach(([key, component]) => {
|
||||||
app.component(key, component);
|
app.component(key, component)
|
||||||
});
|
})
|
||||||
|
|
||||||
app
|
app
|
||||||
.use(ElementPlus, { locale })
|
.use(ElementPlus, { locale })
|
||||||
.use(store)
|
.use(store)
|
||||||
.use(router)
|
.use(router)
|
||||||
.mount('#app');
|
.mount('#app')
|
||||||
|
|||||||
@ -1,24 +1,24 @@
|
|||||||
import router from '@/router';
|
import router from '@/router'
|
||||||
import store from '@/store';
|
import store from '@/store'
|
||||||
import { TOKEN } from '@/store/modules/app'; // TOKEN变量名
|
import { TOKEN } from '@/store/modules/app' // TOKEN变量名
|
||||||
|
|
||||||
const getPageTitle = title => {
|
const getPageTitle = title => {
|
||||||
const appTitle = store.state.app.title;
|
const appTitle = store.state.app.title
|
||||||
if (title) {
|
if (title) {
|
||||||
return `${title} - ${appTitle}`;
|
return `${title} - ${appTitle}`
|
||||||
|
}
|
||||||
|
return appTitle
|
||||||
}
|
}
|
||||||
return appTitle;
|
|
||||||
};
|
|
||||||
|
|
||||||
// 白名单,里面是路由对象的name
|
// 白名单,里面是路由对象的name
|
||||||
const WhiteList = ['login', 'forbidden', 'server-error', 'not-found'];
|
const WhiteList = ['login', 'forbidden', 'server-error', 'not-found']
|
||||||
|
|
||||||
// vue-router4的路由守卫不再是通过next放行,而是通过return返回true或false或者一个路由地址
|
// vue-router4的路由守卫不再是通过next放行,而是通过return返回true或false或者一个路由地址
|
||||||
router.beforeEach(async to => {
|
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)) {
|
if (WhiteList.includes(to.name)) {
|
||||||
return true;
|
return true
|
||||||
}
|
}
|
||||||
if (!window.localStorage[TOKEN]) {
|
if (!window.localStorage[TOKEN]) {
|
||||||
return {
|
return {
|
||||||
@ -27,15 +27,15 @@ router.beforeEach(async to => {
|
|||||||
redirect: to.path, // redirect是指登录之后可以跳回到redirect指定的页面
|
redirect: to.path, // redirect是指登录之后可以跳回到redirect指定的页面
|
||||||
},
|
},
|
||||||
replace: true,
|
replace: true,
|
||||||
};
|
}
|
||||||
} else {
|
} else {
|
||||||
let userinfo = store.state.account.userinfo;
|
let userinfo = store.state.account.userinfo
|
||||||
if (!userinfo) {
|
if (!userinfo) {
|
||||||
try {
|
try {
|
||||||
// 获取用户信息
|
// 获取用户信息
|
||||||
userinfo = await store.dispatch('account/getUserinfo');
|
userinfo = await store.dispatch('account/getUserinfo')
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
return false;
|
return false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// 如果没有权限,跳转到403页面
|
// 如果没有权限,跳转到403页面
|
||||||
@ -44,7 +44,7 @@ router.beforeEach(async to => {
|
|||||||
!!to.meta.roles &&
|
!!to.meta.roles &&
|
||||||
!to.meta.roles.includes(userinfo.role)
|
!to.meta.roles.includes(userinfo.role)
|
||||||
) {
|
) {
|
||||||
return { path: '/403', replace: true };
|
return { path: '/403', replace: true }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
})
|
||||||
|
|||||||
@ -1,14 +1,14 @@
|
|||||||
// index.js
|
// index.js
|
||||||
import { createRouter, createWebHashHistory } from 'vue-router';
|
import { createRouter, createWebHashHistory } from 'vue-router'
|
||||||
|
|
||||||
import redirect from './modules/redirect';
|
import redirect from './modules/redirect'
|
||||||
import error from './modules/error';
|
import error from './modules/error'
|
||||||
import login from './modules/login';
|
import login from './modules/login'
|
||||||
import home from './modules/home';
|
import home from './modules/home'
|
||||||
import test from './modules/test';
|
import test from './modules/test'
|
||||||
|
|
||||||
// 左侧菜单
|
// 左侧菜单
|
||||||
export const allMenus = [...home, ...test];
|
export const allMenus = [...home, ...test]
|
||||||
|
|
||||||
const router = createRouter({
|
const router = createRouter({
|
||||||
history: createWebHashHistory(),
|
history: createWebHashHistory(),
|
||||||
@ -24,11 +24,11 @@ const router = createRouter({
|
|||||||
],
|
],
|
||||||
scrollBehavior(to, from, savedPosition) {
|
scrollBehavior(to, from, savedPosition) {
|
||||||
if (savedPosition) {
|
if (savedPosition) {
|
||||||
return savedPosition;
|
return savedPosition
|
||||||
} else {
|
} else {
|
||||||
return { left: 0, top: 0 };
|
return { left: 0, top: 0 }
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
});
|
})
|
||||||
|
|
||||||
export default router;
|
export default router
|
||||||
|
|||||||
@ -1,15 +1,15 @@
|
|||||||
import store from '@/store';
|
import store from '@/store'
|
||||||
|
|
||||||
const checkUserinfo = code => {
|
const checkUserinfo = code => {
|
||||||
const userinfo = store.state.account.userinfo;
|
const userinfo = store.state.account.userinfo
|
||||||
if (userinfo) {
|
if (userinfo) {
|
||||||
return `/error/${code}`;
|
return `/error/${code}`
|
||||||
|
}
|
||||||
|
return true
|
||||||
}
|
}
|
||||||
return true;
|
|
||||||
};
|
|
||||||
|
|
||||||
const Layout = () => import('@/layout/index.vue');
|
const Layout = () => import('@/layout/index.vue')
|
||||||
const Error = () => import('@/views/error/index.vue');
|
const Error = () => import('@/views/error/index.vue')
|
||||||
|
|
||||||
export default [
|
export default [
|
||||||
{
|
{
|
||||||
@ -53,7 +53,7 @@ export default [
|
|||||||
error: '403',
|
error: '403',
|
||||||
},
|
},
|
||||||
beforeEnter() {
|
beforeEnter() {
|
||||||
return checkUserinfo('403');
|
return checkUserinfo('403')
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -64,7 +64,7 @@ export default [
|
|||||||
error: '500',
|
error: '500',
|
||||||
},
|
},
|
||||||
beforeEnter() {
|
beforeEnter() {
|
||||||
return checkUserinfo('500');
|
return checkUserinfo('500')
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -75,7 +75,7 @@ export default [
|
|||||||
error: '404',
|
error: '404',
|
||||||
},
|
},
|
||||||
beforeEnter() {
|
beforeEnter() {
|
||||||
return checkUserinfo('404');
|
return checkUserinfo('404')
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
];
|
]
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
// home.js
|
// home.js
|
||||||
const Layout = () => import('@/layout/index.vue');
|
const Layout = () => import('@/layout/index.vue')
|
||||||
const Home = () => import('@/views/home/index.vue');
|
const Home = () => import('@/views/home/index.vue')
|
||||||
|
|
||||||
export default [
|
export default [
|
||||||
{
|
{
|
||||||
@ -23,4 +23,4 @@ export default [
|
|||||||
},
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
];
|
]
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
// login.js
|
// login.js
|
||||||
const Login = () => import('@/views/login/index.vue');
|
const Login = () => import('@/views/login/index.vue')
|
||||||
|
|
||||||
export default [
|
export default [
|
||||||
{
|
{
|
||||||
@ -7,4 +7,4 @@ export default [
|
|||||||
name: 'login',
|
name: 'login',
|
||||||
component: Login,
|
component: Login,
|
||||||
},
|
},
|
||||||
];
|
]
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
const Layout = () => import('@/layout/index.vue');
|
const Layout = () => import('@/layout/index.vue')
|
||||||
const Redirect = () => import('@/views/redirect/index.vue');
|
const Redirect = () => import('@/views/redirect/index.vue')
|
||||||
|
|
||||||
export default [
|
export default [
|
||||||
{
|
{
|
||||||
@ -12,4 +12,4 @@ export default [
|
|||||||
},
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
];
|
]
|
||||||
|
|||||||
@ -1,13 +1,13 @@
|
|||||||
const Layout = () => import('@/layout/index.vue');
|
const Layout = () => import('@/layout/index.vue')
|
||||||
const List = () => import('@/views/test/index.vue');
|
const List = () => import('@/views/test/index.vue')
|
||||||
const Add = () => import('@/views/test/Add.vue');
|
const Add = () => import('@/views/test/Add.vue')
|
||||||
const Auth = () => import('@/views/test/Auth.vue');
|
const Auth = () => import('@/views/test/Auth.vue')
|
||||||
const NoAuth = () => import('@/views/test/NoAuth.vue');
|
const NoAuth = () => import('@/views/test/NoAuth.vue')
|
||||||
const Nest = () => import('@/views/test/Nest.vue');
|
const Nest = () => import('@/views/test/Nest.vue')
|
||||||
const NestPage1 = () => import('@/views/test/nest/Page1.vue');
|
const NestPage1 = () => import('@/views/test/nest/Page1.vue')
|
||||||
const NestPage2 = () => import('@/views/test/nest/Page2.vue');
|
const NestPage2 = () => import('@/views/test/nest/Page2.vue')
|
||||||
const Iscache = () => import('@/views/test/Cache.vue');
|
const Iscache = () => import('@/views/test/Cache.vue')
|
||||||
const Nocache = () => import('@/views/test/Nocache.vue');
|
const Nocache = () => import('@/views/test/Nocache.vue')
|
||||||
|
|
||||||
export default [
|
export default [
|
||||||
{
|
{
|
||||||
@ -109,4 +109,4 @@ export default [
|
|||||||
},
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
];
|
]
|
||||||
|
|||||||
@ -1,9 +1,9 @@
|
|||||||
//index.js
|
//index.js
|
||||||
import { createStore } from 'vuex';
|
import { createStore } from 'vuex'
|
||||||
import app from './modules/app';
|
import app from './modules/app'
|
||||||
import account from './modules/account';
|
import account from './modules/account'
|
||||||
import menu from './modules/menu';
|
import menu from './modules/menu'
|
||||||
import tags from './modules/tags';
|
import tags from './modules/tags'
|
||||||
|
|
||||||
export default createStore({
|
export default createStore({
|
||||||
modules: {
|
modules: {
|
||||||
@ -12,4 +12,4 @@ export default createStore({
|
|||||||
menu,
|
menu,
|
||||||
tags,
|
tags,
|
||||||
},
|
},
|
||||||
});
|
})
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
import { GetUserinfo } from '@/api/login';
|
import { GetUserinfo } from '@/api/login'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
namespaced: true,
|
namespaced: true,
|
||||||
@ -8,21 +8,21 @@ export default {
|
|||||||
mutations: {
|
mutations: {
|
||||||
// 保存用户信息
|
// 保存用户信息
|
||||||
setUserinfo(state, data) {
|
setUserinfo(state, data) {
|
||||||
state.userinfo = data;
|
state.userinfo = data
|
||||||
},
|
},
|
||||||
// 清除用户信息
|
// 清除用户信息
|
||||||
clearUserinfo(state) {
|
clearUserinfo(state) {
|
||||||
state.userinfo = null;
|
state.userinfo = null
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
actions: {
|
actions: {
|
||||||
// 获取用户信息
|
// 获取用户信息
|
||||||
async getUserinfo({ commit }) {
|
async getUserinfo({ commit }) {
|
||||||
const { code, data } = await GetUserinfo();
|
const { code, data } = await GetUserinfo()
|
||||||
if (+code === 200) {
|
if (+code === 200) {
|
||||||
commit('setUserinfo', data);
|
commit('setUserinfo', data)
|
||||||
return Promise.resolve(data);
|
return Promise.resolve(data)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
};
|
}
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
import { getItem, setItem, removeItem } from '@/utils/storage'; //getItem和setItem是封装的操作localStorage的方法
|
import { getItem, setItem, removeItem } from '@/utils/storage' //getItem和setItem是封装的操作localStorage的方法
|
||||||
export const TOKEN = 'VEA-TOKEN';
|
export const TOKEN = 'VEA-TOKEN'
|
||||||
const COLLAPSE = 'VEA-COLLAPSE';
|
const COLLAPSE = 'VEA-COLLAPSE'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
namespaced: true,
|
namespaced: true,
|
||||||
@ -14,28 +14,28 @@ export default {
|
|||||||
},
|
},
|
||||||
mutations: {
|
mutations: {
|
||||||
setToken(state, data) {
|
setToken(state, data) {
|
||||||
state.authorization = data;
|
state.authorization = data
|
||||||
// 保存到localStorage
|
// 保存到localStorage
|
||||||
setItem(TOKEN, data);
|
setItem(TOKEN, data)
|
||||||
},
|
},
|
||||||
clearToken(state) {
|
clearToken(state) {
|
||||||
state.authorization = '';
|
state.authorization = ''
|
||||||
|
|
||||||
removeItem(TOKEN);
|
removeItem(TOKEN)
|
||||||
},
|
},
|
||||||
setCollapse(state, data) {
|
setCollapse(state, data) {
|
||||||
state.sidebar.collapse = data;
|
state.sidebar.collapse = data
|
||||||
// 保存到localStorage
|
// 保存到localStorage
|
||||||
setItem(COLLAPSE, data);
|
setItem(COLLAPSE, data)
|
||||||
},
|
},
|
||||||
clearCollapse(state) {
|
clearCollapse(state) {
|
||||||
state.sidebar.collapse = '';
|
state.sidebar.collapse = ''
|
||||||
|
|
||||||
removeItem(COLLAPSE);
|
removeItem(COLLAPSE)
|
||||||
},
|
},
|
||||||
setDevice(state, device) {
|
setDevice(state, device) {
|
||||||
state.device = device;
|
state.device = device
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
actions: {},
|
actions: {},
|
||||||
};
|
}
|
||||||
|
|||||||
@ -1,23 +1,23 @@
|
|||||||
import { allMenus } from '@/router';
|
import { allMenus } from '@/router'
|
||||||
// import { GetMenus } from '@/api/menu';
|
// import { GetMenus } from '@/api/menu';
|
||||||
|
|
||||||
const hasPermission = (role, route) => {
|
const hasPermission = (role, route) => {
|
||||||
if (!!route.meta && !!route.meta.roles && !route.meta.roles.includes(role)) {
|
if (!!route.meta && !!route.meta.roles && !route.meta.roles.includes(role)) {
|
||||||
return false;
|
return false
|
||||||
|
}
|
||||||
|
return true
|
||||||
}
|
}
|
||||||
return true;
|
|
||||||
};
|
|
||||||
|
|
||||||
const generateUrl = (path, parentPath) => {
|
const generateUrl = (path, parentPath) => {
|
||||||
return path.startsWith('/')
|
return path.startsWith('/')
|
||||||
? path
|
? path
|
||||||
: path
|
: path
|
||||||
? `${parentPath}/${path}`
|
? `${parentPath}/${path}`
|
||||||
: parentPath;
|
: parentPath
|
||||||
};
|
}
|
||||||
|
|
||||||
const getFilterMenus = (arr, role, parentPath = '') => {
|
const getFilterMenus = (arr, role, parentPath = '') => {
|
||||||
const menus = [];
|
const menus = []
|
||||||
|
|
||||||
arr.forEach(item => {
|
arr.forEach(item => {
|
||||||
if (hasPermission(role, item) && !item.hidden) {
|
if (hasPermission(role, item) && !item.hidden) {
|
||||||
@ -25,20 +25,20 @@ const getFilterMenus = (arr, role, parentPath = '') => {
|
|||||||
url: generateUrl(item.path, parentPath),
|
url: generateUrl(item.path, parentPath),
|
||||||
title: item.meta.title,
|
title: item.meta.title,
|
||||||
icon: item.icon,
|
icon: item.icon,
|
||||||
};
|
}
|
||||||
if (item.children) {
|
if (item.children) {
|
||||||
if (item.children.length === 1) {
|
if (item.children.length === 1) {
|
||||||
menu.url = generateUrl(item.children[0].path, menu.url);
|
menu.url = generateUrl(item.children[0].path, menu.url)
|
||||||
} else {
|
} 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 {
|
export default {
|
||||||
namespaced: true,
|
namespaced: true,
|
||||||
@ -47,14 +47,14 @@ export default {
|
|||||||
},
|
},
|
||||||
mutations: {
|
mutations: {
|
||||||
SET_MENUS(state, data) {
|
SET_MENUS(state, data) {
|
||||||
state.menus = data;
|
state.menus = data
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
actions: {
|
actions: {
|
||||||
async generateMenus({ commit }, role) {
|
async generateMenus({ commit }, role) {
|
||||||
// 方式一:根据角色生成菜单
|
// 方式一:根据角色生成菜单
|
||||||
const menus = getFilterMenus(allMenus, role);
|
const menus = getFilterMenus(allMenus, role)
|
||||||
commit('SET_MENUS', menus);
|
commit('SET_MENUS', menus)
|
||||||
|
|
||||||
// // 方式二:从后台获取菜单
|
// // 方式二:从后台获取菜单
|
||||||
// const { code, data } = await GetMenus();
|
// const { code, data } = await GetMenus();
|
||||||
@ -63,4 +63,4 @@ export default {
|
|||||||
// }
|
// }
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
};
|
}
|
||||||
|
|||||||
@ -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 = {
|
const state = {
|
||||||
tagList: getItem(TAGLIST) || [],
|
tagList: getItem(TAGLIST) || [],
|
||||||
cacheList: [],
|
cacheList: [],
|
||||||
activePosition: 0,
|
activePosition: 0,
|
||||||
};
|
}
|
||||||
|
|
||||||
const mutations = {
|
const mutations = {
|
||||||
ADD_TAG_LIST: (state, { path, fullPath, name, meta }) => {
|
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.tagList.splice(
|
||||||
state.activePosition + 1,
|
state.activePosition + 1,
|
||||||
@ -23,136 +23,136 @@ const mutations = {
|
|||||||
fullPath: fullPath || path,
|
fullPath: fullPath || path,
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
);
|
)
|
||||||
|
|
||||||
// 保存到localStorage
|
// 保存到localStorage
|
||||||
setItem(TAGLIST, state.tagList);
|
setItem(TAGLIST, state.tagList)
|
||||||
},
|
},
|
||||||
ADD_CACHE_LIST: (state, tag) => {
|
ADD_CACHE_LIST: (state, tag) => {
|
||||||
if (state.cacheList.includes(tag.name)) return;
|
if (state.cacheList.includes(tag.name)) return
|
||||||
if (!tag.meta.noCache) {
|
if (!tag.meta.noCache) {
|
||||||
state.cacheList.push(tag.name);
|
state.cacheList.push(tag.name)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
DEL_TAG_LIST: (state, tag) => {
|
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
|
// 保存到localStorage
|
||||||
setItem(TAGLIST, state.tagList);
|
setItem(TAGLIST, state.tagList)
|
||||||
},
|
},
|
||||||
DEL_CACHE_LIST: (state, tag) => {
|
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) => {
|
DEL_OTHER_TAG_LIST: (state, tag) => {
|
||||||
state.tagList = state.tagList.filter(
|
state.tagList = state.tagList.filter(
|
||||||
v => !!v.meta.affix || v.path === tag.path
|
v => !!v.meta.affix || v.path === tag.path
|
||||||
);
|
)
|
||||||
// 保存到localStorage
|
// 保存到localStorage
|
||||||
setItem(TAGLIST, state.tagList);
|
setItem(TAGLIST, state.tagList)
|
||||||
},
|
},
|
||||||
DEL_OTHER_CACHE_LIST: (state, tag) => {
|
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) => {
|
DEL_SOME_TAG_LIST: (state, tags) => {
|
||||||
state.tagList = state.tagList.filter(
|
state.tagList = state.tagList.filter(
|
||||||
v => !!v.meta.affix || tags.every(tag => tag.path !== v.path)
|
v => !!v.meta.affix || tags.every(tag => tag.path !== v.path)
|
||||||
);
|
)
|
||||||
// 保存到localStorage
|
// 保存到localStorage
|
||||||
setItem(TAGLIST, state.tagList);
|
setItem(TAGLIST, state.tagList)
|
||||||
},
|
},
|
||||||
|
|
||||||
DEL_SOME_CACHE_LIST: (state, tags) => {
|
DEL_SOME_CACHE_LIST: (state, tags) => {
|
||||||
state.cacheList = state.cacheList.filter(v =>
|
state.cacheList = state.cacheList.filter(v =>
|
||||||
tags.every(tag => tag.name !== v)
|
tags.every(tag => tag.name !== v)
|
||||||
);
|
)
|
||||||
},
|
},
|
||||||
|
|
||||||
DEL_ALL_TAG_LIST: state => {
|
DEL_ALL_TAG_LIST: state => {
|
||||||
state.tagList = state.tagList.filter(v => !!v.meta.affix);
|
state.tagList = state.tagList.filter(v => !!v.meta.affix)
|
||||||
// 保存到localStorage
|
// 保存到localStorage
|
||||||
removeItem(TAGLIST);
|
removeItem(TAGLIST)
|
||||||
},
|
},
|
||||||
DEL_ALL_CACHE_LIST: state => {
|
DEL_ALL_CACHE_LIST: state => {
|
||||||
state.cacheList = [];
|
state.cacheList = []
|
||||||
},
|
},
|
||||||
|
|
||||||
UPDATE_TAG_LIST: (state, tag) => {
|
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) {
|
if (index > -1) {
|
||||||
state.tagList[index] = Object.assign({}, state.tagList[index], tag);
|
state.tagList[index] = Object.assign({}, state.tagList[index], tag)
|
||||||
// 保存到localStorage
|
// 保存到localStorage
|
||||||
setItem(TAGLIST, state.tagList);
|
setItem(TAGLIST, state.tagList)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
SAVE_ACTIVE_POSITION: (state, index) => {
|
SAVE_ACTIVE_POSITION: (state, index) => {
|
||||||
state.activePosition = index;
|
state.activePosition = index
|
||||||
},
|
},
|
||||||
};
|
}
|
||||||
|
|
||||||
const actions = {
|
const actions = {
|
||||||
saveActivePosition({ commit }, index) {
|
saveActivePosition({ commit }, index) {
|
||||||
commit('SAVE_ACTIVE_POSITION', index);
|
commit('SAVE_ACTIVE_POSITION', index)
|
||||||
},
|
},
|
||||||
addTag({ dispatch }, tag) {
|
addTag({ dispatch }, tag) {
|
||||||
dispatch('addTagList', tag);
|
dispatch('addTagList', tag)
|
||||||
dispatch('addCacheList', tag);
|
dispatch('addCacheList', tag)
|
||||||
},
|
},
|
||||||
addTagList({ commit }, tag) {
|
addTagList({ commit }, tag) {
|
||||||
commit('ADD_TAG_LIST', tag);
|
commit('ADD_TAG_LIST', tag)
|
||||||
},
|
},
|
||||||
addCacheList({ commit }, tag) {
|
addCacheList({ commit }, tag) {
|
||||||
commit('ADD_CACHE_LIST', tag);
|
commit('ADD_CACHE_LIST', tag)
|
||||||
},
|
},
|
||||||
|
|
||||||
delTag({ dispatch }, tag) {
|
delTag({ dispatch }, tag) {
|
||||||
dispatch('delTagList', tag);
|
dispatch('delTagList', tag)
|
||||||
dispatch('delCacheList', tag);
|
dispatch('delCacheList', tag)
|
||||||
},
|
},
|
||||||
delTagList({ commit }, tag) {
|
delTagList({ commit }, tag) {
|
||||||
commit('DEL_TAG_LIST', tag);
|
commit('DEL_TAG_LIST', tag)
|
||||||
},
|
},
|
||||||
delCacheList({ commit }, tag) {
|
delCacheList({ commit }, tag) {
|
||||||
commit('DEL_CACHE_LIST', tag);
|
commit('DEL_CACHE_LIST', tag)
|
||||||
},
|
},
|
||||||
|
|
||||||
delOtherTags({ dispatch }, tag) {
|
delOtherTags({ dispatch }, tag) {
|
||||||
dispatch('delOtherTagList', tag);
|
dispatch('delOtherTagList', tag)
|
||||||
dispatch('delOtherCacheList', tag);
|
dispatch('delOtherCacheList', tag)
|
||||||
},
|
},
|
||||||
delOtherTagList({ commit }, tag) {
|
delOtherTagList({ commit }, tag) {
|
||||||
commit('DEL_OTHER_TAG_LIST', tag);
|
commit('DEL_OTHER_TAG_LIST', tag)
|
||||||
},
|
},
|
||||||
delOtherCacheList({ commit }, tag) {
|
delOtherCacheList({ commit }, tag) {
|
||||||
commit('DEL_OTHER_CACHE_LIST', tag);
|
commit('DEL_OTHER_CACHE_LIST', tag)
|
||||||
},
|
},
|
||||||
|
|
||||||
delSomeTags({ commit }, tags) {
|
delSomeTags({ commit }, tags) {
|
||||||
commit('DEL_SOME_TAG_LIST', tags);
|
commit('DEL_SOME_TAG_LIST', tags)
|
||||||
commit('DEL_SOME_CACHE_LIST', tags);
|
commit('DEL_SOME_CACHE_LIST', tags)
|
||||||
},
|
},
|
||||||
|
|
||||||
delAllTags({ dispatch }) {
|
delAllTags({ dispatch }) {
|
||||||
dispatch('delAllTagList');
|
dispatch('delAllTagList')
|
||||||
dispatch('delAllCacheList');
|
dispatch('delAllCacheList')
|
||||||
},
|
},
|
||||||
delAllTagList({ commit }) {
|
delAllTagList({ commit }) {
|
||||||
commit('DEL_ALL_TAG_LIST');
|
commit('DEL_ALL_TAG_LIST')
|
||||||
},
|
},
|
||||||
delAllCacheList({ commit }) {
|
delAllCacheList({ commit }) {
|
||||||
commit('DEL_ALL_CACHE_LIST');
|
commit('DEL_ALL_CACHE_LIST')
|
||||||
},
|
},
|
||||||
|
|
||||||
updateTagList({ commit }, tag) {
|
updateTagList({ commit }, tag) {
|
||||||
commit('UPDATE_TAG_LIST', tag);
|
commit('UPDATE_TAG_LIST', tag)
|
||||||
},
|
},
|
||||||
};
|
}
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
namespaced: true,
|
namespaced: true,
|
||||||
state,
|
state,
|
||||||
mutations,
|
mutations,
|
||||||
actions,
|
actions,
|
||||||
};
|
}
|
||||||
|
|||||||
@ -1,34 +1,34 @@
|
|||||||
import axios from 'axios';
|
import axios from 'axios'
|
||||||
import { ElMessage } from 'element-plus';
|
import { ElMessage } from 'element-plus'
|
||||||
import store from '@/store';
|
import store from '@/store'
|
||||||
import router from '@/router';
|
import router from '@/router'
|
||||||
|
|
||||||
const service = axios.create({
|
const service = axios.create({
|
||||||
baseURL: '/',
|
baseURL: '/',
|
||||||
timeout: 10000,
|
timeout: 10000,
|
||||||
withCredentials: true,
|
withCredentials: true,
|
||||||
});
|
})
|
||||||
|
|
||||||
// 拦截请求
|
// 拦截请求
|
||||||
service.interceptors.request.use(
|
service.interceptors.request.use(
|
||||||
config => {
|
config => {
|
||||||
const { authorization } = store.state.app;
|
const { authorization } = store.state.app
|
||||||
if (authorization) {
|
if (authorization) {
|
||||||
config.headers.Authorization = `Bearer ${authorization.token}`;
|
config.headers.Authorization = `Bearer ${authorization.token}`
|
||||||
}
|
}
|
||||||
return config;
|
return config
|
||||||
},
|
},
|
||||||
error => {
|
error => {
|
||||||
// console.log(error);
|
// console.log(error);
|
||||||
return Promise.reject(error);
|
return Promise.reject(error)
|
||||||
}
|
}
|
||||||
);
|
)
|
||||||
|
|
||||||
// 拦截响应
|
// 拦截响应
|
||||||
service.interceptors.response.use(
|
service.interceptors.response.use(
|
||||||
// 响应成功进入第1个函数,该函数的参数是响应对象
|
// 响应成功进入第1个函数,该函数的参数是响应对象
|
||||||
response => {
|
response => {
|
||||||
return response.data;
|
return response.data
|
||||||
},
|
},
|
||||||
// 响应失败进入第2个函数,该函数的参数是错误对象
|
// 响应失败进入第2个函数,该函数的参数是错误对象
|
||||||
async error => {
|
async error => {
|
||||||
@ -36,12 +36,12 @@ service.interceptors.response.use(
|
|||||||
// 响应拦截器中的 error 就是那个响应的错误对象
|
// 响应拦截器中的 error 就是那个响应的错误对象
|
||||||
if (error.response && error.response.status === 401) {
|
if (error.response && error.response.status === 401) {
|
||||||
// 校验是否有 refresh_token
|
// 校验是否有 refresh_token
|
||||||
const { authorization } = store.state.app;
|
const { authorization } = store.state.app
|
||||||
if (!authorization || !authorization.refresh_token) {
|
if (!authorization || !authorization.refresh_token) {
|
||||||
router.push('/login');
|
router.push('/login')
|
||||||
|
|
||||||
// 代码不要往后执行了
|
// 代码不要往后执行了
|
||||||
return Promise.reject(error);
|
return Promise.reject(error)
|
||||||
}
|
}
|
||||||
// 如果有refresh_token,则请求获取新的 token
|
// 如果有refresh_token,则请求获取新的 token
|
||||||
try {
|
try {
|
||||||
@ -52,32 +52,32 @@ service.interceptors.response.use(
|
|||||||
headers: {
|
headers: {
|
||||||
Authorization: `Bearer ${authorization.refresh_token}`,
|
Authorization: `Bearer ${authorization.refresh_token}`,
|
||||||
},
|
},
|
||||||
});
|
})
|
||||||
// 如果获取成功,则把新的 token 更新到容器中
|
// 如果获取成功,则把新的 token 更新到容器中
|
||||||
// console.log('刷新 token 成功', res)
|
// console.log('刷新 token 成功', res)
|
||||||
store.commit('app/setToken', {
|
store.commit('app/setToken', {
|
||||||
token: res.data.data.token, // 最新获取的可用 token
|
token: res.data.data.token, // 最新获取的可用 token
|
||||||
refresh_token: authorization.refresh_token, // 还是原来的 refresh_token
|
refresh_token: authorization.refresh_token, // 还是原来的 refresh_token
|
||||||
});
|
})
|
||||||
// 把之前失败的用户请求继续发出去
|
// 把之前失败的用户请求继续发出去
|
||||||
// config 是一个对象,其中包含本次失败请求相关的那些配置信息,例如 url、method 都有
|
// config 是一个对象,其中包含本次失败请求相关的那些配置信息,例如 url、method 都有
|
||||||
// return 把 request 的请求结果继续返回给发请求的具体位置
|
// return 把 request 的请求结果继续返回给发请求的具体位置
|
||||||
return service(error.config);
|
return service(error.config)
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
// 如果获取失败,直接跳转 登录页
|
// 如果获取失败,直接跳转 登录页
|
||||||
// console.log('请求刷新 token 失败', err)
|
// console.log('请求刷新 token 失败', err)
|
||||||
router.push('/login');
|
router.push('/login')
|
||||||
// 清除token
|
// 清除token
|
||||||
store.commit('app/clearToken');
|
store.commit('app/clearToken')
|
||||||
return Promise.reject(error);
|
return Promise.reject(error)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// console.dir(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
|
||||||
|
|||||||
@ -1,20 +1,20 @@
|
|||||||
export const getItem = name => {
|
export const getItem = name => {
|
||||||
const data = window.localStorage.getItem(name);
|
const data = window.localStorage.getItem(name)
|
||||||
try {
|
try {
|
||||||
return JSON.parse(data);
|
return JSON.parse(data)
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
return data;
|
return data
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
|
||||||
|
|
||||||
export const setItem = (name, value) => {
|
export const setItem = (name, value) => {
|
||||||
if (typeof value === 'object') {
|
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 => {
|
export const removeItem = name => {
|
||||||
window.localStorage.removeItem(name);
|
window.localStorage.removeItem(name)
|
||||||
};
|
}
|
||||||
|
|||||||
@ -21,11 +21,11 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import { defineComponent } from 'vue';
|
import { defineComponent } from 'vue'
|
||||||
|
|
||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
props: ['error'],
|
props: ['error'],
|
||||||
});
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
|
|||||||
@ -3,12 +3,12 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import { defineComponent } from 'vue';
|
import { defineComponent } from 'vue'
|
||||||
|
|
||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
name: 'home',
|
name: 'home',
|
||||||
setup() {},
|
setup() {},
|
||||||
});
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
|
|||||||
@ -43,17 +43,17 @@ import {
|
|||||||
toRefs,
|
toRefs,
|
||||||
ref,
|
ref,
|
||||||
computed,
|
computed,
|
||||||
} from 'vue';
|
} from 'vue'
|
||||||
import { Login } from '@/api/login';
|
import { Login } from '@/api/login'
|
||||||
import { useStore } from 'vuex';
|
import { useStore } from 'vuex'
|
||||||
import { useRouter, useRoute } from 'vue-router';
|
import { useRouter, useRoute } from 'vue-router'
|
||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
name: 'login',
|
name: 'login',
|
||||||
setup() {
|
setup() {
|
||||||
const { ctx } = getCurrentInstance(); // 可以把ctx当成vue2中的this
|
const { ctx } = getCurrentInstance() // 可以把ctx当成vue2中的this
|
||||||
const store = useStore();
|
const store = useStore()
|
||||||
const router = useRouter();
|
const router = useRouter()
|
||||||
const route = useRoute();
|
const route = useRoute()
|
||||||
const state = reactive({
|
const state = reactive({
|
||||||
model: {
|
model: {
|
||||||
userName: 'admin',
|
userName: 'admin',
|
||||||
@ -78,34 +78,34 @@ export default defineComponent({
|
|||||||
loginForm: ref(null),
|
loginForm: ref(null),
|
||||||
submit: () => {
|
submit: () => {
|
||||||
if (state.loading) {
|
if (state.loading) {
|
||||||
return;
|
return
|
||||||
}
|
}
|
||||||
state.loginForm.validate(async valid => {
|
state.loginForm.validate(async valid => {
|
||||||
if (valid) {
|
if (valid) {
|
||||||
state.loading = true;
|
state.loading = true
|
||||||
const { code, data, message } = await Login(state.model);
|
const { code, data, message } = await Login(state.model)
|
||||||
if (+code === 200) {
|
if (+code === 200) {
|
||||||
ctx.$message.success({
|
ctx.$message.success({
|
||||||
message: '登录成功',
|
message: '登录成功',
|
||||||
duration: 1000,
|
duration: 1000,
|
||||||
});
|
})
|
||||||
const targetPath = route.query.redirect;
|
const targetPath = route.query.redirect
|
||||||
router.push(targetPath ? targetPath : '/');
|
router.push(targetPath ? targetPath : '/')
|
||||||
store.commit('app/setToken', data);
|
store.commit('app/setToken', data)
|
||||||
} else {
|
} else {
|
||||||
ctx.$message.error(message);
|
ctx.$message.error(message)
|
||||||
}
|
}
|
||||||
state.loading = false;
|
state.loading = false
|
||||||
}
|
}
|
||||||
});
|
})
|
||||||
},
|
},
|
||||||
});
|
})
|
||||||
|
|
||||||
return {
|
return {
|
||||||
...toRefs(state),
|
...toRefs(state),
|
||||||
};
|
}
|
||||||
},
|
},
|
||||||
});
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
|
|||||||
@ -1,11 +1,11 @@
|
|||||||
<script>
|
<script>
|
||||||
import { h } from 'vue';
|
import { h } from 'vue'
|
||||||
export default {
|
export default {
|
||||||
created() {
|
created() {
|
||||||
this.$router.replace(this.$route.fullPath.replace(/^\/redirect/, ''));
|
this.$router.replace(this.$route.fullPath.replace(/^\/redirect/, ''))
|
||||||
},
|
},
|
||||||
render() {
|
render() {
|
||||||
return h('div');
|
return h('div')
|
||||||
},
|
},
|
||||||
};
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@ -6,15 +6,15 @@
|
|||||||
</dl>
|
</dl>
|
||||||
</template>
|
</template>
|
||||||
<script>
|
<script>
|
||||||
import { defineComponent, onActivated } from 'vue';
|
import { defineComponent, onActivated } from 'vue'
|
||||||
|
|
||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
name: 'test-cache', // 该name必须跟路由配置的name一致
|
name: 'test-cache', // 该name必须跟路由配置的name一致
|
||||||
setup() {
|
setup() {
|
||||||
console.log('cache');
|
console.log('cache')
|
||||||
onActivated(() => {
|
onActivated(() => {
|
||||||
console.log('onActivated');
|
console.log('onActivated')
|
||||||
});
|
})
|
||||||
},
|
},
|
||||||
});
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@ -6,12 +6,12 @@
|
|||||||
</dl>
|
</dl>
|
||||||
</template>
|
</template>
|
||||||
<script>
|
<script>
|
||||||
import { defineComponent } from 'vue';
|
import { defineComponent } from 'vue'
|
||||||
|
|
||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
name: 'test-no-cache', // 该name必须跟路由配置的name一致,不一致或者不设置name则不缓存
|
name: 'test-no-cache', // 该name必须跟路由配置的name一致,不一致或者不设置name则不缓存
|
||||||
setup() {
|
setup() {
|
||||||
console.log('nocache');
|
console.log('nocache')
|
||||||
},
|
},
|
||||||
});
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@ -32,7 +32,7 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import { defineComponent, reactive, ref, toRefs } from 'vue';
|
import { defineComponent, reactive, ref, toRefs } from 'vue'
|
||||||
|
|
||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
name: 'testList',
|
name: 'testList',
|
||||||
@ -210,15 +210,15 @@ export default defineComponent({
|
|||||||
},
|
},
|
||||||
selectedItems: [],
|
selectedItems: [],
|
||||||
batchDelete() {
|
batchDelete() {
|
||||||
console.log(state.selectedItems);
|
console.log(state.selectedItems)
|
||||||
},
|
},
|
||||||
// 选择
|
// 选择
|
||||||
handleSelectionChange(arr) {
|
handleSelectionChange(arr) {
|
||||||
state.selectedItems = arr;
|
state.selectedItems = arr
|
||||||
},
|
},
|
||||||
// 请求函数
|
// 请求函数
|
||||||
async getList(params) {
|
async getList(params) {
|
||||||
console.log(params);
|
console.log(params)
|
||||||
// params是从组件接收的,包含分页和搜索字段。
|
// params是从组件接收的,包含分页和搜索字段。
|
||||||
const { data } = await new Promise(rs => {
|
const { data } = await new Promise(rs => {
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
@ -239,23 +239,23 @@ export default defineComponent({
|
|||||||
],
|
],
|
||||||
total: 100,
|
total: 100,
|
||||||
},
|
},
|
||||||
});
|
})
|
||||||
}, 3000);
|
}, 3000)
|
||||||
});
|
})
|
||||||
|
|
||||||
// 必须要返回一个对象,包含data数组和total总数
|
// 必须要返回一个对象,包含data数组和total总数
|
||||||
return {
|
return {
|
||||||
data: data.list,
|
data: data.list,
|
||||||
total: +data.total,
|
total: +data.total,
|
||||||
};
|
}
|
||||||
},
|
},
|
||||||
});
|
})
|
||||||
const table = ref(null);
|
const table = ref(null)
|
||||||
const refresh = () => {
|
const refresh = () => {
|
||||||
table.value.refresh();
|
table.value.refresh()
|
||||||
};
|
}
|
||||||
|
|
||||||
return { ...toRefs(state), refresh, table };
|
return { ...toRefs(state), refresh, table }
|
||||||
},
|
},
|
||||||
});
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user