小系统bug修复与功能增强--系统篇

先看看系统界面,就2个主要界面

第一个是登录界面

第二个是登录后主体界面

前端用TypeScript+Vue3+ElementPlus写,后端用php8+thinkphp8

第一点,功能增强点,原来的维持组件间的登录状态提升为用pinia来改写

main.js文件变动如下

// main.js

import { createApp } from 'vue'

import { createPinia } from 'pinia'

import piniaPersist from 'pinia-plugin-persist'

import ElementPlus from 'element-plus'

import 'element-plus/dist/index.css'

import { router } from './router'

import App from './App.vue'

const pinia = createPinia()

pinia.use(piniaPersist)

const app = createApp(App)

app.use(pinia)

app.use(ElementPlus)

app.use(router)

app.mount('#app')

新建tokener.js文件

// stores/tokener.js

import { defineStore } from 'pinia'

export const useTokenerStore = defineStore('tokener', {

state: () => {

return { token: 0 }

},

actions: {

setToken(value) {

this.token = value

},

},

persist: {

enabled: true,

strategies: [

{ storage: localStorage, paths: ['token'] },

],

}

})

pinia默认使用sessionStorage来存储,这里使用了localStorage,也可以为不同的变量混用存储方式

然后看看在新写的展示图片列表的地方是怎么使用存储好的token令牌的,这也是第二个新增点,其他地方用法同理

<script lang="ts" setup>

import { onMounted, ref } from 'vue'

import axios from 'axios';

import { useTokenerStore } from '../../stores/tokener'

const tokener = useTokenerStore()

onMounted(() => {

console.log(`the component is now mounted.`)

axios.get('http://admin.am8.com/index/getList', {

params: {

token: tokener.token,

}

})

.then(function (response) {

console.log(response);

if (response.data.code === 1) {

tableData.value = response.data.data

} else {

if (response.data.sub_code === 0) {

tokener.$reset()

}

}

})

.catch(function (error) {

console.log(error);

});

})

const tableData = ref([])

</script>

首先需要引入tokener.js文件

import { useTokenerStore } from '../../stores/tokener'

然后是获取存储的对象

const tokener = useTokenerStore()

最后是直接通过对象引用存储好的token值即可

params: {

token: tokener.token,

}

另外还有一个地方重置了token对象,这时候整个对象的值都会恢复成初始值

if (response.data.sub_code === 0) {

tokener.$reset()

}

我们继续看看展示图片列表的视图部分,这个展示图片的模块是新增的

<template>

<el-table :data="tableData" style="width: 100%">

<el-table-column type="index" width="50" />

<el-table-column label="Name" width="180">

<template #default="scope">

<el-image

style="width: 100px; height: 100px"

:src="scope.row.name"

fit="fill"></el-image>

</template>

</el-table-column>

</el-table>

</template>

以表格的方式展示了序列数和图片列表,结合上面逻辑处理部分,就能看到tableData是在哪里来的

if (response.data.code === 1) {

tableData.value = response.data.data

}

后端返回成功时,初始化了tableData的值

后端接口如下

public function getList()

{

$list = Head2::select();

$list2 = [];

foreach ($list as $key => $value) {

$search = '\\';

$replace = '/';

replacedString = str_replace(search, $replace, $value->name);

list\[key]['name'] = Config::get('app.server_url').'storage/'.$replacedString;

}

return mySuccessResponse($list);

}

第三个新增点是将前端代码打包进后端展示

打包就在项目中执行npm run build,生成dist文件夹,复制dist文件夹放到thinkphp8的public文件夹里面,这里我在public文件夹下新增一个admin文件夹,然后再把dist文件夹放到admin文件夹中,想法是项目应该是可以支持多个单文件组件的模式。比如后面计划前台又用另一个单文件组件来写。然后把dist文件夹中的index.html文件剪切到thinkphp8的视图中,想法是前端页面应该可以既用vue3项目写也可以用thinkphp8模板来写,混写。兼容各种技术来实现前端

编写视图接口

use think\facade\View;

class Anonym {

public function index()

{

return View::fetch();

}

...

}

视图结构如下

后端是自动多应用模式,这是一个admin应用的视图结构,那么在浏览器就可以访问http://admin.am8.com/Anonym/index进入到登录页面,admin.am8.com是我配置的映射到admin应用下的域名,大家各自配各自的

然后index.html页面需要稍微调整一下路径

<!DOCTYPE html>

<html lang="en">

<head>

<meta charset="UTF-8" />

<link rel="icon" href="/admin/dist/favicon.ico" />

<meta name="viewport" content="width=device-width, initial-scale=1.0" />

<title>Vite App</title>

<script type="module" crossorigin src="/admin/dist/assets/index-BBtu1Sxt.js"></script>

<link rel="stylesheet" crossorigin href="/admin/dist/assets/index-DbFK1zW7.css">

</head>

<body>

<div id="app"></div>

</body>

</html>

前面就说了在public文件夹下新建admin文件夹然后再放入dist文件夹,这里的修改就是为了引用对前端的资源文件

第四个改动点是将BaseController里面的登录检查移到应用中间件中实现,原因是因为继承的基础控制器在未登录情况下不能直接返回json对象到前端,需要用die等方法处理成json字符串。如果处理成json字符串,前端又需要解码json字符串成json对象。而且thinkphp8也不推荐使用die等中断程序的方法。

新增admin应用中间件,并且修改代码如下

public function handle($request, \Closure $next)

{

$array = ['anonym/login', 'anonym/index', 'Anonym/index'];

$value = $request->pathinfo();

$sign = true;

foreach ($array as $k => $v) {

if ($v === $value) {

$sign = false;

break;

}

}

if ($sign) {

$exist = AdminToken::where([

'token' => request()->param('token'),

])->find();

if ($exist !== null) {

// 获取当前时间的时间戳

$now = time();

timestamp = intval(exist->update_time);

// 设定1小时的秒数

$oneHourInSeconds = 3600;

if (($now - $timestamp) > $oneHourInSeconds) {

return myFailResponse(0, '登录状态已过期');

}

} else {

return myFailResponse(0, '未登录');

}

}

return next(request);

}

这里没用inArray来实现,因为那个方法判断有时不准确,改成如下写法

$array = ['anonym/login', 'anonym/index', 'Anonym/index'];

$value = $request->pathinfo();

$sign = true;

foreach ($array as $k => $v) {

if ($v === $value) {

$sign = false;

break;

}

}

if ($sign) {

...

}

这样写是为了判断路径,如果路径属于以上几种路径就不用检查登录状态,分别是登录请求、登录界面显示、还有里面主体界面显示。

第五个改动点,将菜单默认的选中项改为动态路由,这是为了页面刷新时能相应地在菜单项选中项也能对应上

<el-menu

router

:default-active="$route.fullPath"

class="el-menu-vertical-demo"

@open="handleOpen"

@close="handleClose"

>

...

</el-menu>

注意看:default-active="$route.fullPath",就是这个改动

第六个改动点,将前端路由由H5模式改为Hash模式

import { createRouter, createWebHashHistory } from 'vue-router'

history: createWebHashHistory(),

这是因为index.html放在thinkphp视图里面,访问时肯定会经过后端路由,为了不影响到前端路由,故前端改用hash模式

相关推荐
人间打气筒(Ada)1 小时前
ubuntu网络及软件包管理
网络·ubuntu·php
飞天大河豚2 小时前
2025前端框架最新组件解析与实战技巧:Vue与React的革新之路
vue.js·react.js·前端框架
customer083 小时前
【开源免费】基于SpringBoot+Vue.JS医疗报销系统(JAVA毕业设计)
java·vue.js·spring boot·后端·开源
道不尽世间的沧桑3 小时前
第9篇:插槽(Slots)的使用
前端·javascript·vue.js
B站计算机毕业设计超人3 小时前
计算机毕业设计SpringBoot+Vue.jst房屋租赁系统(源码+LW文档+PPT+讲解)
vue.js·spring boot·后端·eclipse·intellij-idea·mybatis·课程设计
bin91533 小时前
DeepSeek 助力 Vue 开发:打造丝滑的滑块(Slider)
前端·javascript·vue.js·前端框架·ecmascript·deepseek
杰九4 小时前
【环境配置】maven,mysql,node.js,vue的快速配置与上手
java·vue.js·spring boot·mysql·node.js·maven
wapicn994 小时前
‌挖数据平台对接DeepSeek推出一键云端部署功能:API接口驱动金融、汽车等行业智能化升级
java·人工智能·python·金融·汽车·php
秋意钟4 小时前
Element UI日期选择器默认显示1970年解决方案
前端·javascript·vue.js·elementui
Hacker_Nightrain4 小时前
内网网络安全的解决之道
安全·web安全·php