vue.js

关注公众号 jb51net

关闭
首页 > 网络编程 > JavaScript > javascript类库 > vue.js > Bootstrap+Vue滑动监听Scrollspy

Bootstrap+Vue滑动监听Scrollspy实现餐厅餐品展示

作者:爱学习的小船

本文主要介绍了Bootstrap+Vue滑动监听Scrollspy实现餐厅餐品展示,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧

一、介绍

效果图:

介绍:根据滚动位置自动更新引导导航或列表组组件,以指示视口中当前处于活动状态的链接。

作用:可以用于餐厅点菜的菜品展示页侧边栏、博客系统的侧边栏等,实现流畅的垂直滚动监听

官方网址:Scrollspy | Directives | BootstrapVue (bootstrap-vue.org)

在本文中,主要在官方文档的基础上,提供两种呈现数据的方式,

将数据放在data中,在div中进行加载

获取后端的传过来的数据,存入data,再进行加载

二、环境准备

需要提前安装好node.js,我使用的是vue2, bootstrap-vue"版本:2.23.1,

使用npm或yarn 安装 bootstrap-vue

// 两种方式选一个
npm install vue bootstrap bootstrap-vue 
yarn add vue bootstrap bootstrap-vue

在应用入口注册BootstrapVue,(通常是app.js 或 main.js)

import Vue from 'vue'
import { BootstrapVue, IconsPlugin } from 'bootstrap-vue'
 
// Import Bootstrap and BootstrapVue CSS files (order is important)
import 'bootstrap/dist/css/bootstrap.css'
import 'bootstrap-vue/dist/bootstrap-vue.css'
 
// Make BootstrapVue available throughout your project
Vue.use(BootstrapVue)
// Optionally install the BootstrapVue icon components plugin
Vue.use(IconsPlugin)

其他需要的东西,例如前后端交互需要的axios等等

三、<template>部分

这里以列表组为例,并且用 v-for 循环 生成每一个item,每个item都是一个card,card中存放餐品信息。总体代码如下:

<template>
  <div>
    <b-container fluid id="menu">
      <b-row>
        <b-col cols="3"> <!--这里代表 左边 导航栏占几个格,总共12格-->
          <div id="list-nav" style="width: 100%; height: 800px">
 
            <!--b-list-group 中存左侧导航栏的菜品类别  -->
            <!-- v-b-scrollspy:listgroup-ex 绑定需要被监听的容器,即id为 listgroup-ex的容器,在第26行-->
            <b-list-group v-b-scrollspy:listgroup-ex>
              <!-- b-list-group-item 即为左侧导航中的每个菜品类别,
                    用for循环,加载 菜品类别数组categories 中的每个 菜品类别category,
                    通过href实现指引,需要注意,动态的绑定,href前要加: 冒号
                       "`#p${category.categoryID}`" 意思是 指向 id 为 p+categoryID 的元素,例如 #p1、#p2,在第30行,语法是ES6的模板字符串
                       多加个p 主要是因为 html4 规定id不能为数字 -->
              <b-list-group-item class="list-nav-item" v-for="(category, index) in categories" :key="index"
                                 :href="`#p${category.categoryID}`" rel="external nofollow" >
                {{ category.categoryName }}
              </b-list-group-item>
            </b-list-group>
          </div>
        </b-col>
 
        <b-col cols="9"><!--这里表示 右边的 数据栏占几个格,总共12格-->
          <!-- 下边的div里 id="listgroup-ex" 即是第10行被监听的容器,里边就是要被左侧导航 监听指向的 菜品数据-->
          <div class="menu-content" id="listgroup-ex" style="position:relative; overflow-y:auto; height:800px">
            <!-- 同样 用v-for 遍历菜品类别数组 categories 取出 每种菜品类别category  -->
            <div v-for="(category, index) in categories" :key="index" class="menu-section">
              <!-- h6这里 是我在右侧增加了菜品类别的小标题,这里的id 就是第16-17行种 href所指向的,也就是数据双向监听的关键,每次页面呈现到对应的id时候,左侧的类别也会改变,同样点击左侧,右侧也会跳转到对应的地方  -->
              <h6 :id="'p'+category.categoryID" style="margin-top: 5px">{{ category.categoryName }}</h6>
              <b-row>
                <!-- 下边div 里的 就是用 for循环取出 该菜品类别 category 里的dishList 数组 里的每一个 菜品dish,然后呈现出来,具体的样式就可以自行更改啦-->
                <div class="card" v-for="(dish,index2) in category.dishList" :key="index2">
                  <b-row>
                    <b-col cols="5">
                      <img class="card-img-top" :src="dish.dishPhoto"> 
                    </b-col>
                    <b-col cols="7" class="card-message">
                      <div class="card-body">
                        <p class="card-title" style="font-size: 15px">{{ dish.dish }}</p>
                        <p class="card-text" style="font-size: 12px" >{{ dish.description }}</p>
                        <div class="card-text"><strong style="color:orange; font-size: 15px">¥{{ dish.price }}</strong>
                          <!--加入购物车按钮,我用了vant里的组件,用的话,记得下载并引入vant,或者改成其他button组件-->
                          <van-button icon="plus" type="warning" color="#ee0a24" round @click="addToCart(dish)"
                                      size="mini" id="addtocartmenu"></van-button>
                        </div>
                      </div>
                    </b-col>
                  </b-row>
                </div>
 
              </b-row>
            </div>
          </div>
        </b-col>
 
      </b-row>
    </b-container>
  </div>
</template>

静态页面中的代码主要分为两部分,左侧导航栏 & 右侧数据栏,核心就在于 两点:

第10行的代码中 v-b-scrollspy: listgroup-ex ,指向需要监听的div,即26行id="listgroup-ex" 的div

在16-17行的代码中,:href="`#p${category.categoryID}`",用来绑定对应的超链接,绑定到第30行,因为我用for循环加载每个菜品,所以href 就得是动态的,一定记得href前加冒号':', 这里的语法是ES6的模板字符串``,有需要可以看一下,模板字符串 - JavaScript | MDN (mozilla.org)

如下图所示:

四、<script>部分

4.1 从data中加载数据

在script中存测试用例

export default {
  data() {
    return {
      activeSection: null, // 不知道干嘛的在目录那边有用到
      currentCategory: '', // 当前分类
      categories: [
        {
          categoryID: 1,
          categoryName: "汉堡",
          dishList: [
            {
              dishID: 1,
              dish: "汉堡11",
              description: "汉堡",
              dishPhoto: "https://img.yzcdn.cn/vant/cat.jpeg",
              price: 10,
              stock: 100
            },
            {
              dishID: 2,
              dish: "汉堡",
              description: "汉堡",
              dishPhoto: "https://img.yzcdn.cn/vant/cat.jpeg",
              price: 10,
              stock: 100
            },
            {
              dishID: 3,
              dish: "汉堡",
              description: "汉堡",
              dishPhoto: "https://img.yzcdn.cn/vant/cat.jpeg",
              price: 10,
              stock: 100
            },
            {
              dishID: 4,
              dish: "汉堡",
              description: "汉堡",
              dishPhoto: "https://img.yzcdn.cn/vant/cat.jpeg",
              price: 10,
              stock: 100
            },
          ]
        },
        {
          categoryID: 2,
          categoryName: "汉堡",
          dishList: [
            {
              dishID: 1,
              dish: "汉堡11",
              description: "汉堡",
              dishPhoto: "https://img.yzcdn.cn/vant/cat.jpeg",
              price: 10,
              stock: 100
            },
            {
              dishID: 2,
              dish: "汉堡",
              description: "汉堡",
              dishPhoto: "https://img.yzcdn.cn/vant/cat.jpeg",
              price: 10,
              stock: 100
            },
            {
              dishID: 3,
              dish: "汉堡",
              description: "汉堡",
              dishPhoto: "https://img.yzcdn.cn/vant/cat.jpeg",
              price: 10,
              stock: 100
            },
            {
              dishID: 4,
              dish: "汉堡",
              description: "汉堡",
              dishPhoto: "https://img.yzcdn.cn/vant/cat.jpeg",
              price: 10,
              stock: 100
            },
            
          ]
        },
        {
          categoryID: 3,
          categoryName: "汉堡",
          dishList: [
            {
              dishID: 1,
              dish: "汉堡11",
              description: "汉堡",
              dishPhoto: "https://img.yzcdn.cn/vant/cat.jpeg",
              price: 10,
              stock: 100
            },
            {
              dishID: 2,
              dish: "汉堡",
              description: "汉堡",
              dishPhoto: "https://img.yzcdn.cn/vant/cat.jpeg",
              price: 10,
              stock: 100
            },
            {
              dishID: 3,
              dish: "汉堡",
              description: "汉堡",
              dishPhoto: "https://img.yzcdn.cn/vant/cat.jpeg",
              price: 10,
              stock: 100
            },
            {
              dishID: 4,
              dish: "汉堡",
              description: "汉堡",
              dishPhoto: "https://img.yzcdn.cn/vant/cat.jpeg",
              price: 10,
              stock: 100
            },
          ]
        },
      ]
    }
  }
}

4.2 从后端接收数据

如果数据是从后端过来的,需要在页面加载时就展现,方法需要在mounted里加载,我习惯在method里写,然后在mounted里使用,如下:

export default {
  methods: {
    //获取菜品信息
    getDishes() {
      // 通过后端API获取菜品列表(包括分类信息),需要先引入axios
      this.$api({
        url: '/categories/alldishes', //请求地址
        method: 'get'
      }).then(res => {
        console.log(res)
        this.categories = res.data; //将数据传给categories 
      }).catch(function (error) {
        console.log(error);
      });
    }
  },
  mounted() {
    this.getDishes();
  }
}

五、<style>部分

我对样式进行了一点点修改,如下:

#menu {
  font-size: 1rem;
  font-weight: 400;
  line-height: 1.5;
  color: #212529;
  text-align: left;
  box-sizing: border-box;
  padding-top: 1rem;
  padding-bottom: 1rem;
  padding-left: 0px;
  padding-right: 0px;
  margin-right: 0px;
  margin-left: 0px;
  height: calc(100% - 10rem);
  width: 100%;
  overflow-y: auto;
  display: block !important;
}
 
.list-nav-item {
  --bs-list-group-color: #212529;
  --bs-list-group-bg: null;
  --bs-list-group-border-color: null; /*rgba(0, 0, 0, 0.125) */
  --bs-list-group-border-width: 1px;
  --bs-list-group-border-radius: 0.375rem;
  --bs-list-group-item-padding-x: 1rem;
  --bs-list-group-item-padding-y: 0.5rem;
  --bs-list-group-action-color: #495057;
  --bs-list-group-action-hover-color: #495057;
  --bs-list-group-action-hover-bg: #f8f9fa;
  --bs-list-group-action-active-color: #212529;
  --bs-list-group-action-active-bg: #e9ecef;
  --bs-list-group-disabled-color: #6c757d;
  --bs-list-group-disabled-bg: #fff;
  --bs-list-group-active-color: #fff;
  --bs-list-group-active-bg: #ffcd56;
  --bs-list-group-active-border-color: #ffcd56;
  display: flex;
  flex-direction: column;
  padding-left: 10px;
  margin-bottom: 0;
  border-radius: var(--bs-list-group-border-radius);
 
}
 
/*商品列表*/
.card {
  background: none;
}
 
.card-message {
  padding-left: 0;
  padding-right: 0;
}
 
 
.card-title {
  width: auto;
  height: 20px;
  margin-top: 2px;
}
 
.card-body {
  padding-left: 0;
  padding-right: 0;
}

到此这篇关于Bootstrap+Vue滑动监听Scrollspy实现餐厅餐品展示的文章就介绍到这了,更多相关Bootstrap+Vue滑动监听Scrollspy 内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

您可能感兴趣的文章:
阅读全文