专做品牌的网站,品牌网站建设的作用,学会网站建设的重要性,wordpress 双栏主题文章目录 前言一、导航功能实现a.效果图#xff1a;b.后端代码c.前端代码 二、轮播图功能实现a.效果图b.后端代码c.前端代码 三、标签栏功能实现a.效果图b.后端代码c.前端代码 四、侧边栏功能实现1.整体效果图2.侧边栏功能实现a.效果图b.后端代码c.前端代码 3.侧边栏展示分类及… 文章目录 前言一、导航功能实现a.效果图b.后端代码c.前端代码 二、轮播图功能实现a.效果图b.后端代码c.前端代码 三、标签栏功能实现a.效果图b.后端代码c.前端代码 四、侧边栏功能实现1.整体效果图2.侧边栏功能实现a.效果图b.后端代码c.前端代码 3.侧边栏展示分类及课程信息功能实现a.效果图b.后端代码c.前端代码 五、分类课程推荐楼层设计功能实现a.效果图b.后端代码c.前端代码 前言 在当今数字化教育浪潮中构建一个高效且用户友好的线上教育平台至关重要。本博客将指导您使用Django作为后端框架结合Vue 3的强大前端能力快速搭建平台首页的核心功能包括导航栏、轮播图、侧边栏、标签栏及分类课程推荐。我们将探讨前后端数据交互、Vue组件化开发等关键技术轻松构建出既美观又实用的线上教育平台。 最终实现效果图如下 一、导航功能实现
a.效果图 b.后端代码 导航表模型类 class NavigationModel(BaseModel):name models.CharField(max_length100)url models.CharField(max_length100)is_url models.BooleanField(defaultFalse)def __str__(self):return self.nameclass Meta:verbose_name 导航表verbose_name_plural 导航表db_table navigation导航表序列化器 class NavigationSerializer(serializers.ModelSerializer):class Meta:model NavigationModelfields (id,name,url,is_url)# fields __all__获取所有头部导航栏信息: class NavigationView(APIView):def get(self, request):nav_list NavigationModel.objects.all()ser NavigationSerializer(nav_list, manyTrue)return Response({code:200, data:ser.data})配置url信息: urlpatterns [path(nav/header/, NavigationView.as_view()),...
]c.前端代码 components/Header.vue: !-- 0.导航栏 --
ul classnavli v-for(item,index) in nav.header_nav_list :keyindexa :hrefitem.url v-ifitem.is_url{{item.name}}/arouter-link :toitem.url v-else{{item.name}}/router-link/li
/ul
script setup
import nav from ../api/nav// 获取顶部导航菜单nav.get_header_nav()
/scriptsrc/api/nav.js: import http from ../http;
import {reactive} from vue;
const nav reactive({header_nav_list: [], // 头部导航列表get_header_nav(){// 获取头部导航菜单http.get(/home/nav/header/).then(response{this.header_nav_list response.data;})},
})
export default nav;二、轮播图功能实现
a.效果图 b.后端代码 轮播图模型类 class BannerModel(BaseModel):image models.CharField(max_length255)link models.CharField(max_length255)is_http models.BooleanField(defaultFalse)def __str__(self):return self.imageclass Meta:verbose_name 轮播图表verbose_name_plural 轮播图表db_table banner轮播图序列化器 class BannerSerializer(serializers.ModelSerializer):class Meta:model BannerModelfields __all__获取轮播图数据 class BannerView(APIView):def get(self, request):banners BannerModel.objects.all()ser BannerSerializer(banners, manyTrue)return Response({code:200, data:ser.data})配置url信息 path(banner/, BannerView.as_view()),c.前端代码 src/components/Banner.vue !-- 焦点图、轮播图--
div classg-banner-content mouseoverstate.current_menu -1el-carousel height382px indicator-positionbottom changehandleCarouselChangeel-carousel-item v-for(item, key) in banner.bannerImg :keykeyimg :srcitem.image alt stylewidth: 100%; height: 100% //el-carousel-item/el-carousel
/divscript setup
import banner from ../api/banner;
banner.get_banner_list();// 轮播图列表 接口数据替换
// http://192.168.56.1:3000/src/assets/img/course1.jpg
const bannerImg reactive([{image: /src/assets/img/course1.jpg,link: ,is_http: false,
}])// 当前轮播 banner背景
const nowBannerImg reactive({ src: bannerImg[0].image });
//轮播切换赋值
const handleCarouselChange (index) {// 更新当前banner图片地址nowBannerImg.src banner.bannerImg[index].image;
};scriptsrc/api/banner.js: import { reactive } from vue;
import http from ../http;
const banner reactive({bannerImg: [], // 轮播广告列表get_banner_list() {// 获取轮播广告列表return http.get(/home/banner/).then(response {// console.log(Bannner---response.data);// console.log(response.data);this.bannerImg response.data.data;// console.log(bannerImg);// console.log(response.data.data);})},
})export default banner;三、标签栏功能实现
a.效果图 b.后端代码 标签表模型类 class DirectionModel(BaseModel):direction models.CharField(max_length255)desc models.CharField(max_length255)icon models.CharField(max_length255)def __str__(self):return self.directionclass Meta:verbose_name 方向表verbose_name_plural 标签表db_table direction标签 / 方向表序列化器 class DirectionSerializer(serializers.ModelSerializer):class Meta:model DirectionModelfields [id,direction,desc,icon]# fields __all__获取所有标签数据 class DirectionView(APIView):def get(self, request):directions DirectionModel.objects.all()ser DirectionSerializer(directions, manyTrue)return Response({code:200, data:ser.data})配置urls path(directions/, DirectionView.as_view()),c.前端代码 src/components/Banner.vue !-- 标签表方向表 --div classsystem-class-showa classshow-box v-for(item, index) in directions.directions_list :keyindexdiv classsystem-class-icon :style{ background-image: url(${item.icon}) }/divdiv classdescribeh4{{ item.direction }}/h4p{{ item.desc }}/p/div/adiv classline/diva classall-btndiv classmini-title体系课/divdiv classmore-btnmore/div/a/divimport directions from ../api/directions;directions.get_directions_list();src/api/directions.js import { reactive } from vue;
import http from ../http;const directions reactive({directions_list: [], // 标签列表get_directions_list() {// 获取标签列表return http.get(/home/directions/).then(response {// console.log(11111111111111);// console.log(directions_list---response.data);// console.log(response.data);this.directions_list response.data.data;// console.log(response.data.data);})},})export default directions;四、侧边栏功能实现
1.整体效果图 2.侧边栏功能实现
a.效果图 b.后端代码 分类表模型类 class CategoryModel(BaseModel):id models.AutoField(primary_keyTrue) # 通常Django会自动为主键添加AutoField这里显式写出也可以name models.CharField(max_length255, uniqueTrue) # 假设分类名最大长度为255个字符parent models.ForeignKey(self, on_deletemodels.CASCADE, nullTrue, blankTrue, related_nameson) # 自关联字段表示父分类recommend models.BooleanField(defaultFalse)def __str__(self):return self.nameclass Meta:verbose_name 分类表verbose_name_plural 分类表db_table category父级分类序列化器、子级分类序列化器 # 子类序列化器---二级分类
class SonCategorySerializer(serializers.ModelSerializer):class Meta:model CategoryModelfields (id, name)# fields __all__# 父类序列化器--一级分类
class CategorySerializer(serializers.ModelSerializer):son SonCategorySerializer(manyTrue, read_onlyTrue)class Meta:model CategoryModelfields __all__# fields (id,name,son)获取父级与子级分类 # 2.获取一、二级分类
class CategoryView(APIView):def get(self, request):# 查询所有一级分类parent is null# query_setcategories CategoryModel.objects.filter(is_delete0,parent__id__isnullTrue) #query_setclist [] #侧边栏 二级分类显示几个for category in categories:# 获取一级下面所有的二级分类操作显示二级分类数据条数sondata category.son.all()[0:2] #query_set# d对二级数据进行序列化操作son SonCategorySerializer(sondata, manyTrue)clist.append({id: category.id, name: category.name, son: son.data})return Response({code:200, data:clist})配置url path(nav/cates/, CategoryView.as_view()), #侧边栏-获取一二级分类 c.前端代码 src/components/Banner.vue !-- 左侧边栏Banner---二级分类 --div classmenuContentdivv-for(item, index) in cates.cates_list:keyindexclassitem:class{ js-menu-item-on: state.current_menu 0 }mouseoverfnMethod(item.id)!-- item.id 一级分类id --span classtitle{{ item.name }}:/spanspan classsub-title v-for(s, index) in item.son :keyindexnbsp;nbsp;{{ s.name }}nbsp;nbsp;/spani classimv2-arrow1_r/i/div/divimport cates from ../api/cates;cates.get_cates_list();
// 定义方法-展示侧边栏所有二级分类以及所有分类下的课程
const fnMethod (cateid) {state.current_menu 0;cates.get_coures_list(cateid);
};src/api/cates.js import http from ../http;
import { reactive } from vue;const cates reactive({cates_list: [], // Banner---两级分类列表get_cates_list() {// 获取两级分类return http.get(/home/nav/cates/).then(response {// console.log(左侧边栏获取两级分类response.data);// console.log(response.data);this.cates_list response.data.data;})},
})
export default cates;3.侧边栏展示分类及课程信息功能实现 点击分类(侧边栏触发)获取此分类下所有的二级分类mouseover以及此分类下推荐的课程 a.效果图 b.后端代码 课程表模型类 class CourseModel(BaseModel):id models.AutoField(primary_keyTrue)name models.CharField(max_length255, uniqueTrue)# parent 指向 Category 分类idparent models.ForeignKey(CategoryModel, on_deletemodels.CASCADE, related_namecourse,verbose_nameparent-父级分类)topid models.IntegerField(verbose_nametopid-顶级分类)recommend models.BooleanField(defaultFalse)picurl models.CharField(max_length100)price models.FloatField()level models.IntegerField(verbose_name1零基础 2中级 3高级)sales models.IntegerField(default0,verbose_name销量)describe models.TextField()def __str__(self):return self.nameclass Meta:verbose_name 课程表verbose_name_plural 课程表db_table course课程序列化器 class CourseSerializer(serializers.ModelSerializer):# teacher TeachersSerializer(manyTrue, read_onlyTrue)# teacher TeachersSerializer()class Meta:model CourseModelfields __all__获取所有分类及其推荐课程 class CategoryCourseView(APIView):def get(self, request):#获取一级分类idcateid request.GET.get(cateid)#根据id查询分类一级分类和二级分类cate CategoryModel.objects.filter(idcateid).first()#通过id查询推荐课程ser CategorySerializer(cate)#返回结果#print(cate.id)courses CourseModel.objects.filter(topidcateid,recommendTrue)#print(courses)cSer CourseSerializer(courses, manyTrue)#print(cSer.data)return Response({code:200, clist:ser.data,courses:cSer.data})配置urls path(nav/catescourses/, CategoryCourseView.as_view()),#侧边栏-传一级分类id-展示子分类及其所有课程c.前端代码 src/components/Banner.vue !-- 侧边栏触发显示分类信息、课程信息 --
div classsubmenu v-ifstate.current_menu 0!-- 1.2.1侧边栏触发显示商品课程二级分类信息 --div classinner-boxh2 classtype{{ cates.cc_list.name }}/h2div classtag clearfix/divdiv classlorespan classtitle知识点/spanp classlores clearfixa target_blank v-for(item, index) in cates.cc_list.son :keyindex href{{ item.name }}/a/p/div/div!-- 1.2.2侧边栏触发显示分类下的课程信息---div classrecomment clearfixa href target_blank title classrecomment-item v-for(c,index) in cates.course_list :keyindexdiv classimg :style{ background-image: url(${c.picurl}), background-size: 100% }/divdiv classdetailsdiv classtitle-boxp classtitlespan classtext{{c.name}}/spanspan classtag tixi体系/span/p/divdiv classbottomspan classdiscount-name优惠价:/spanspan classprice{{c.price}}/span middot;span classdifficulty {{c.describe}} /span middot;span classdifficulty v-ifc.level1 0基础 /span middot;span classdifficulty v-ifc.level2 中级 /span middot;span classdifficulty v-ifc.level3 高级 /span middot;span classnumi classimv2-set-sns/i {{c.sales}}人/span/div/div/a/div/divsrc/api/cates.js import http from ../http;
import { reactive } from vue;const cates reactive({cates_list: [], // Banner---两级分类列表cc_list: {}, //Banner---触发显示显示所有二级分类course_list: [], //Banner ---触发显示显示分类下的课程get_cates_list() {// 获取两级分类return http.get(/home/nav/cates/).then(response {this.cates_list response.data.data;})},get_coures_list(cateid) {// 获取所有二级分类 及其 课程return http.get(/home/nav/catescourses/?cateid cateid).then(response {// console.log(左侧边栏获取课程分类及课程response.data);// console.log(response.data);this.cc_list response.data.clist;this.course_list response.data.courses;})},})export default cates;五、分类课程推荐楼层设计功能实现 首页分类课程推荐设计 显示推荐分类获取不同楼层不同分类下的课程点击不同分类时获取当前楼层分类下的推荐课程并显示 a.效果图 b.后端代码 为了便于理解建立三张表频道表、频道分类表、频道课程表模型类如下 # a.频道表
class ChannelModel(BaseModel):name models.CharField(max_length255, uniqueTrue)picurl models.CharField(max_length100)sort models.IntegerField()def __str__(self):return self.nameclass Meta:verbose_name 频道表verbose_name_plural 频道表db_table channel# b.频道分类表 id,name,显示顺序,频道id,类别(1-添加的 2-分类的),分类id
class ChannelCategoryModel(BaseModel):name models.CharField(max_length255)sort models.IntegerField()channel models.ForeignKey(ChannelModel, on_deletemodels.CASCADE, related_namecates)type models.IntegerField()cateid models.IntegerField()def __str__(self):return self.nameclass Meta:verbose_name 频道分类表verbose_name_plural 频道分类表db_table channel_cates# c.频道分类课程表 id,name,图标,价格,难度,购买人数,频道分类id
class ChannelCoursesModel(BaseModel):name models.CharField(max_length255,uniqueTrue)picurl models.CharField(max_length100)price models.FloatField()sales models.IntegerField(default0)level models.IntegerField()ccates models.ForeignKey(ChannelCategoryModel, on_deletemodels.CASCADE, related_namecourses)def __str__(self):return self.nameclass Meta:verbose_name 频道分类课程表verbose_name_plural 频道分类课程表db_table channel_courses频道、频道分类、频道课程序列化器 # --
# c.频道分类课程序列化器
class ChannelCourseSerializer(serializers.ModelSerializer):class Meta:model ChannelCoursesModelfields __all__# b.频道分类序列化器-
class ChannelCategorySerializer(serializers.ModelSerializer):courses ChannelCourseSerializer(manyTrue, read_onlyTrue)class Meta:model ChannelCategoryModelfields __all__# a.频道序列化器
class ChannelSerializer(serializers.ModelSerializer):cates ChannelCategorySerializer(manyTrue, read_onlyTrue)class Meta:model ChannelModelfields __all__获取首页推荐课程分类信息 # 6.2 楼层-课程卡片--无顺序版--直接嵌套序列化器
class HomeCourseView(APIView):def get(self, request):channels ChannelModel.objects.order_by(sort).all()ser_channels ChannelSerializer(channels, manyTrue)return Response({code:200, data:ser_channels.data})配置urls path(homecourse/, HomeCourseView.as_view()), #首页推荐分类课程c.前端代码 src/components/NewCourse.vue templatediv classbg000div classcontainer-types new-course v-forrecord,index in course.data :keyindex!-- 第一级pic --h3classtypes-title justify-content_flex-start:style{ background-image: url(${record.picurl}) }{{index}}!-- 第二级 eg推荐、前端课程 --ul classmenuli :class{curr: state.current_menu[index]key}v-foritem,key in record.cates :keykeyclickselectTab(item,key,index)a{{ item.name }}/a/li/ul/h3!-- 对应分类下的课程信息 --div classlist clearfix show a classitem v-forcitem,cindex in record.cates[courseList.data[index]].courses :keycindexdiv classimg:style{ background-image: url(${citem.picurl}) }/divdiv classtitle ellipsis2{{ citem.name }}/divdiv classdifficulty{{ citem.level }} · {{ citem.person }}人报名/divdiv classbottom clearfixspan classprice l red bold{{ citem.price }}/span/div/a/div/div /div
/templatescript setup
import {reactive} from vue
// 接口取回的数据
import course from ../api/home;course.get_courses_list();// 定义每个频道TAB的下标
let courseList reactive({data: [0,0,0]})// 点击事件item-cateskey-二级indexindex-一级index
const selectTab (item,key,index) {courseList.data[index] keystate.current_menu[index] key
}
const state reactive({current_menu: [0,0,0],
})/scriptsrc/api/home.js import { reactive } from vue;
import http from ../http;
const course reactive({data: [], // 分类下课程信息get_courses_list() {// 获取分类下课程信息return http.get(/home/homecourse/).then(response {console.log(response.data.data);console.log(response.data.data);this.data response.data.data;},})export default course;