本文已参与「新人创作礼」活动, 一起开启掘金创作之路。
一、前言
本篇主要介绍如何使用nuxt + swiper实现官网的上下翻页效果以及通过菜单跳转对应滚动画面,并进行组件封装,以后开发类似的网站就可以只填充其中页面组件了。
关键技术: nuxt2 、 swiper5.4、vue-awesome-swiper4.1.1
二、实现方式
1.创建nuxt项目
确保安装了 npx(npx 在 NPM 版本 5.2.0 默认安装了):
npx create-nuxt-app <项目名>
// or
yarn create nuxt-app <项目名>
创建过程会有选择UI框架、集成的服务器端框架等选择,我基本都是一路回车,敲过来的。
之后我们启动项目,如图所示
之后我们先将页面结构调整成我们需要的上下翻页的结构样式。
具体项目目录如下
这里我们将项目页面分成了两部分,第一部分是页面的header头部,用于放标题和菜单;第二部分是主体内容页面,可翻页显示。咱们今天主要讲翻页部分内容。
2.上下翻页效果的实现
首先我们先引入swiper
yarn add swiper@5.4
yarn add vue-awesome-swiper@4.1.1
之后我们还要在 plugins 文件夹下,添加swiper.js文件,文件内容如下
import Vue from 'vue'
import VueAwesomeSwiper from 'vue-awesome-swiper'
Vue.use(VueAwesomeSwiper)
因为引入了插件,我们还需要在nuxt.config.js文件中进行如下配置
css: [
'vant/lib/index.css',
'swiper/css/swiper.css' // 加入swiper样式
],
plugins: [
'@/plugins/vant',
{src: "@/plugins/swiper", ssr: false} // 组件这里配置下swiper插件
],
然后就可以去上面说的第二部分主体,搭建翻页主体了。
这里我们先创建我们需要的数据在vuex中,首先我们如果要实现指定页面的滚动,我们需要一个当前页面的变量,另外我们说要做一个封装,所以有多少个页面我们也不知道,所以我们需要动态计算出有多少个页面,就需要一个变量承载有多少个页面。所以store中的数据声明如下
// store/index.js
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
export const state = () => ({
activePage: '',
menuList: []
})
const mutations = {
changeActivePage(state, option) {
console.log('changeActivePage===', state, option)
state.activePage = option
},
setMenuList(state, option) {
console.log('setMenuList=====', state, option)
state.menuList = option
}
}
export default {
state,
mutations
}
那我们应该怎么去计算有多少个页面呢?首先要把这些页面放到一个地方统一管理,我们将页面放到component/swiperPage这个文件夹下面,之后在项目初始画的时候去动态计算有多少个组件。 代码如下
// pages/index.vue
<template>
<div class="main-content">
<PageHeader />
<MainWrapper/>
</div>
</template>
<script>
// 自动创建组件
import '../plugins/autoCreateCom'
import { mapMutations } from 'vuex'
export default {
name: 'IndexPage',
mounted () {
// 这里计算出有多少个页面,并组织称咱们需要的格式 -- start --
let files = require.context('../components/swiperPage', true, /\.vue$/);
let list = [], components = {};
files.keys().forEach((key) => {
const component = files(key).default;
components[component.name] = component;
list.push({ name: component.desc, value: component.name })
});
// 这里计算出有多少个页面,并组织称咱们需要的格式 -- end --
// 将值存入到vuex的中
this.setMenuList(list)
},
methods: {
...mapMutations(['setMenuList']),
}
}
</script>
<style lang="less" scoped>
.main-content {
width: 100%;
height: 100%;
position: relative;
}
</style>
这里要说明一下,因为在nuxt项目中,component文件中的一级文件会自动声明为全局组件,但是在其之下的文件夹中,就不会自动声明了, 这里咱们需要手动声明。
// /plugins/autoCreateCom.js
import Vue from 'vue';
const components = {};
let files = require.context('../components/swiperPage', true, /\.vue$/);
files.keys().forEach((key) => {
const component = files(key).default;
components[component.name] = component;
});
Object.keys(components).forEach((key) => Vue.component(key, components[key]));
创建好声明文件后,在入口文件中引入一下,如上代码
然后我们就可以搭建页面了,内容如下点击查看swiper参数配置
// MainWrapper.vue
<template>
<div class="main-wrapper">
<client-only>
<swiper :options="swiperOption" ref="mySwiper" class="swiper">
<swiper-slide :key="banner.value" v-for="banner in menuList">
<component :is="banner.value" />
</swiper-slide>
<div class="swiper-scrollbar"></div>
</swiper>
</client-only>
</div>
</template>
<script>
import { mapState, mapMutations } from 'vuex'
export default {
name: 'MainWrapper',
data() {
return {
// swiper的选项配置
swiperOption: {
centeredSlides: false,
spaceBetween: 0,
grabCursor: true,
autoplay: false, // 是否自动打开
loop: false, // 关闭无限循环
slidesPerView: 1,
direction : 'vertical', // 滑动方向
navigation: {
nextEl: '.swiper-button-next',
prevEl: '.swiper-button-prev'
},
mousewheel: true, // 支持滚轮翻页
mousewheel: {
sensitivity : 0.2,
}
}
};
},
computed: {
// 这里我们将当前在那个页面activePage、页面list存到了vuex中
...mapState(['activePage', 'menuList']),
swiper() { // swiper实例
return this.$refs.mySwiper.$swiper
}
},
watch: {
activePage (val) { // 监听当前页面变化,若有变化,将当前页面替换至对应index
let index = this.menuList.findIndex(item => item.value === val)
this.swiper.slideTo(index)
}
}
}
</script>
<style lang="less" scoped>
.main-wrapper {
position: relative;
width: 100%;
height: 100%;
z-index: 10;
}
.swiper {
width: 100%;
height: 100%;
.swiper-slide {
font-size: 18px;
background: #fff;
display: flex;
justify-content: center;
align-items: center;
}
}
</style>
之后我们就在创建好每一页的文件就好啦,就可以上下翻动了
3.点击菜单翻动到对应页面
这部分菜单我们一般放在头部,点击后从左侧弹出,代码如下
// PageHeader.vue
<template>
<div class="page-header">
<div class="logo">
<img src="~/assets/images/shout.svg" alt="">
</div>
<div class="menu-tablet">
<div v-for="item in menuList" :key="item.value" @click="clickSearch(item.value)" style="cursor: pointer;">
{{item.name}}
</div>
</div>
<div class="menu-mobile" @click="show = true">
menu
</div>
<van-popup v-model="show" position="right" class="vanPop">
<ul class="right-nav">
<li v-for="item in menuList" :key="item.value" @click="clickSearch(item.value)">
{{item.name}}
</li>
</ul>
</van-popup>
</div>
</template>
<script>
import { mapState, mapMutations } from 'vuex'
export default {
name: 'PageHeader',
data () {
return {
show: false
}
},
computed: {
...mapState(['menuList']),
},
methods: {
...mapMutations(['changeActivePage']),
// 这里出发点击事件,修改对应的ActivePage
clickSearch(value) {
this.changeActivePage(value)
this.show = false
},
},
mounted () {
}
}
</script>
<style lang="less" scoped>
.page-header {
position: absolute;
top: 0;
left: 0;
width: 100%;
padding: 0 12px;
height: 56px;
display: flex;
justify-content: space-between;
align-items: center;
font-size: 12px;
z-index: 11;
box-sizing: border-box;
background: #3a4c80;
color: #fff;
}
.vanPop {
width: 120px;
height: 100%;
background: #3a4c80;
color: #fff;
transition: all .5s;
}
.right-nav {
width: 100%;
height: 100%;
padding-top: 24px;
box-sizing: border-box;
li {
width: 100%;
height: 75px;
line-height: 75px;
font-size: 14px;
padding-left: 12px;
box-sizing: border-box;
border-bottom: 1px solid hsla(0,0%,100%,.2);
cursor: pointer;
}
}
.menu-tablet {
display: flex;
width: 50%;
justify-content: space-around;
}
@media screen and (max-width: 1180px) {
.page-header .menu-tablet.dark {
color: #595758;
}
.menu-mobile {
display: none;
}
}
@media screen and (max-width: 1440px){
.page-header .menu-tablet.dark {
color: #595758;
}
.menu-mobile {
display: none;
}
}
@media screen and (max-width: 688px) {
.page-header .menu-tablet {
display: none;
}
.menu-mobile {
display: block;
}
}
</style>
以上我们就实现了对nuxt + swiper官网上下翻页效果及菜单跳转封装。
三、后记
做这个主要是为了以后遇到类似的官网项目可以直接复用源码仓库。
本篇完结! 撒花! 感谢观看! 希望能帮助到你!