luffy前端主页搭建
子组件
页头组件components / Header.vue
<template> <div class="header"> <div class="slogan"> <p>老男孩IT教育 | 帮助有志向的年轻人通过努力学习获得体面的工作和生活</p> </div> <div class="nav"> <ul class="left-part"> <li class="logo"> <router-link to="/"> <img src="../assets/img/head-logo.svg" alt=""> </router-link> </li> <li class="ele"> <span @click="goPage('/free-course')" :class="{active: url_path === '/free-course'}">免费课</span> </li> <li class="ele"> <span @click="goPage('/actual-course')" :class="{active: url_path === '/actual-course'}">实战课</span> </li> <li class="ele"> <span @click="goPage('/light-course')" :class="{active: url_path === '/light-course'}">轻课</span> </li> </ul> <div class="right-part"> <div> <span>登录</span> <span class="line">|</span> <span>注册</span> </div> </div> </div> </div> </template> <script> export default { name: "Header", data() { return { // 当前所在路径,去sessionStorage取的,如果取不到,就是 / url_path: sessionStorage.url_path || '/', } }, methods: { goPage(url_path) { // 已经是当前路由就没有必要重新跳转 if (this.url_path !== url_path) { this.$router.push(url_path); } sessionStorage.url_path = url_path; }, }, created() { // 组件加载成功,就取出当前的路径,存到sessionStorage this.$route.path sessionStorage.url_path = this.$route.path; // 把url_path = 当前路径 this.url_path = this.$route.path; } } </script> <style scoped> .header { background-color: white; box-shadow: 0 0 5px 0 #aaa; } .header:after { content: ""; display: block; clear: both; } .slogan { background-color: #eee; height: 40px; } .slogan p { width: 1200px; margin: 0 auto; color: #aaa; font-size: 13px; line-height: 40px; } .nav { background-color: white; user-select: none; width: 1200px; margin: 0 auto; } .nav ul { padding: 15px 0; float: left; } .nav ul:after { clear: both; content: ''; display: block; } .nav ul li { float: left; } .logo { margin-right: 20px; } .ele { margin: 0 20px; } .ele span { display: block; font: 15px/36px '微软雅黑'; border-bottom: 2px solid transparent; cursor: pointer; } .ele span:hover { border-bottom-color: orange; } .ele span.active { color: orange; border-bottom-color: orange; } .right-part { float: right; } .right-part .line { margin: 0 10px; } .right-part span { line-height: 68px; cursor: pointer; } </style>
轮播图组件Banner.vue
<template> <div class="banner"> <el-carousel :interval="5000" arrow="always"> <el-carousel-item v-for="item in img_list" :key="item.id"> <div v-if="item.link.indexOf('http')>-1"> <a :href="item.link"> <img :src="item.image" :alt="item.title"> </a> </div> <div v-else> <router-link :to="item.link"> <img :src="item.image" :alt="item.title"> </router-link> </div> </el-carousel-item> </el-carousel> </div> </template> <script> export default { name:'Banner', data(){ return{ img_list:[] } }, created() { this.$axios.get(this.$settings.BASE_URL+'/home/banner/').then(res=>{ console.log(res.data) if(res.data.code==100){ this.img_list = res.data.result }else { this.$message(res.data.msg) } }).catch(res=>{ this.$message('轮播图服务器异常,请稍后再试') }) } } </script> <style scoped> .el-carousel__item { height: 400px; min-width: 1200px; } .el-carousel__item img { height: 400px; margin-left: calc(50% - 1920px / 2); } </style>
页脚组件:components/Footer.vue
<template> <div class="footer"> <ul> <li>关于我们</li> <li>联系我们</li> <li>商务合作</li> <li>帮助中心</li> <li>意见反馈</li> <li>新手指南</li> </ul> <p>Copyright © luffycity.com版权所有 | 京ICP备17072161号-1</p> </div> </template> <script> export default { name: "Footer" } </script> <style scoped> .footer { width: 100%; height: 128px; background: #25292e; color: #fff; } .footer ul { margin: 0 auto 16px; padding-top: 38px; width: 810px; } .footer ul li { float: left; width: 112px; margin: 0 10px; text-align: center; font-size: 14px; } .footer ul::after { content: ""; display: block; clear: both; } .footer p { text-align: center; font-size: 12px; } </style>
父组件
主页组件:views/Home.vue
<template> <div class="home"> <!--引入Header组件和Banner组件--> <Header></Header> <Banner></Banner> <!--填充页面组件--> <div class="course"> <el-row> <el-col :span="6" v-for="(o, index) in 8" :key="o" class="course_detail"> <el-card :body-style="{ padding: '0px' }"> <img src="http://photo.liuqingzheng.top/2023%2002%2022%2021%2057%2011%20/image-20230222215707795.png" class="image"> <div style="padding: 14px;"> <span>推荐课程</span> <div class="bottom clearfix"> <time class="time">价格:999</time> <el-button type="text" class="button">查看详情</el-button> </div> </div> </el-card> </el-col> </el-row> </div> <!--引入页脚组件--> <Footer></Footer> </div> </template> <script> import Header from "@/components/Header"; import Footer from "@/components/Footer"; import Banner from "@/components/Banner"; export default { name: 'HomeView', components:{ Header, Banner, Footer, } } </script> <style scoped> .time { font-size: 13px; color: #999; } .bottom { margin-top: 13px; line-height: 12px; } .button { padding: 0; float: right; } .image { width: 100%; display: block; } .clearfix:before, .clearfix:after { display: table; content: ""; } .clearfix:after { clear: both } .course_detail { padding: 50px; } </style>
要注意的问题
1. rooter-link只能做内部跳转,如果要跳转到外部链接,需要用a标签
<div v-if="item.link.indexOf('http')>-1"> <a :href="item.link"> <img :src="item.image" :alt="item.title"> </a> </div> <div v-else> <router-link :to="item.link"> <img :src="item.image" :alt="item.title"> </router-link> </div>
2. vue中的.then()与.catch()
.then()
在axios请求完成后执行的下一步操作(异步执行),包括两个参数
axios.post(url, data) .then(res => { console.log(res);//第一个参数:成功后返回结果 }, error => { console.log(error);//第二个参数:请求失败后返回值 })
.catch()
在.then()中代码逻辑出错、请求失败等的回调函数,防止因代码造成程序崩溃,这里的方法类似于try{}.catch(e){},省略了try{}
axios.post(url, data) .then(data => { console.log(data) }) .catch(err => { console.log(err)//代码错误、请求失败捕获 })
总结
catch中获取到的值是请求失败或者代码问题造成的错误,而因代码造成的错误在.then()中获取不到,因此我们常用catch
我们偶尔会遇到一些问题:明明请求成功了,逻辑却进入catch中了,这时说明在then中的处理逻辑可能出现了错误,并不是请求失败才会进入catch。