vue3-tailwind-todo
https://github.com/kgrg/vue3-tailwind-todo
基于这个项目,把ip到sta的映射做了前端管理.
核心代码是存储和获得的接口,需要flask提供.
def redis2ipdic():
global ipdic
ipdic.clear()
tmdic=cl.hgetall(IPDIC_KEY)
for k in tmdic.keys():
ipdic[k.decode() ]=tmdic[k].decode()
return ipdic
def ipdic2redis():
global ipdic
# 将字典保存到Redis的哈希中
cl.delete(IPDIC_KEY)
cl.hmset(IPDIC_KEY,ipdic)
本地变量ipdic,被flask使用,redis里的ipdic_key被rust使用,需要他们同步,不清楚flask多线程怎么安全,应该就是不安全的
@app.route('/api/getipdic')
def getipdic():
return json.dumps(redis2ipdic())
@app.route('/api/setipdic',methods=['POST'])
def setipdic():
global ipdic
postagr = request.get_json()
ipdic.clear()
for i in postagr:
ipdic[i['IP']]=i['sta']
ipdic2redis()
restartRust()
# print(ipdic)
# ipdic=json.loads(postagr)
return json.dumps({"OK":len(ipdic)})
后端基本就完成了
在项目vite.config.ts,js加入
export default defineConfig({
server: {
proxy: {
// 字符串简写写法
'/foo': 'http://localhost:4567',
// 选项写法
'^/api/.*': {
target: 'http://myserver/',
changeOrigin: true,
rewrite: (path) => path
},
},
},
改变save 的和load的逻辑
在src/shared/server/index.ts
import type { Todo } from '@/modules/todo/types/todo'
import { promises } from 'dns'
import { json } from 'stream/consumers'
import { ref } from 'vue'
const STORAGE_KEY = 'todos'
export class StorageError extends Error {
constructor(message: string, public code: string) {
super(message)
this.name = 'StorageError'
}
}
// StorageService.getTodos().then(data=>
// {
// this.todos =data
// }
async function fetchData(url:string): Promise<string> {
try {
const response = await fetch(url);
if (!response.ok) {
throw new Error('Network response was not ok');
}
return await response.text();
// 等待JSON解析完成
} catch (error) {
console.error('Fetch error:', error);
throw error; // 可以选择重新抛出错误以便上层调用者处理
}
}
export const StorageService = {
async getTodos(): Promise<Todo[]> {
try {
const datastr=await fetchData("/api/getipdic")
const dic:Todo[]=[]
const data=JSON.parse(datastr);
var id=1
for (const i in data){
const me:Todo={ "id":String(id++),"IP":i, "sta":data[i]}
dic.push(me )
}
return dic
// localStorage.setItem(STORAGE_KEY,JSON.stringify(dic))
// return
} catch (error) {
const stored = localStorage.getItem(STORAGE_KEY)
return stored?JSON.parse(stored):[]
throw new StorageError(
'Failed to load todos from storage',
'STORAGE_READ_ERROR'
)
}
},
saveTodos(todos: Todo[]) {
try {
localStorage.setItem(STORAGE_KEY, JSON.stringify(todos))
const re= fetch('./api/setipdic', { method: 'POST', body: JSON.stringify(todos),
headers: { 'Content-Type': 'application/json' } }).then(re=>{
if (re.ok)
re.json().then(data=>{
console.log(data)
})
else
alert ("同步失败saveTodos")
});
} catch (error) {
throw new StorageError(
'Failed to save todos to storage',
'STORAGE_WRITE_ERROR'
)
}
}
}
运行.然后在src/App.vue去掉routeview.
换homeview.因为否则build的index.html无法改名.
<script setup lang="ts">
//import { RouterView } from 'vue-router'
//<RouterView />
import HomePage from '@/modules/todo/views/HomePage.vue'
</script>
<template>
<HomePage />
</template>
工作完成.