Vue实战狗尾草博客管理平台第六章
源码地址:https://github.com/18291907191/gwc_manage
Vue实现狗尾草博客后台管理系统第六章
本章节内容
文章列表
文章详情
草稿箱
文章发布。
本章节内容呢,开发的很是随意哈,因为多数就是element-ui的使用,熟悉的童鞋,是可以很快完成本章节的内容的。
为啥文章模块会有这么多东西呢?
因为狗尾草想着以后,文章如果是待发布的话就需要一个地方去存放起来,一开始删除的文章呢,也将会被移入到草稿箱中,这样的话,文章就不会被随便的更改啦。
文章列表
先给大家一张效果图
是不是感觉非常轻松,一个table就可以搞定,
这里的代码呢,我就直接贴出来,因为没有什么值得注意的地方都是基础。
article>list.vue
<template>
<div class="article-wrap">
<el-table
:data="articleList"
height="100%"
stripe> <el-table-column
prop="id"
align="center"
label="文章编号">
</el-table-column> <el-table-column
prop="create_time"
align="center"
label="创建时间">
<template slot-scope="scope">
{{$moment(scope.row.create_time).format('YYYY-MM-DD HH:mm')}}
</template>
</el-table-column> <el-table-column
prop="tags"
align="center"
label="标签">
<template slot-scope="scope">
{{$utils.formatTableFont(scope.row.tags)}}
</template>
</el-table-column> <el-table-column
prop="title"
align="center"
label="标题">
<template slot-scope="scope">
{{$utils.formatTableFont(scope.row.title)}}
</template>
</el-table-column> <el-table-column
prop="title_image"
align="center"
label="标题图片">
<template slot-scope="scope">
<img v-if="scope.row.title_image" class="title-img" :src="scope.row.title_image" />
<span v-else>-</span>
</template>
</el-table-column> <el-table-column
prop="reader_number"
align="center"
label="阅读数">
<template slot-scope="scope">
{{$utils.formatTableData(scope.row.reader_number)}}
</template>
</el-table-column> <el-table-column
prop="good_number"
align="center"
label="点赞数">
<template slot-scope="scope">
{{$utils.formatTableData(scope.row.good_number)}}
</template>
</el-table-column> <el-table-column
label="操作"
align="center"
fixed="right">
<template slot-scope="scope">
<el-button size="mini" @click.stop="$router.push({path:'/article/detail',query:{articleId:scope.row.id,status:1}})">编辑</el-button>
</template>
</el-table-column>
</el-table>
</div>
</template>
<script>
export default {
data() {
return {
articleList: [],
params: {
searchParams: '',
page: ,
size: ,
status:
},
}
},
methods: {
// 获取文章列表
async getArticleList() {
try {
const { articleData } = await this.$http.getRequest('/article/api/v1/article_list',this.params);
this.articleList = articleData;
} catch(err) {
throw new Error('获取文章列表失败',err);
}
}
},
mounted() {
this.getArticleList();
}
}
</script>
<style lang="less" scoped>
.article-wrap {
height: %;
overflow: hidden;
/deep/.title-img {
width: 90px;
height: 90px;
}
}
</style>
这里呢,接口呢,都已经完成了。这类先不做说明,后面会单独将node.js抽离出来的哈。
不过呢,这里的formatTableData方法呢,是因为我们在做表格数据显示的时候呢,会有没有数据的情景,所以这里。我封装了一个方法,专门的针对表格的数据进行一个处理,在没有数据的时候呢就显示'-',如果是数字类型的呢,这里就显示0
给大家把方法贴出来,至于如果把方法挂在到全局,前面有讲到啦。这里也不需要这样做,因为直接方法utils文件中,utils挂载到全局,是可以直接使用的了。
utils>plugins.js
import * as http from './http';
import VueCookies from 'vue-cookies'
import moment from 'moment';
import utils from './plugins'; const install = (Vue, opts = {}) => {
if (install.installed) return;
Vue.prototype.$http = http;
Vue.prototype.$cookies = VueCookies;
Vue.prototype.$moment = moment;
Vue.prototype.$utils = utils;
} export default install
utils>index.js
/**
* @description 封装的工具类
* @author chaizhiyang
*/
class Util {
/**
* 保留小数点后两位
* @param {Number} data 需要处理的数值
* @return {Number} 保留两位小数的数值
* @author Czy 2018-10-25
*/
returnFloat(data) {
return data.toFixed()
} //el-table表格数据的处理
formatTableFont(val) {
//格式化数据,为空或0或null时,显示无
let formatTableData;
if (!val) {
formatTableData = "-";
} else {
formatTableData = val;
}
return formatTableData;
}; //el-table表格数据的处理
formatTableData(val) {
//格式化数据,为空或0或null时,显示无
let formatTableData;
if (!val) {
formatTableData = "";
} else {
formatTableData = val;
}
return formatTableData;
}; // 返回性别
sexStatus(status) {
if (!status) return
switch (status) {
case :
return '男';
break;
case :
return '女';
break;
default:
return '未知';
break;
}
} /**
* 正则验证
* @param {Number,String} str 需要验证的内容如:手机号,邮箱等
* @param {String} type 需要正则验证的类型
* @return {Boolean} true: 正则通过,输入无误。false: 正则验证失败,输入有误
* @author Czy 2018-10-25
*/
checkStr(str, type) {
switch (type) {
case 'phone': //手机号码
return /^[||||][-]{}$/.test(str);
case 'tel': //座机
return /^(\d{,}-\d{,})(-\d{,})?$/.test(str);
case 'card': //身份证
return /^\d{}|\d{}$/.test(str);
case 'account': //账号 ,长度4~16之间,只能包含数字,中文,字母和下划线
return /^(\w|[\u4E00-\u9FA5])*$/.test(str);
case 'pwd': //密码以字母开头,长度在6~18之间,只能包含字母、数字和下划线
return /^[a-zA-Z]\w{,}$/.test(str);
case 'postal': //邮政编码
return /[-]\d{}(?!\d)/.test(str);
case 'QQ': //QQ号
return /^[-][-]{,}$/.test(str);
case 'email': //邮箱
return /^[\w-]+(\.[\w-]+)*@[\w-]+(\.[\w-]+)+$/.test(str);
case 'money': //金额(小数点2位)
return /^\d*(?:\.\d{,})?$/.test(str);
case 'URL': //网址
return /(http|ftp|https):\/\/[\w\-_]+(\.[\w\-_]+)+([\w\-\.,@?^=%&:/~\+#]*[\w\-\@?^=%&/~\+#])?/.test(str);
case 'IP': //IP
return /((?:(?:[-]|[-]\\d|[]?\\d?\\d)\\.){}(?:[-]|[-]\\d|[]?\\d?\\d))/.test(str);
case 'date': //日期时间
return /^(\d{})\-(\d{})\-(\d{}) (\d{})(?:\:\d{}|:(\d{}):(\d{}))$/.test(str) || /^(\d{})\-(\d{})\-(\d{})$/.test(str);
case 'number': //数字
return /^[-]$/.test(str);
case 'english': //英文
return /^[a-zA-Z]+$/.test(str);
case 'chinese': //中文
return /^[\u4E00-\u9FA5]+$/.test(str);
case 'lower': //小写
return /^[a-z]+$/.test(str);
case 'upper': //大写
return /^[A-Z]+$/.test(str);
case 'HTML': //HTML标记
return /<("[^"]*"|'[^']*'|[^'">])*>/.test(str);
default:
return true;
}
} /**
* 类型判断
* @param {*} o 进行判断的内容
* @return {Boolean} true: 是该类型,false: 不是该类型
* @author Czy 2018-10-25
*/
isString(o) { //是否字符串
return Object.prototype.toString.call(o).slice(, -) === 'String'
} isNumber(o) { //是否数字
return Object.prototype.toString.call(o).slice(, -) === 'Number'
} isObj(o) { //是否对象
return Object.prototype.toString.call(o).slice(, -) === 'Object'
} isArray(o) { //是否数组
return Object.prototype.toString.call(o).slice(, -) === 'Array'
} isDate(o) { //是否时间
return Object.prototype.toString.call(o).slice(, -) === 'Date'
} isBoolean(o) { //是否boolean
return Object.prototype.toString.call(o).slice(, -) === 'Boolean'
} isFunction(o) { //是否函数
return Object.prototype.toString.call(o).slice(, -) === 'Function'
} isNull(o) { //是否为null
return Object.prototype.toString.call(o).slice(, -) === 'Null'
} isUndefined(o) { //是否undefined
return Object.prototype.toString.call(o).slice(, -) === 'Undefined'
} isFalse(o) {
if (o == '' || o == undefined || o == null || o == 'null' || o == 'undefined' || o == || o == false || o == NaN) {
return true
}
return false
} isTrue(o) {
return !this.isFalse(o)
}
} export default new Util();
这里直接挂在到全局。使用方法呢就是this.$utils.func就可以了
文章详情
这里的主要功能呢就是根据id去回显该文章的所有信息,并可以进行修改,删除,移入草稿箱等得操作。这里呢,因为详情和发布是相同的,所以呢,这里也就发一份。当然了就有同学问我,为什么不讲两个页面放到一个页面中呢。
这里给大家解释一下哈:
项目初期往往会比较简单,大多人选择将相同的地方进行封装,给前妻开发带来很大方便,但是项目越往后,会发现,在一个页面反复的添加,修改判断。页面的逻辑处理变得十分复杂,便后悔当初没有还不如分开处理。当然,另一个原因就是,这里路由也做了懒加载,我们在不进入另一个路由的同时呢。他是不会被加载的。性能损耗而言呢,也就是多占了份空间,当然,不要为了封装而封装,不要过度封装。适用才是最合适的!
article>publish
<template>
<section class="wraper">
<el-form ref="form" :model="form" label-width="92px" :rules="rules">
<!--S 标题 -->
<admin-title :title="title.tit1"></admin-title>
<el-form-item label="Article Title" prop="title">
<el-col :span="">
<el-input v-model="form.title"></el-input>
</el-col>
</el-form-item>
<el-form-item label="Title Image" prop="title_image"
>
<el-col :span="">
<el-input v-model="form.title_image"></el-input>
</el-col>
</el-form-item>
<admin-title :title="title.tit2"></admin-title>
<el-form-item label="Article Tags" prop="tags">
<el-col :span="">
<el-select
style="width: 100%;"
v-model="form.tags"
multiple
filterable
allow-create
default-first-option
placeholder="请选择文章标签">
<el-option
v-for="item in tagList"
:key="item.id"
:label="item.tag"
:value="item.id">
</el-option>
</el-select>
</el-col>
</el-form-item>
<admin-title :title="title.tit3"></admin-title>
<el-form-item label="Abstract" prop="describe" align="left">
<textarea class="abstract" v-bind:maxlength="" v-model="form.describe" rows="" cols="" type="text" name="abstract">
</textarea>
<span style="font-size:16px;"><font style="color: #3576e0;">{{ - form.describe.length}}</font>/</span>
</el-form-item>
<el-form-item label="Content" prop="content">
<mavon-editor v-model="form.content"/>
</el-form-item>
<el-form-item align="left">
<el-col>
<el-button type="primary" @click.native="handleSubmit('rules')" :loading="buttonLoading.publishLoading">文章发布</el-button>
<el-button type="primary" @click.native="handleMoveDraft('rules')" :loading="buttonLoading.draftLoading">保存草稿</el-button>
</el-col>
</el-form-item>
</el-form>
</section>
</template>
<script>
import AdminTitle from '@/components/commons/Title'; export default {
components: {
AdminTitle,
},
watch: {
'form.describe'(curVal, oldVal) {
if (curVal.length > this.textNum) {
this.textareaValue = String(curVal).slice(, this.textNum);
}
}
},
data() {
return {
title: {
tit1: '文章标题',
tit2: '文章标签',
tit3: '文章摘要',
}, //标题
form: {
title: '',
tags: [],
title_image: '',
describe: '',
content: '',
status: ,
}, //提交数据
tagList: [], //标签选择器
textNum: ,
previewMarkdown: '<h1>测试</h1>',
buttonLoading: {
publishLoading: false,
draftLoading: false
},
rules: {
title: [
{ required: true, message: '请输入文章标题', trigger: 'blur'}
],
title_img: [
{ required: false, message: '请输入标题图片', trigger: 'blur'}
],
tags: [
{ required: false, message: '请选择文章标签', trigger: 'change'}
],
describe: [
{ required: true, message: '请输入文章摘要', trigger: ['change','blur']}
],
content: [
{ required: true, message: '请输入文章内容', trigger: ['blur','change']}
]
}, // 表单规则校验
}
},
methods: {
//发布文章
async handleSubmit() {
let isOk = this.validata();
if(!isOk) {
return ;
}
this.form.status = ;
this.publishLoading = true;
try {
const result = await this.$http.postRequest('/article/api/v1/article_add',this.form);
this.publishLoading = false;
this.$message({
type: 'success',
message: '文章发布成功!'
})
this.$router.push({
path: '/article/list'
})
} catch(err) {
throw new Error('文章更新失败',err);
this.publishLoading = false;
}
},
// 保存草稿
async handleMoveDraft() {
this.form.status = ;
this.publishLoading = true;
try {
const result = await this.$http.postRequest('/article/api/v1/article_add',this.form);
this.publishLoading = false;
this.$message({
type: 'success',
message: '保存草稿箱成功!'
})
this.$router.push({
path: '/article/draft'
})
} catch(err) {
this.publishLoading = false;
throw new Error('保存草稿失败',err);
}
},
// 表单校验
validata() {
let isForm;
this.$refs.form.validate(valid => {
isForm = valid;
});
if (!isForm) {
return false;
}
return true;
},
// 获取文章所有标签
getTags() {
let hash = {};
let arr = [];
axios.get('/article/api/v1/articleTags')
.then(res => {
arr = res.reduce((item,next) => {
hash[next.tag] ? '' : hash[next.tag] = true && item.push(next);
return item;
},[]);
this.tagList = arr;
})
}
},
}
</script>
<style lang="less" scoped>
.wraper {
width: %;
height: %;
.abstract {
padding: 10px;
font-size: 14px;
}
/deep/.el-form-item__label {
text-align: left;
padding-right: ;
}
} </style>
这里有一个重点,需要大家着重记一下的是,表单的校验,我们在添加好了以后,往往在需要提交的时候去进行判断,将不符合规则的表单给提示出来。不会使用的人,便会去写很多的if判断,this.$message({type:'error',message:'xxx'})的方法给出来,
但是element_ui明明已经给了一个合理的解决方案了。大家就要学会去使用,给我们带来便捷!
// 表单校验
validata() {
let isForm;
this.$refs.form.validate(valid => {
isForm = valid;
});
if (!isForm) {
return false;
}
return true;
},
这块的表单校验,通过给 form表单起一个名称,在提交的时候,调用validate方法就可以方便的达到校验表单的效果。根据返回结果去判断是否继续往下执行就可以啦。get到了有木有。
封装的一个subtitle组件
compoents/commons/Title.vue
<template>
<p class="title">{{title}}</p>
</template> <script>
export default {
name: "AdminTitle",
props: {
title: String
},
data () {
return { };
}
};
</script> <style lang="less">
.title {
display: flex;
align-items: center;
margin: 20px ;
color: #;
position: relative;
&::before {
content: "";
display: inline-block;
position: absolute;
left: -15px;
width: 2px;
height: 13px;
background-color: #3576e0;
border-radius: 1px;
}
}
</style>
这里呢,狗尾草选择使用了<mavon-editor v-model="form.content"/>富文本编辑器,富文本编辑器很多哈。这里就不做特殊说明,有使用遇到坎坷的童鞋呢,可以留言咨询哦。(大家可以查看后期我的react前端文章详情的回显效果)
草稿箱
这里的草稿箱呢,其实表面上看和列表页是一样的。但是呢。文章没有写完的依旧可以放在草稿箱中。待发布的也可以放在草稿箱中,这也就是像个完全不同功能的模块了。
article>draft.vue
<template>
<div class="article-wrap">
<el-table
:data="articleList"
height="100%"
stripe> <el-table-column
prop="id"
align="center"
label="文章编号">
</el-table-column> <el-table-column
prop="create_time"
align="center"
label="创建时间">
<template slot-scope="scope">
{{$moment(scope.row.create_time).format('YYYY-MM-DD HH:mm')}}
</template>
</el-table-column> <el-table-column
prop="tags"
align="center"
label="标签">
<template slot-scope="scope">
{{$utils.formatTableFont(scope.row.tags)}}
</template>
</el-table-column> <el-table-column
prop="title"
align="center"
label="标题">
<template slot-scope="scope">
{{$utils.formatTableFont(scope.row.title)}}
</template>
</el-table-column> <el-table-column
prop="title_image"
align="center"
label="标题图片">
<template slot-scope="scope">
<img v-if="scope.row.title_image" class="title-img" :src="scope.row.title_image" />
<span v-else>-</span>
</template>
</el-table-column> <el-table-column
prop="reader_number"
align="center"
label="阅读数">
<template slot-scope="scope">
{{$utils.formatTableData(scope.row.reader_number)}}
</template>
</el-table-column> <el-table-column
prop="good_number"
align="center"
label="点赞数">
<template slot-scope="scope">
{{$utils.formatTableData(scope.row.good_number)}}
</template>
</el-table-column> <el-table-column
label="操作"
align="center"
fixed="right">
<template slot-scope="scope">
<el-button size="mini" @click.stop="$router.push({path:'/article/detail',query:{articleId:scope.row.id,status:2}})">编辑</el-button>
<el-button size="mini" type="danger" @click.stop="handleDeleteDraft(scope.row.id)">删除</el-button>
</template>
</el-table-column>
</el-table>
</div>
</template>
<script>
export default {
data() {
return {
articleList: [],
params: {
searchParams: '',
page: ,
size: ,
status:
}
}
},
methods: {
//获取文章列表
async getArticleList() {
try {
const { articleData } = await this.$http.getRequest('/article/api/v1/article_list',this.params);
this.articleList = articleData;
} catch(err) {
throw new Error('获取文章列表失败',err);
}
},
handleDeleteDraft(id) {
this.$confirm('此操作将永久删除该文章,不可复原, 是否继续?', '删除提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(async () => {
try {
const result = await this.$http.postRequest('/article/api/v1/article_delete',{ id });
this.$message({
type: 'success',
message: '文章已删除!'
})
this.getArticleList();
} catch(err) {
throw new Error('删除草稿失败',err);
}
this.$message({
type: 'success',
message: '删除成功!'
});
}).catch(() => {
this.$message({
type: 'info',
message: '已取消删除'
});
});
}
},
mounted() {
this.getArticleList();
}
}
</script>
<style lang="less" scoped>
.article-wrap {
height: %;
overflow: hidden;
/deep/.title-img {
width: 90px;
height: 90px;
}
}
</style>
这里给大家理一下这里的思路哈。
文章列表可编辑,编辑时,可选择将文章进行更新发布或者移入草稿箱。发布没有啥说的,移入草稿箱呢,其实也就是将该文章的状态进行更改。
在草稿箱中,主需要根据状态去查询文章即可。 但是草稿箱中的删除操作也就会将文章彻底的删除。
最后呢,附上更改后的路由
router>index.js
import Vue from 'vue'
import Router from 'vue-router'
// import HelloWorld from '@/components/HelloWorld'
Vue.use(Router) const _import = file => () => import('@/pages/' + file + '.vue');
const _import_ = file => () => import('@/components/' + file + '.vue'); const asyncRouterMap = []; const constantRouterMap = [
{
path: '/login',
name: 'Login',
component: _import('login/index'),
},
{
path: '/',
name: '概况',
component: _import_('commons/Layout'),
redirect: '/index',
children: [
{
path: '/index',
name: '总览',
component: _import('home/index'),
meta: {
isAlive: false,
auth: true,
title: '概况数据'
}
}
]
},
{
path: '/article',
name: '文章',
component: _import_('commons/Layout'),
redirect: '/article/publish',
children: [
{
path: '/article/publish',
name: '文章发布',
component: _import('article/publish'),
meta: {
auth: true,
isAlive: true,
isFooter: false,
title: '文章发布'
}
},
{
path: '/article/list',
name: '列表',
component: _import('article/list'),
meta: {
auth: true,
isAlive: false,
isFooter: true,
title: '列表'
}
},
{
path: '/article/draft',
name: '草稿箱',
component: _import('article/draft'),
meta: {
auth: true,
isAlive: false,
isFooter: true,
title: '草稿箱'
}
},
{
path: '/article/detail',
name: '文章详情',
component: _import('article/detail'),
meta: {
auth: true,
isAlive: false,
isFooter: false,
title: '文章详情'
}
}
]
},
{
path: '/404',
name: '',
component: _import('error/index'),
meta: {
title: "请求页面未找到",
auth: false
},
},
{
path: '*',
meta: {
title: "请求页面未找到",
auth: false
},
redirect: '/404'
}
]; const router = new Router({
mode: 'history',
routes: constantRouterMap,
linkActiveClass: "router-link-active",
}); export default router
总结
1.表单提交时的校验。
2.不要为了封装而封装。避免过度封装。适用才是王道。
下一章节
Vuex的进阶使用
Vue实战狗尾草博客管理平台第六章的更多相关文章
- Vue实战狗尾草博客管理平台第四章
本章主要内容如下: 填补上期的坑. iconfont仓库的关联,引入. 开发登录页面 填坑 上期中我们功能都已正常使用.但不知道有没有小伙伴测试过error页面,当访问地址不存在时,路由是否能正常挑战 ...
- Vue实战狗尾草博客管理平台第五章
本章主要内容如下: 静态资源服务器的配置.学会如何使用静态资源服务器引入静态资源.并给大家推荐一个免费可使用的oss服务器~ 页面的开发由于近期做出的更改较大.就放在下一篇中. 静态资源服务器 静态资 ...
- Vue实战狗尾草博客后台管理系统第七章
Vue实战狗尾草博客后台管理平台第七章 本章内容为借助模块化来阐述Vuex的进阶使用. 在复杂项目的架构中,对于数据的处理是一个非常头疼的问题.处理不当,不仅对维护增加相当的工作负担,也给开发增加巨大 ...
- Vue实战狗尾草博客后台管理系统第三章
Vue实现狗尾草博客后台管理系统第三章 本章节,咱们开发管理系统侧边栏及面包屑功能. 先上一张效果图 样式呢,作者前端初审,关于设计上毫无美感可言,大家可根据自己情况设计更好看的哦~ 侧边栏 这里我们 ...
- Vue实战狗尾草博客管理系统第一章
Vue实战狗尾草博客后台管理系统第一章 这里准备采用的技术栈为:vue全家桶+element-ui 这里因为是后台管理系统,没有做SSR的必要.所以这里就采用前后端分离来昨晚这个项目~ 项目搭建 vu ...
- Vue实战狗尾草博客管理系统第二章
伙伴们出来啦,探讨各问题,关于项目中大量的表单,大家是怎么处理的? 本章主要内容如下:底层布局,路由配置,github仓库推送关联. 关联GitHub仓库 关联建立在github已创建账号的基础上 登 ...
- 一个 Vue + Node + MongoDB 博客系统
源码 耗时半载(半个月)的大项目终于完成了.这是一个博客系统,使用 Vue 做前端框架,Node + express 做后端,数据库使用的是 MongoDB.实现了用户注册.用户登录.博客管理(文章的 ...
- 关于vue项目管理项目的架构管理平台
关于vue项目管理项目的架构管理平台 https://panjiachen.github.io/vue-element-admin-site/#/zh-cn/faq 31.4k 次浏览 完整项目地址: ...
- python drf+xadmin+react+dva+react-native+sentry+nginx 搭建前后端分离的博客完整平台
前言: 经过差不多半年的开发,搭建从前端到服务器,实现了前后端分离的一个集PC端.移动端的多端应用,实属不易,今天得空,好好写篇文章,记录这些天的成果.同时也做个分享. 演示网站地址: http:// ...
随机推荐
- execjs使用时异常
一.异常信息(...gbk.....) UnicodeDecodeError: 'gbk' codec can't decode byte 0xa1 in position 26: illegal m ...
- 【Gradle】自定义Android Gradle工程
自定义Android Gradle工程 defaultConfig默认配置 defaultConfig是Android对象中的一个配置项,负责定义所有的默认配置.一个基本的defaultConfig配 ...
- mssql sqlserver 如何编写case when 多条件呢?
摘要: 下文讲述case when中多条件的编写方法,如下所示: 实验环境:sql server 2008 R2 case when 多条件编写方法 case when多条件编写语法: case ...
- Redis—简介与安装
Redis 简介 Redis 安装 Redis 配置文件 # Redis默认不是以守护进程的方式运行,可以通过该配置项修改,使用yes启用守护进程.daemonize yes # 当Redis以守护进 ...
- Linux:Apache服务器的搭建
下载安装并启动apache服务 安装apache服务 yum install -y httpd 启动apache服务 systemctl start httpd.service apache服务器的目 ...
- Druid-代码段-4-1
所属文章:池化技术(一)Druid是如何管理数据库连接的? 本代码段对应主流程4,丢弃连接的守护线程: //连接池瘦身,参考主流程4 public class DestroyConnectionThr ...
- jango rest-framework page_size更新
老项目是三年前写的, 这周的新项目要用上DRF的分页功能时,发现老的写法无效了. 于是看了一些文档,原来写法变了. https://blog.csdn.net/dqchouyang/article/d ...
- Leetcode 1239. 串联字符串的最大长度
地址 https://leetcode-cn.com/problems/maximum-length-of-a-concatenated-string-with-unique-characters/s ...
- 第05组 Alpha事后诸葛亮
组长博客链接(2分) 组长博客链接 现代软件工程 项目Postmortem 模板(27分) 设想和目标(2分) 1.我们的软件要解决什么问题?是否定义得很清楚?是否对典型用户和典型场景有清晰的描述? ...
- 更新GitHub项目出现There is no tracking information for the current branch. Please specify which branch you want to merge with. 怎么解决
git pull命令用于从另一个存储库或本地分支获取并集成(整合).git pull命令的作用是:取回远程主机某个分支的更新,再与本地的指定分支合并,它的完整格式稍稍有点复杂. 如果当前分支只有一个追 ...