Nuxtjs结合Element-ui框架应用项目详细记录---初始/头部组件/尾部组件/轮播图

1,183 阅读3分钟

前期准备:

预计使用到的技术栈:

  • Nuxtjs
  • Vue
  • element
  • vue-router
  • Axios
  • Token
  • Vuex
  • 高德地图

一、修改配置文件

配置文件nuxt.config.js对项目进行了全局配置,对每个页面都生效

import pkg from './package'

export default {
  mode: 'universal',

  /*
  ** Headers of the page
  */
  head: {
    title: "闲云旅游网", // 修改title
    meta: [
      { charset: 'utf-8' },
      { name: 'viewport', content: 'width=device-width, initial-scale=1' },
      { hid: 'description', name: 'description', content: pkg.description }
    ],
    link: [
      { rel: 'icon', type: 'image/x-icon', href: '/favicon.ico' },
      { rel: 'stylesheet', type: 'text/css', href: '//at.alicdn.com/t/font_1168872_ehvuah8v57g.css' } // 新增全局字体样式
    ]
  },

  /*
  ** Customize the progress-bar color
  */
  loading: { color: '#fff' },

  /*
  ** Global CSS
  */
  css: [
    'element-ui/lib/theme-chalk/index.css',
    'assets/main.css' // 新增自定义的页面过渡样式(文件来自3.4.1)
  ],

  /*
  ** Plugins to load before mounting the App
  */
  plugins: [
    '@/plugins/element-ui'
  ],

  /*
  ** Nuxt.js modules
  */
  modules: [
    // https://axios.nuxtjs.org/setup
    '@nuxtjs/axios'
  ],

  /*
  ** Axios module configuration
  */
  axios: {
    // See https://github.com/nuxt-community/axios-module#options
    // baseURL: "http://157.122.54.189:9095" // 新增备用地址
    baseURL: "http://127.0.0.1:1337" // 新增axios默认请求路径 		  
  },

  /*
  ** Build configuration
  */
  build: {
    transpile: [/^element-ui/],

    /*
    ** You can extend webpack config here
    */
    extend(config, ctx) {
    }
  },
}

配置assets/main.css文件,实现页面切换时样式过渡,非必须

/* 页面切换时候过渡样式 */
.page-enter-active,
.page-leave-active {
    transition: opacity .5s;
}

/* 打开时候过渡样式 */
.page-enter,
.page-leave-active {
    opacity: 0;
}

/* 页面顶部页面加载进度条 */
.nuxt-progress {
    background: #409eff;
    height: 1px;
}

二、初始化默认全局布局

  • 普通vue的根实例放在App.vue,里面有<router-view/>是路由映射出口.还有一些全局的css样式等.现在nuxt里面没有App.vue,而是提供了一个layouts/default.vue公共布局组件,该布局组件默认作用于所有页面,相当于App.vue.
  • 里面的<Nuxt/>也是相当于<router-view/>,只不过封装成这个模式.

在这里插入图片描述

根据项目需要初始化样式


<style lang="less">
html {
  font-family: 'Source Sans Pro', -apple-system, BlinkMacSystemFont, 'Segoe UI',
    Roboto, 'Helvetica Neue', Arial, sans-serif;
  font-size: 16px;
  word-spacing: 1px;
  -ms-text-size-adjust: 100%;
  -webkit-text-size-adjust: 100%;
  -moz-osx-font-smoothing: grayscale;
  -webkit-font-smoothing: antialiased;
  box-sizing: border-box;
}

*{
  margin:0; 
  padding:0;
}
ul, li, ol{
  list-style:none;
}
a{
  text-decoration:none;
  color:inherit;
}

em,i{
  font-style: normal;
}
</style>

二、创建公共组建

  1. components文件夹中新建应用统一的头部组件和页脚组件
  2. 在默认布局中layouts/default.vue中导入公共组件
  3. 公共样式可以不引入子文件夹

1.头部组件

  • components/PageHeader.vue
  • <nuxt-link to="/">等同于<router link>
  • 使用element组件的Dropdown 下拉菜单,在右上登录成功时鼠标上移出现下拉效果
<template>
  <header class="header">
    <el-row type="flex" justify="space-between" class="main">
      <!-- logo -->
      <div class="logo">
        <nuxt-link to="/">
          <img src="http://157.122.54.189:9093/images/logo.jpg" alt="" />
        </nuxt-link>
      </div>

      <!-- 菜单栏 -->
      <el-row type="flex" class="navs">
        <nuxt-link to="/">首页</nuxt-link>
        <nuxt-link to="/post">旅游攻略</nuxt-link>
        <nuxt-link to="/hotel">酒店</nuxt-link>
        <nuxt-link to="/air">国内机票</nuxt-link>
      </el-row>

      <!-- 登录/用户信息 -->
      <el-row type="flex" align="middle">
        <!-- 如果用户存在则展示用户信息,用户数据来自store -->
        <el-dropdown v-if="false">
          <el-row type="flex" align="middle" class="el-dropdown-link">
            <nuxt-link to="#">
              <img src="http://157.122.54.189:9093/images/pic_sea.jpeg" />
              用户名
            </nuxt-link>
            <i class="el-icon-caret-bottom el-icon--right"></i>
          </el-row>
          <el-dropdown-menu slot="dropdown">
            <el-dropdown-item>
              <nuxt-link to="#">个人中心</nuxt-link>
            </el-dropdown-item>
            <el-dropdown-item>
              <div @click="handleLogout">退出</div>
            </el-dropdown-item>
          </el-dropdown-menu>
        </el-dropdown>

        <!-- 不存在用户信息展示登录注册链接 -->
        <nuxt-link to="/user/login" class="account-link" v-else>
          登录 / 注册
        </nuxt-link>
      </el-row>
    </el-row>
  </header>
</template>
<script>
export default {
  methods: {
    // 用户退出
    handleLogout() {},
  },
};
</script>
<style scoped lang="less">
.header {
  height: 60px;
  line-height: 60px;
  background: #fff;
  border-bottom: 1px #ddd solid;
  box-shadow: 0 3px 0 #f5f5f5;
  box-sizing: border-box;

  .main {
    width: 1000px;
    margin: 0 auto;
  }

  .logo {
    width: 156px;
    padding-top: 8px;

    img {
      display: block;
      width: 100%;
    }
  }

  .navs {
    margin: 0 20px;
    flex: 1;

    a {
      display: block;
      padding: 0 20px;
      height: 60px;
      box-sizing: border-box;

      &:hover,
      &:focus,
      &:active {
        border-bottom: 5px #409eff solid;
        color: #409eff;
      }
    }

    /deep/ .nuxt-link-exact-active {
      background: #409eff;
      color: #fff !important;
    }
  }

  .message {
    height: 36px;
    line-height: 1;
    cursor: pointer;
    .el-icon-bell {
      margin-right: 2px;
      font-size: 18px;
    }
  }

  .el-dropdown-link {
    margin-left: 20px;

    &:hover {
      img {
        border-color: #409eff;
      }
    }

    a {
      display: block;
    }

    img {
      width: 32px;
      height: 32px;
      vertical-align: middle;
      border: 2px #fff solid;
      border-radius: 50px;
    }
  }

  .account-link {
    font-size: 14px;
    margin-left: 10px;
    color: #666;

    &:hover {
      color: #409eff;
      text-decoration: underline;
    }
  }
}
</style>

2.尾部组件

  • components/PageFooter.vue
<template>
  <div class="footer-wrapper">
    <div class="footer">
      <el-row class="info-list">
        <el-col :span="6" :offset="1">
          <h5>闲云旅游旅游网</h5>
          <p>上亿旅行者共同打造的"旅行神器"</p>
          <p><span>60,000</span> 多个全球旅游目的地</p>
          <p><span>600,000</span> 个细分目的地新玩法</p>
          <p><span>760,000,000</span> 次攻略下载</p>
          <p><span>38,000</span> 家旅游产品供应商</p>
        </el-col>
        <el-col :span="5">
          <h5>关于我们</h5>
          <p>隐私政策 商标声明</p>
          <p>服务协议 游记协议</p>
          <p>商城平台服务协议</p>
          <p>网络信息侵权通知指引</p>
          <p>闲云旅游旅游网服务监督员</p>
          <p>网站地图加入闲云旅游</p>
        </el-col>
        <el-col :span="5">
          <h5>旅行服务</h5>
          <p>旅游攻略 酒店预订</p>
          <p>旅游特价 国际租车</p>
          <p>旅游问答 旅游保险</p>
          <p>旅游指南 订火车票</p>
          <p>旅游资讯 APP下载</p>
        </el-col>
        <el-col :span="6" class="scan">
          <p>
            <img
              src="http://157.122.54.189:9093/images/1556522965.png"
              alt=""
            />
          </p>
          关注我们
        </el-col>
      </el-row>

      <div class="licence">
        京ICP备08001421号 京公网安备110108007702 Copyright © 2016-2019 博学谷
        All Rights Reserved
      </div>
    </div>
  </div>
</template>

<script>
export default {};
</script>

<style scoped lang="less">
.footer-wrapper {
  background: #333;
  color: #ccc;
  min-width: 1000px;
}

.footer {
  padding-top: 30px;
  margin: 0 auto;
  width: 1000px;
}

.info-list {
  h5 {
    font-weight: normal;
    font-size: 16px;
    margin-bottom: 10px;
  }

  p {
    font-size: 12px;
    line-height: 1.8;
    span {
      color: orange;
    }
  }
}

.scan {
  text-align: center;

  img {
    width: 140px;
    height: 140px;
  }

  font-size: 12px;
}

.licence {
  border-top: 1px #666 solid;
  margin-top: 20px;
  padding: 50px 0;
  text-align: center;
  font-size: 12px;
}
</style>

3.头部尾部引入全局

layouts/default.vue引入

<template>
  <div>
    <!-- 步骤三:使用 -->
    <!-- 页头 -->
    <PageHeader />
    <!-- 内容占位组件 -->
    <nuxt />
    <!-- 页尾 -->
    <PageFooter />
  </div>
</template>

<script>
// 步骤一:引入
import PageHeader from "@/components/PageHeader";
import PageFooter from "@/components/PageFooter";
export default {
  components: {
    // 步骤二:注册
    PageHeader,
    PageFooter,
  },
};
</script>

4.轮播图

思路:

  1. 使用Element-ui的幻灯片组件Carousel 走马灯,新增首页轮播图布局。
  2. 请求后端接口渲染图片数据
  • pages/index.vue内容替换成以下代码
<template>
  <div class="container">
    <!-- 幻灯片 -->
    <!-- interval:自动切换图片的时间 -->
    <!-- v-for:循环数据 -->
    <!-- el-carousel-item:一个item就是一个图片 -->
    <el-carousel :interval="3000" arrow="always">
      <el-carousel-item v-for="(item, index) in banners" :key="index">
        <div
          class="banner-image"
          :style="`
                background:url(${$axios.defaults.baseURL}${item.url}) center center no-repeat;
                background-size:contain contain;
                `"
        ></div>
      </el-carousel-item>
    </el-carousel>
    <!-- 下面是搜索框 -->
  </div>
</template>

<script>
export default {
  data() {
    return {
      // 轮播图数据
      banners: [],
    };
  },
  //页面创建时需要获取轮播图数据,created时虽然dow不在,但是拿数据没问题
  // mounted()也可以
  created() {
    this.$axios({
      url: "/scenics/banners",
    }).then((res) => {
      console.log(res.data.data);
      this.banners = res.data.data; //获取数据时赋值给banners数组,用来遍历
      // 解构写法
      // const { data } = res.data;
      // this.banners = data;
    });
  },
};
</script>

<style scoped lang="less">
.container {
  min-width: 1000px;
  margin: 0 auto;
  position: relative;

  /deep/ .el-carousel__container {
    height: 700px;
  }

  .banner-image {
    width: 100%;
    height: 100%;
  }
}
</style>