Preface前言:VueCli+Node+mongodb打造个人博客(包括前端展示和后台管理系统)(上)https://segmentfault.com/a/11...github地址:https://github.com/ssevenk/ss...上一篇我们完成了后台的配置,实现了数据的增删改查。现在我们只需要在前端页面向后端发送相应的请求就可以引入axios了。在我们开始构建组件之前,首先要确定前端异步请求方式这里我使用axios先在main.js中importimportaxiosfrom'axios'Vue.prototype.$axios=axios;这样我们就可以直接在自定义组件中使用它。$axios向后台管理系统发起异步请求。这里我把它分为两个组件:管理组件(Manage.vue)和编辑组件(Edit.vue)管理组件(Manage.vue)。该组件的页面展示如图所示。核心部分就是那个窗体,用来展示已有的数据,并对其进行操作。左侧导航分为三类,文章、八卦和收藏夹。当我们点击对应的类别时,我们并不是在切换组件,而是在ManageIn.vue中更新数据,我们定义了一个名为things的空数组来保存当前要显示的数据和一个kind值来保存当前类型的数据被显示。设kind值为blog,默认显示“article”Datadata(){return{kind:"blog",things:[],}组件初始化时,调用生命周期函数created()发起向后端发送相应类型的请求。后端返回相应的数据,存入thingscreated(){this.getData("blog");//第一次默认获取文章的数据},methods:{getData(kind){this.kind=kind;this.$axios.get(`/data/${kind}`).then(res=>{this.things=res.data;})}每次点击左侧导航栏的按钮时,调用getData()一次并传入相应的kind参数用于更新事物,kind用于更新要显示的数据和类型。比如点击杂谈,就会调用getData(essay)数据表。这里我使用了Element-ui组件库来制作表格。基本上,这是一个官方案例。可以看到效果和我的基本一样,所以这部分可以直接参考官网教程https://element.eleme.cn/#/zh...数据绑定的时候,选择我们构建的things数组before:data=‘东西’搜索右上角有一个搜索输入框,输入后可以立即显示搜索结果。在数据表中,一开始我想定义一个新的show数组来存放搜索结果然后给输入框绑定键盘事件调用搜索。功能,后来发现Element官网很简单。可以直接对el-table表绑定的数据做文章:data="((things.filter(data=>!search||data.title.toLowerCase().includes(search.toLowerCase())"搜索是双向绑定输入框数据的,分页数据太多,必须用我们的Element-ui组件库PageSize设置为5,当前默认页为1data(){return{kind:"blog",things:[],currentPage:1,pageSize:5,search:""};}当页码被点击切换时,更新页码handleCurrentChange(currentPage){this.currentPage=currentPage;}然后再次改进我们之前的el-table标签上的数据:data="((things.filter(data=>!ssearch||data.title.toLowerCase().includes(search.toLowerCase())).slice((currentPage-1)*pageSize,currentPage*pageSize)))"这里的逻辑是先把数据整理好再搜索过滤和分页编辑组件(Edit.vue)比显示更重要,或者说是对数据的操作。这里我把新建和编辑功能集成到同一个组件中,因为它们都是使用markdown编辑器写的相同的布局。只是初始化方式、按钮和请求都不一样,关于这个markdown编辑器,我用的是simpleMDE,添加了本地上传图片的功能,请参考我的另一篇文章https://segmentfault.com/a/11...我会的此处不再赘述,样式方面,为了控制页面内编辑器的高度,在编辑器中出现滚动条,而不是在页面中出现。CodeMirror-scroll{min-height:350px;height:350px;}添加这样一个css样式(本来默认800px)来创建或者编辑?在管理组件中,点击新建按钮或者某篇文章的编辑按钮,我们就会进入编辑组件,因为它集成在同一个组件中,所以首先要判断当前是要创建还是编辑,要处理什么样的数据,文章还是八卦还是收藏?创建一个bool值isNew和一个字符串值kind然后在生命周期函数created()created(){this.kind=this.$route.params.kind;if(this.$route.params.id!="new"){this.isNew=false;}},根据Manage组件路由跳转时传入的参数判断vue-router路由跳转,如果对query和params的用法有疑问,可以参考我的文章https://segmentfault.com/a/11...按钮button提供了一个函数,让它计算它应该显示什么文本“:"更新")+"文章";case"essay":return(this.isNew?"Publish":"Update")+"杂谈";case"article":return(this.isNew?"Publish":"更新")+"收藏";默认值:返回“”;}}如果是在mounted()循环函数中编辑,请求后端数据填写markdown编辑器的输入框if(!this.isNew){this.$axios.get(`/data/${this.$route.params.kind}/${this.$route.params.id}`).then(req=>{this.title=req.data.title;this.content=req.data.content;this.comments=req.data.comments;simplemde.value(this.content);});}编辑后向后端发送请求if(!this.isNew){this.$axios.post(`/data/${this.$route.params.kind}/${this.$route.params.id}`,{id:this.$route.params.id,title:this.title,content:this.content})如果是新的,需要给新文章一个创建日期computed:{date:function(){vartime=newDate(this.time);返回`${(time.getMonth()+1).toString().padStart(2,"0")}-${time.getDate().toString().padStart(2,"0")}`;}}为了美观,使用padStart保证个位数的日期也可以输出两位。发布时,将其添加到日期中。$axios.post(`/data/${this.$route.params.kind}/new`,{title:this.title,content:this.content,comments:this.comments,date:this.date})删除数据当点击删除按钮时,会获取对应数据的id值并传给后台,但在此之前,必须使用findIndex和splicedel(delid)找到数据在things中的位置并删除{vardelIndex=this.things.findIndex(item=>{returnitem._id==delid;});this.things.splice(delIndex,1);this.$axios.delete(`/data/${this.kind}/${delid}`);}PS。其实我后来写了一个EditArticle组件来对应“收藏夹”,因为它只需要标题和跳转链接,不需要编辑器,所以单独写了一个。原理类似。我不会在这里详细介绍。完成后台管理系统后,我们就开始制作展示页面。敬请期待后续文章。第三篇已经更新:https://segmentfault.com/a/11...