nuxt.js 也是基于vue 的 那么就离不开组件化开发 我们按照组件结构来进行分析
页面的头部 通用组件 分隔了三个位置 适用于大多数头部 且预留插槽
- <template>
- <div class="nav-top">
- <div class="left">
- <slot name="left">slot>
- div>
- <div class="center">
- <slot name="center">slot>
- div>
- <div class="right">
- <slot name="right">slot>
- div>
- div>
- template>
-
- <script>
- export default {
- name: "Navtop"
- }
- script>
-
- <style scoped>
- .nav-top{
- display: flex;
- line-height: 52px;
- height: 52px;
- overflow: hidden;
- }
-
- .left,.right{
- display: flex;
- width: 16%;
- align-items: center;
- justify-content: center;
- }
-
-
-
- .center{flex: 1}
-
-
- style>
在首页使用
引入:
import navTop from '../components/common/navtop/Navtop'
注册
components:{ navTop, },
使用 左边放logo 中间搜索框 右边放 标识
- <navTop class="navtop">
- <div slot="left">
- <img src="~assets/img/common/logo-bai.png" alt="" class="img1" @click="GoHome">
- div>
- <div slot="center">
- <input type="text" class="input" placeholder="二建优学班" @click="GoSearch">
- div>
- <div slot="right">
- <img src="~assets/img/tabbar/class-bai.svg" alt="" class="img2 svg" @click="GoClass">
- div>
- navTop>
对应的回调 分别跳转到 不同的位置
- methods:{
- GoHome(){
- this.$router.push('/home')
- },
- GoSearch(){
- this.$router.push('/search')
- },
- GoClass(){
- this.$router.push('/class')
- }
- }
首先要安装 对应的依赖包
npm i swiper@4.5.1
npm i vue-awesome-swiper@3.1.3
创建对应的组件:
swiper 的相关配置 v-swiper:mySwiper 绑定到下方 swiperOption当中
轮播图的数据 由外部 组件 props 传进来
图片加载完成后 @onload 发射自定义事件 通知首页 计算图片加载完成后的首页页面长度
- <template>
- <div v-swiper:mySwiper="swiperOption" v-if="csbanner.length">
- <div class="swiper-wrapper">
- <div class="swiper-slide" v-for="banner in csbanner">
- <img :src="banner" @load="homeswiperload()">
- div>
- div>
- <div class="swiper-pagination swiper-pagination-bullets">div>
- div>
- template>
-
-
- <script>
- export default {
- name: "swiper",
- props:{
- csbanner:{
- type:Array,
- default(){
- return[]
- }
- }
- },
- data(){
- return{
- swiperOption:{
- spaceBetween: 0,
- autoplay: {
- delay: 3000,
- disableOnInteraction: false,
- },
- pagination: {
- el: '.swiper-pagination',
- clickable: true,
- },
- speed:700,//切换速度
- loop:true//前后循环
- },
- isload:false,
- }
- },
- methods:{
- homeswiperload(){
- if(!this.isload){
- console.log('首页swiper轮播图加载完成');
- this.$emit('homeswiperload')
- this.isload = true
- }
- }
- }
- }
- script>
-
- <style scoped>
- .swiper-pagination{
- width: 100%;
- bottom: 10px;
- }
- style>
plugin/swiper.js
在这里编辑相关配置 挂载到nuxt.confin.js 的 plugin模块当中
这样写 还有一个作用就是 在ssr渲染中 没有全局this 导致 swiper的相关报错
- import Vue from 'vue'
- if (process.browser) {
- const VueAwesomeSwiper = require("vue-awesome-swiper/dist/ssr");
- Vue.use(VueAwesomeSwiper);
- }
在首页 引入及使用
import homeSwiper from '../components/common/swiper/swiper'components:{ homeSwiper, },
主要就是网络请求相关的 流程 梳理一下:
在nuxt.js 中 asyncData 属于一个生命周期 在此生命周期中请求数据 返回数据不用再赋值到组件的data 中 课直接供模板使用
- async asyncData({$axios}){
- const {data} = await $axios.get('http://www.wsg3096.com/ass/home-data.txt')
- return {homeData:data}
- },
homeIcon
- <template>
- <div class="homeicon">
- <div v-for="n in cicons">
- <a :href="n.url">
- <img :src="n.img" alt="">
- <div>{{n.title}}div>
- a>
- div>
- div>
- template>
-
- <script>
-
- export default {
- name: "Home-icon",
- props:{
- cicons:{
- type:Array,
- default(){
- return[]
- }
- }
- }
- }
- script>
-
- <style scoped>
- .homeicon{
- display: flex;
- justify-items: center;
- text-align: center;
- padding: 10px 0px;
- background: #fff;
- box-shadow: 1px 8px 8px rgba(155,155,155,0);
- }
-
- .homeicon img{
- width: 48px
- }
-
- .homeicon div{
- width: 100%;
- text-align: center;
- cursor: pointer;
- font-size: 14px}
- style>
homeRecommend
- <template>
- <div class="recommend">
- <div class="tuijian-bt">
- {{caws.boxBy1}}
- <a href="https://m.zhongxin5.cn/Live/Index?classId=0&teacherId=0&isback=2" target="_blank">
- <span>更多>span>
- a>
- div>
- <div class="tuijian" v-for="w in chotclass.slice(0,4)">
- <a :href="w.link">
- <img :src="w.img" alt="">
- <div class="right">
- <span class="tuijian-name">{{caws.erjian}} - {{w.tit2}}<br>{{w.tit3}}span>
- <span class="tuijian-price">
- <i>¥i>{{w.price}}<i class="line-c">¥{{w.lastprice}}i>
- span>
- div>
- a>
- <div class="clear-fix">div>
- div>
- div>
- template>
-
- <script>
-
- export default {
- name: "Home-recommend",
- props:{
- caws:{
- type:Object,
- default() {
- return {}
- }
- },
- chotclass:{
- type:Array,
- default() {
- return []
- }
- }
- },
- methods:{
-
- }
- }
- script>
-
- <style scoped>
- .tuijian{
- padding: 12px 10px;
- background: #fff;
- margin: 0px 16px;
- border-bottom: 1px solid #f8e8e8;
- }
-
- .tuijian-bt{
- font-size: 20px;
- font-weight: bold;
- line-height: 3;
- margin: 0px 18px;
- display: flex;
- justify-content: space-between;
- align-items: center;
- color: #f35;
- }
-
- .tuijian-bt span{
- font-size: 15px;
- font-weight: 400;
- color: #666;
- }
-
-
- .tuijian img{
- width: 45%;
- float: left;
- border-radius: 10px;
- }
-
- .tuijian-price i{
- font-style: normal;
- font-size: 16px;
- font-weight: 400;
- }
-
- .tuijian-price{
- font-size: 20px;
- font-weight: 600;
- color: #fc3f1d;
- margin-top: 8px;
- }
-
- .right{
- width: 55%;
- padding-left: 8px;
- }
-
- .tuijian-name{
- font-size: 16px;
- line-height: 1.6;
- white-space: nowrap;
- }
-
- .line-c{
- text-decoration: line-through;
- margin-left: 8px;
- color: #666;
- }
-
- .right span{
- display: block;
- }
-
- style>