Vue+ElementUI搭建商铺管理后台项目概要
时间:2023-04-05 17:54:58
HTML5
背景在开发了商铺客户端后,掌握了客户端的一些开发技术,并从中积累了项目经验。由于客户端的商户应用页面是基于静态数据渲染的,在实际应用实践中,静态页面数据并不能满足实际应用场景的需求。如果我们要定期更改页面上的内容,对于普通应用程序用户来说并不容易。或许最尴尬的方式是联系应用开发者修改原有的项目内容,但如果想把这种使用需求一劳永逸地交给普通用户,还是使用GUI界面操作更为方便。在开发和管理后台项目的同时,还可以掌握Vue+ElementUI的技术栈组合项目介绍本项目以Vue+ElementUI为核心技术开发,所有功能均由个人独立开发。本项目主要功能是管理客户端项目http://123.57.204.48:5000的数据,包括各页面数据的增删改查,以及首页数据的可视化展示的应用程序。您也可以将本项目作为模板进行二次开发。本项目的UI和功能实现可以作为参考。欢迎有兴趣进一步交流的同学在项目仓库提issue,欢迎大家收藏关注,谢谢!仓库地址:https://github.com/konglingwe...在线地址:http://123.57.204.48:5000/admin部分应用页面截图店铺配置页面产品管理页面产品编辑页面应用开发技术核心技术架构:Vue@2.6.X+Element-ui@2.12.X依赖包:vue-routerv-charts(基于echarts包的vue组件库)axios(http请求工具)构建工具:vue-cliless部署运行:github-动作云服务器开发过程中的案例介绍由于本应用使用场景广泛,相关业务场景的实现过程在此不再介绍。项目开发完成后,总结了几种常见场景下的技术实现,在此分享。如果遇到一类功能需求,可以参考下面的功能实现二次打包uplod上传组件组件源码地址:https://github.com/konglingwe...我们在大多数应用中都会遇到这样的需求.,从本地电脑上传一张或多张图片到网站,将上传的内容作为网站需要为我们展示的内容。在开发这个功能的时候,对于习惯了element-ui中上传组件的我来说,对于上传一张或者多张图片的业务处理,我们也可以自定义封装上传组件。这样细粒度的处理方便,更符合我们的业务需求。最常用的是嵌入在表单中的图片上传功能。除了输入框等类型的表单可以处理v-model形式的数据外,还可以使用upload,大大方便了提交表单时的数据。过程。首先为上传组件定义这样的道具。props:{value:[String,Array],multipart:{type:Boolean,default:false}},看过vue官方文档中自定义v-model指令的基本介绍的都知道,value属性是用来接收componentsv-model指令的绑定值通过输入事件在组件中对应发出,传入的参数会自动更新为指令绑定的值。另一个多部分属性指示组件一次可以上传的文件数。有了这两个props,我们就有了一个大致实现整个组件功能的思路。接下来,可以根据这两个属性实现触发输入事件的功能。所有原生el-upload上文件更新的事件监听器,根据multipart属性的值,这里以on-success事件为例进行这种处理。//这里只是部分代码handlerSuccess(res,file,fileList){if(!this.multipart){if(fileList.length>1){fileList.shift();}}常量值=this.multipart?文件列表。map(item=>{return(item.response&&item.response.path)||item.url;}):res.path;this.$emit("input",value);}至此动态更新组件v-模型指令绑定值的逻辑就完成了。但是,经过我的测试,发现还有一个组件初始化过程需要处理,即组件绑定的file-list字段的初始化过程。首先,我们需要在组件中定义一个fileList变量data(){return{fileList:[]}}。使用这个fileList变量,我们可以初始化基本上传组件的数据。具体的绑定过程这里就不演示了。详情操作可以查看官方组件使用情况。但是经过测试,这里还是有问题。我们在表单中调用这个组件时,v-model绑定的值,大部分都是通过API请求的方式异步获取的。当请求完成后,通过v-model指令传入的值并不能实时同步到变量fileList中,那么如何解决这个问题呢?想了想,想到了vue提供的$watchAPI。我们可以通过观察组件的value属性来解决这个问题。//这里我们只需要在组件创建的时候观察一次`value`属性值的变化created(){constunwatch=this.$watch("value",newVal=>{this.fileList=Array(this.newVal).flat().map(item=>({name:"",url:newVal}));unwatch&&unwatch();});}:::^Remark组件源码:https://github.com/konglingwe...:::现在去测试组件,发现页面选项可以完美运行卡片视图切换渲染源码https://github.com/konglingwe...Tab视图是一种类似于浏览器页面浏览的操作方式,通过点击tabs来切换页面。我们可以在这里查看点击的页面,点击关闭按钮可以关闭对应的标签页。tab组件本身的功能很简单,这里就不详细介绍了。下面主要讲一下如何实现点击页面后的交互效果。既然有了标签页,我们需要的是让浏览过的页面保持有状态,下次切换回来时保持离开页面时的状态。说到这里,我们很容易想到vue本身提供的keep-alive组件。通过用这个组件包装我们动态切换的路由组件,我们可以缓存项目渲染的组件。keep-alive的具体使用就不多说了。详情请参考官方文档。为了存储标签页和缓存组件的数据,我们需要定义两个数组类型的变量,通过对这两个数组进行操作和处理来实现具体的功能。/*tab-标签组件使用说明title:HTML原生属性Stringclick:监听标签点击事件Functionclose:监听标签关闭事件Functionclosable:是否可以关闭Booleanactive:布尔标签当前是否激活///Only相关的代码片段显示在这里for="(tag,index)intags":key="index":closable="!tag.isHome":active="$route.path===tag.path":style="{width:`${100/maxTags}%`}">{{tag.label}}
data(){return{maxTags:7,//最大标签存储标签数:[{label:"Home",//标签内容名称:"seller-dashboard",//页面路由路径对应的name:"/seller/dashboard",//页面路由对应的路径为Home:true}],//Tab初始化数据cacheViews:[]//缓存的页面组件,手动存储在组件中声明的`name`值};有了上面数据函数中定义的变量,我们只需要实现页面交互的功能即可。每个页面切换应该如何存储?针对这个问题,我们需要实时观察路由实例对象的变化,然后通过操作tags和cacheViewswatch这两个变量来实现我们的需求:{$route(newRoute){constindex=this.tags.findIndex(item=>item.path===newRoute.path);if(index===-1){if(this.tags.length>=this.maxTags){this.tags.splice(1,1);}if(!this.cacheViews.includes(this.$route.name)){this.cacheViews.push(this.$route.name);}this.tags.push({label:newRoute.meta.breadcrumbMenus[newRoute.meta.breadcrumbMenus.length-1],path:newRoute.path,name:newRoute.name});//`meta.breadcrumbMenus`是我设置的数据结构,用于显示对应页面的面包屑菜单。您还可以自定义自己的“标签”字段。}}},在存储路由缓存和tab标签时需要注意。我默认保持设置的页面名称和路由名称一致。也可以根据自己的需要灵活控制,但是一定要保证cacheViews数组有一定的存储。是页面组件中定义的name值,keep-alive组件在缓存时也是需要的,否则动态组件不会被它缓存。实现了缓存页面组件和存储tab标签的功能后,对于tab标签的切换和关闭功能就很简单了,分别监听tab标签的点击和关闭事件来处理相应的逻辑方法:{closeTag(tag,index){this.tags.splice(index,1);constisActive=this.$route.path===tag.path;this.cacheViews.splice(this.cacheViews.indexOf(tag.name),1);如果(isActive&&!tag.isHome){this.$router.push(this.tags[this.tags.length-1].path);}},toggleTag(tag,index){if(tag.path===this.$route.path){返回;}this.$router.push(tag.path);至此,整个tabview的功能就完成了。以上介绍是我自己项目的实现方法。有些代码还没有被推广。这个功能还有待优化。后续我会在完成后及时更新。当遇到有类似需求的场景开发时,可以参考这个实现方法。欢迎在评论区指点指点!参考:https://juejin.cn/post/684490...项目中使用的技术魔法分享Vue的计算属性我们都知道vue的计算属性在项目开发中无处不在,但是用的最多的是这个属性的getter函数,对computed属性有深入了解的同学肯定知道他有一个setter函数供我们使用,但是往往很多人不知道它的应用场景在哪里,包括我自己在开发的时候在发布这个项目之前,我对这个setter的使用场景知之甚少。先介绍一下计算属性整个语法的写法。//这里我们以`formType`属性为例computed:{formType:{set(val){this.form.type=val===""?-1:瓦尔;},get(){返回this.form.type===-1?"":this.form.type;}}代码中的formType属性是一个具有getter和setter的Computed属性。它的作用更像是js中的Object.defineProperty方法,通过拦截某个对象属性的读取来完成一些特定的逻辑。可以看出是对formType属性的读取操作触发了对另一条数据的读取,这里引入form.type的属性值。了解了它的基本用法之后,我们需要进一步应用它`form`对象的属性值}}从代码逻辑不难看出,将两段代码结合起来,完成了formType和form.type在'的两个值上的特殊对应关系'和-1。那么这种特殊的一对一数据转换对应关系适合用在什么地方呢?这里我用一张动态截图来展示一下。让我先解释一下。表单中的鼠标操作选择框我使用的是element-uiselect类型的选择框。选择框的表单项绑定的值为formType组件html
jspartdata(){return{options:[{value:0,label:"全减"},{value:1,label:"折扣"},{value:2,label:"特价"},{value:3,label:"支持发票"},{value:4,label:"TakeoutGuarantee"}],}}从js部分代码可以看出,表单项选择框中渲染的所有数据都是这样的,选择得到的值双向绑定后的框是值字段。因为服务端的一些设计规则返回给前端的是number类型的数据,我们用计算属性处理后的form.type字段的值刚好满足要求。因此,在我编辑完表单后,它的数据类型完全满足了后端的需求,省去了前端提交请求接口时需要重新处理数据结构不一致的问题,同时也加强了响应流程组件数据本身。自动部署本项目使用github-actions提供的集成部署环境,提交更新后本地代码自动部署到云服务器。详细的部署配置文件点这里https://github.com/konglingwe...管理员权限等级管理对于比较大的管理后台系统,会同时分配多个管理员,也会有权限等级的分类这些管理员之间。为了实践这个业务功能,本项目分为super和junior两个级别。线上环境默认登录为初级管理员,在管理员列表中可以看到。不同级别的管理员只能查看同级别或低于自己级别的注册用户,超级管理员可以查看所有用户。如果想以超级管理员身份登录,需要一个配套的后台https://github.com/konglingwe...该项目需要使用node环境初始化自动脚本后才能使用。收获通过这个项目的开发,我在B端应用方面获得了更多的经验和技术收获。通过在实际项目中对Vue及其组件库的不断实践和应用,对前端开发流程和规范有了更深入的了解。多想。以前做一个好的项目,我们考虑的是如何实现需求,如何用更少的代码实现功能。而现在让我开发一个项目,我会更多地思考如何用另一个想法来完成同样的需求。同一个功能需求可能有很多答案。它被用在我见过的一些场景中。如果我能用一句话概括,不同的解决方案具有相同的效果,这也会拓宽我的思路。不仅在技术层面对前端有了更深入的了解,对开发规范也有了更多的了解。比如代码可读性、可维护性、语义变量命名等。以代码可读性为例。这个问题对于多人协作开发的项目来说非常重要。如何根据代码语义让别人快速理解你的项目?多想想这个问题。在解决一个技术问题的时候,最好让代码量多一些,同时也要保证代码的语义和可读性更好。不能追求逻辑代码的简化(学习API和练习demo时可以这样做),这样会损害整个项目。可维护性和代码可读性问题。项目预览在线地址:http://123.57.204.48:5000/adminithub:https://github.com/konglingwe...其他相关项目客户端在线地址:http://123.57.204.48:5000客户端仓库地址:https://github.com/konglingwe...服务器仓库地址:https://github.com/konglingwe...谢谢。如果您对本项目有好的建议,欢迎到仓库提issue,欢迎朋友交流留言,谢谢!感谢所有阅读、点赞和关注的朋友!