关于我有一个后台可配置blog的系统,我使用nuxt做了一个网站,后台可以更新文章这件事情
目录结构
nuxt的结构是page就是可以直接展示的页面,components里面 是可以重复使用的组件,composables可以放一些使用到的小工具, nuxt 与vue3还是很相近的,但是不同于vue的是,nuxt的可带参的路由是直接在可以配参数的文件下建立[id].vue,例如我希望blog 是可以带参的,那么
我以这样的形式久可以了
404 页面除去所有的路由是这样的形式去展示的
在page里面加一个[…slug].vue ,在这个vue文件里写样式就可以了
我的cms的js代码如下,可参考
前端的样式对大家来说还是非常简单的,亮点就在于,这个前端页面的东西是可以配置的,一些blog的内容是可以实时更新的,有的title和活动页面也是可以自己配置的,可以做到的实时发布更新的效果
cms.js 文件的配置是这个项目的亮点
export function randText(len=8){
let text = ' '
const possible = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'
for (let i=0; i<len; i++){
text += possible.charAt(Math.floor(Math.random()*possible.length))
}
return text
}
这段代码是用于生成一个随机字符串。它使用了一个包含大写字母、小写字母和
数字的字符集合(possible),并循环执行以下的步骤
- Math.random() 函数返回一个介于0(包含)和1(不包含) 之间的随机小数
- Math.random() *possible.length 将得到的随机小数去乘以possible字符集合的长度,就会得到一个介于0(包含)和possible.length(不包含)之间的随机数
- Math.floor()函数将上一个得到的随机数向下取整,得到一个整数
- possible.charAt()函数接收上一步得到的整数作为索引,返回对应索引位置上的字符
- text += 将上一步得到的字符 拼接到text的变量上
export async function sendReq(method,url,params,transform) {
let opt ={
server:true,
method,
transform,
}
if(method=='POST' &¶ms){
opt.key=randText(16)
opt.body=params
}
return await useFetch(url,opt)
}
这段代码定义了一个异步函数sendReq,用于发送http 请求
这个函数接受四个参数
- method: 表示请求的方法,可以是’GET’,‘POST’,‘DELETE’.'PUT’等
- url:表示请求的url 地址
- params: 表示请求的参,可以是一个对象或者是字符串
- transform:表示对请求结果的转换函数,用于对返回的数据进行处理
在函数内部,首先要定义一个opt对象,他包含几个属性 - server:true 表示请求将会发送到服务器端
- method: 使用传入的method参数
- transform: 使用传入的transforms参数
接下来,通过一个条件判断语句,检查请求是否是’POST’ 并且是否有参数,如果都满足的话,就执行以下的操作
· 生成一个长度是16的随机字符串,赋值给opt.key
· 把参数params赋值给 opt.body属性
最后,使用useFetch(url,opt) 函数发送http请求,并将其返回结果作为函数的返回值,注意的是,这里使用了await,等待请求的完成
总的来说就是,这段代码是一个用于发送HTTP请求的封装函数,根据请求方法和参数进行相应的设置,并使用useFetch函数去发送请求,并返回了请求结果。
接下来是把用到的方法传有参数
export async function get(path, transform) {
return await sendReq('GET', `/api${path}`, undefined, transform)
}
export async function query(path, { filters, pos, limit, keywords, orders }, transform) {
return await sendReq('POST', `/api${path}`, { filters, pos, limit, keywords, orders }, transform)
}
export function getPageMeta(data){
let head ={
meta:[ ],
}
if(!data){
return head
}
if(data.title){
head.title=data.title
}
if(data.description){
head.meta.push({
name:'description',
content:data.description
})
}
if(data.keywords){
head.meta.push({
name:'keywords',
content:data.keywords
})
}
return head
}
这段代码是定义了一个getPageMeta,用于生成页面的元数据(PageMeta)
函数接受一个参数data 表示页面的数据,函数内部首先要定义一个head 对象,包含一个空数据meta
接下来,通过一系列的条件判断,对data进行检查,如果data为空,那么直接返回head对象
这段代码的作用是根据传入的页面数据data 生成页面的元数据对象head,其中包含了标题,描述和关键词等信息。可以根据需要去使用这些元数据 来设置页面的
function splitTags(tags) {
if (!tags) {
return []
}
if (typeof tags =='string'){
tags = tags.replaceAll(',', ',').replaceAll(';', ',').replaceAll(';', ',').replaceAll('、', ',').replaceAll(' ', ',').replaceAll(';', ',').replaceAll(';', ',')
tags = tags.split(',')
}
return tags.filter(tag =>!tags.startsWith('$')).map(tag =>tag.trim())
}
这段代码定义了一个splitTags 函数,用于将标签字符串拆分成一个标签数组
export function formatData(t){
let shortDate = ''
let longDate = ''
if(!t){
return { shortDate,longDate }
}
if(typeof t == 'object') {
if(!t.Valid) {
return { shortDate,longDate }
}
t=t.Time
}
const d =new Date(t)
const now =new Date()
const monthStr = `${d.getMonth() +1}`.padStart(2,'0')
const dayStr =`${d.getDate()}`.padStart(2,'0')
if (d.getFullYear() != now.getFullYear()) {
shortDate = `${d.getFullYear()}-${monthStr}-${dayStr}`
} else {
shortDate = `${monthStr}-${dayStr}`
}
longDate =`${d.getFullYear()} -${monthStr}-${dayStr} ${dayStr} ${d.getHours()}:${d.getMinutes()}`
return { shortDate, longDate }
}
这段代码定义了一个函数formatDate,用于格式化日期
函数接受一个参数t 表示日期。先定义了两个空的字符串变量
通过一系列的条件判断,对t进行处理,t为空返回一个对象,那么 shortDate 和 longDate 的值都为空字符串。
判断t的类型是否是对象,如果是对象,进一步检查valid 的属性,如果是不存在或者是假值,同样返回一个对象, shortDate 和 longDate 的值都为空字符串。
通过了前面的条件判断后,程序会继续执行后面的代码,使用new date(t)创建一个日期对象d 。然后使用 new Date() 创建一个当前日期对象 now
通过一些操作获取月份、日期、小时和分钟的字符串表示形式,使用 padStart() 方法来保证它们的位数为两位数。
通过比较d的年份和当前的年份来决定shortDate的值,如果年份是不同的,则将shortDate 设置为完整的日期格式(例如:2022-07-01),如果是相同的, shortDate 设置为月份和日期的格式(例如:07-01)
而longDate 设置为完整的日期格式
这段代码的作用就是将传入的日期进行格式化,返回一个包含端短日期和 长日期格式的对象,用于日期的格式化,满足特定的日期显示需求
export function formatPost (item) {
if(item.pubishedAtLong){
return item
}
item.tags=splitTags(item.tags)
const {shortDate,longDate}=formatDate(item.publishedAt)
item.publishedAt=shortDate
item.publishedAtLong=longDate
item.suggestions=(item.suggestions || [] ).map(item=>formatPost(item))
item.relations=(item.relations || []).map(item=>formatPost(item))
return item
}
export async function getCategory(id){
if (!id.startsWith('/')){
id ='/'+id
}
let resp =await get(`/category${id}`,function(data){
data.items=(data.items || []).filter(item => !item.name.stratWith('$'))
return data
})
return resp || []
}
export async function getPage(id,transform){
if(!id.startWith('/')) {
id='/'+id
}
return await get (`/page${id}`,transform)
}
export async function getPost(id){
if(!id.startWith('/')){
id='/'+id
}
let resp =await get(`/post${id}`,function(data){
return formatPost(data)
})
return resp
}
export async function queryPostsEx({filters,pos,limit,keywords,orders},trandform){
let resp =await query(`/post`,{
filters,
pos,
limit,
keywords,
orders,
},transform)
return resp || []
}
下面这段代码的作用是查询文章列表,并对返回的结果进行一些处理操作,包括筛选条件的设置和结果数据的格式化处理
export async function queryPosts({categoryId,categoryPath,tags,pos,limit,keywords,orders}){
let filters=[{ name:'categoryId',op:'=',value:categoryId}]
if(categoryPath) {
filters.push({name:'categoryPath',op:'=',value:categoryPath})
}
if(tags){
filters.push({name:'tags's,op:'like',value:tags})
}
return await queryPostEx({filters,pos,limit,keywords,orders},function(data) {
data.items=(data.items || []).map(item =formatPost(item))
data.relations=(data.relations || []).map(item=>formatPost(item))
data.suggestions=(data.suggestions || []).map(item => formatPost(item))
return data
})
}
代码解析:
这段代码定义了一个异步函数 queryPosts,用于查询文章列表。
函数可以接受的一个包含了多个参数的对象作为输入,包括categoryId、categoryPath、tags、pos、limit、keywords和orders
函数内部定义的filters ,用于存储查询条件,初始时,将一个对象添加到filters数组中,该对象表示要查询的文章的categroyId属性等于传入的categroyId值
接下来要判断,是否存在categoryPath 或者tags,如果存在,则将另一个对象添加到filters数组中,表示要查询文章的categoryPath或者tags属性符合传入的categoryPath / tags
最后,返回一个异步函数调用queryPostEx,传入一个包含多个参数的对象,其中包含filters、pos、lmit、keywordshe orders。同时,传入一个回调函数作为第二个参数
这个异步函数调用会等待queryPostEx 函数的返回结果,并将返回结果进行处理,在回调函数中,对返回的数据进行了一些处理操作
将data 的items/relations/suggestions数组中的每个元素都应用formatPost函数进行处理,事后将处理的data对象作为函数的返回值