基于mpvue实现左侧导航与右侧内容的联动

本文介绍了如何使用mpvue在微信小程序中创建左侧导航与右侧内容联动的效果。通过scroll-view组件的scroll-into-view属性,实现在点击左侧导航时,右侧内容滚动到对应位置。同时,当滑动右侧内容区域,会更新左侧导航的current样式。内容还涵盖了导航高度过长时的滚动处理策略。
摘要由CSDN通过智能技术生成

效果图如下:

    

(1)左侧导航联动右侧内容

实现:点击左侧导航,右侧内容滑到对应的位置,并且导航上有current当前样式。

mpvue用的还是微信小程序提供的组件scroll-view,它里面有一个属性scroll-into-view,值为某子元素的id,滚动到该元素。

template:

<scroll-view class="menu-wrapper" scroll-y>
  <ul>
    <li class="menu-item"
        v-for="(item,index) in goods"
        :class="index===currentIndex ? 'current' : ''"
        :key="index"
        @tap="selectMenu(index)">
           {{item.name}}
    </li>
  </ul>
</scroll-view>
<scroll-view scroll-y
             :scroll-into-view="contentId"
             scroll-with-animation="true"
             class="foods-wrapper">
  <ul>
    <li v-for="(item,i) in goods"
        :id="'con_'+i"
        class="food-list food-list-hook" :key="i">
    </li>
  </ul>
<scroll-view>

js:

data() {
  return {
    goods: [],
    contentId: '', // 每个food-list的id,scroll-into-view滚动到对应的id
    currentIndex: 0
  }
},
methods: {
  selectMenu(index) {
    this.contentId = `con_${index}`
    this.currentIndex = index
  }
}

(2)在左侧导航联动右侧内容的基础上增加右侧内容联动左侧导航

实现:滑动右侧内容区域,给左侧对应导航增加current样式,并且当导航高度过长,会联动其滚动

补充:contentHeight是右侧内容scroll-view的高度,同时也是左侧导航scroll-view的高度,navItemHeight是导航ul下每一个item的高度,当导航下ul的高度超过scroll-view的高度,并且this.currentIndex * this.navItemHeight  > this.contentHeight,导航才向上滚动。

tempate:

<scroll-view class="menu-wrapper"
             :scroll-into-view="navId"
             scroll-with-animation="true"
             scroll-y>
  <ul class="menu-ul">
    <li class="menu-item"
        v-for="(item,index) in goods"
        :id="'nav_'+index"
        :class="index===currentIndex ? 'current' : ''"
        :key="index"
        @tap="selectMenu(index)">
         {{item.name}}
    </li>
  </ul>
</scroll-view>
<scroll-view scroll-y
             @scroll="onScroll"
             :scroll-into-view="contentId"
             scroll-with-animation="true"
             class="foods-wrapper">
  <ul>
    <li v-for="(item,i) in goods"
        :id="'con_'+i"
        class="food-list food-list-hook" :key="i">
    </li>
  </ul>
</scroll-view>

js:

export default{
  data() {
    return {
      goods: [],
      contentId: '', // 每个food-list的id,scroll-into-view滚动到对应的id
      navId: '', // 导航模块对应的id,用来联动内容区域
      currentIndex: 0,
      navulHeight: 0, // 导航里ul高度
      navItemHeight: 0, // 每个导航高度
      listHeight: [], // foods内部块的高度
      contentHeight: [], // 内容区域scroll-view高度
    }
  },
  watch: {
    currentIndex() {
      console.log(this.currentIndex)
      if (this.contentHeight < this.navulHeight) {
        let h = this.currentIndex * this.navItemHeight
        if (h > this.contentHeight) {
          // 导航滑动
          this.navId = `nav_${this.currentIndex}`
        } else {
          this.navId = 'nav_0'
        }
      }
    }
  },
  methods: {
    selectMenu(index) {
      this.contentId = `con_${index}`
      this.navId = `nav_${index}`
      this.currentIndex = index
    },
    onScroll(e) {
      this.contentId = ''
      let scrollTop = e.target.scrollTop
      // console.log(scrollTop)
      let length = this.listHeight.length
      if (scrollTop >= this.listHeight[length - 1] - this.contentHeight) {
        return
      } else if (scrollTop > 0 && scrollTop < this.listHeight[0]) {
        this.currentIndex = 0
      }
      for (let i = 0; i < length; i++) {
        if (scrollTop >= this.listHeight[i - 1] && scrollTop < this.listHeight[i]) {
          this.currentIndex = i
        }
      }
      // console.log(this.currentIndex)
    },
    getFoodHeight() {
      var query = wx.createSelectorQuery()
      let h = 0
      query.selectAll('.food-list-hook').boundingClientRect((rects) => {
        // console.log(rects)
        rects.forEach((rect) => {
          h += rect.height
          this.listHeight.push(h)
        })
        // console.log(this.listHeight)
      })
      query.select('.foods-wrapper').boundingClientRect((rect) => {
        this.contentHeight = rect.height
      })
      query.select('.menu-ul').boundingClientRect((rect) => {
        this.navulHeight = rect.height
      })
      query.select('.menu-item').boundingClientRect((rect) => {
        this.navItemHeight = rect.height
      }).exec()
    }
  },
  watch: {
    goods() {
      // 获取模块高度,即food-list
      setTimeout(() => {
        this.getFoodHeight()
      }, 60)
    }
  }
}

 

环境配置 Node 下载地址http://nodejs.cn/ 安装文件下有一个绿色的图片交node.exe 点击运行 输入node -v进行检测是否安装成功 使用vue-cli(脚手架)搭建项目 vue-cli是vue官方提供的用域搭建基于vue+webpack_es6项目的脚手架工具 在线文档:https://github.com/vuejs/vue-cli 操作: 1.npm install -g vue-cli:全局下载工具 2.vue init webpack 项目名:下载基于webpack模板项目 3.cd 项目名:进入项目目录 4.npm install :下载项目依赖的所有模块 5.npm run dev :运行项目 6.访问项目:localhost:8080 项目目录结构 src assets:存放照片、css、js css js img components:存放组件 lib:存放模拟数据 router:配置路由 store:存放vuex vuex的安装:cd x项目目录 cnpm install vuex --save views:存放所有单页面 配置访问端口号: 根目录下有一个config文件夹,看名字就知道与配置有关,打开config目录下的index.js dev: { env: require('./dev.env'), port: 8092, autoOpenBrowser: true, assetsSubDirectory: 'static', assetsPublicPath: '/', proxyTable: {}, } 项目目录下:https://blog.csdn.net/weixin_39378691/article/details/83784403 1.安装elementUI:cd进入项目根目录,npm i element-ui -S 2.引入elementUI组件(main.js文件中) import Element from 'element-ui' import 'element-ui/lib/theme-chalk/index.css' Vue.use(Element, { size: 'small' }) 项目目录下:https://blog.csdn.net/weixin_41432849/article/details/81988058 1.安装jquery:cd进入项目根目录, npm install jquery --save 2.在项目 build 里的webpack.base.conf.js 里加载webpack文件,注意,要放在配置文件第一行; const webpack = require('webpack') 3.在module.exports的最后加入 , plugins:[ new webpack.ProvidePlugin({ $:"jquery", jQuery:"jquery", jquery:"jquery", "window.jQuery":"jquery" }) ]
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值