慕课网 视频学习详解tab组件cube-ui框架有源码

本文详述了使用Vue.js结合Cube-UI库构建复杂交互界面的过程,重点介绍了如何自定义主题颜色、实现tab与slide组件的联动效果,以及通过组件化方式优化列表展示。同时,探讨了数据获取策略,包括axios封装与API调用,展示了如何在组件切换时动态加载数据。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

在这里插入图片描述
tab.vue
在这里插入图片描述
app.vue
在这里插入图片描述
详细过程参考:
https://www.cnblogs.com/zhaobao1830/p/9978505.html

先说明遗留的问题
在这里插入图片描述
这个问题是因为components里面多写数据了

项目用了cube-ui库,如果要修改里面默认的颜色,可以这样做

我们安装cube-ui的时候,会出现一个文件:theme.styl,可以在这里面修改

项目中的做法是,我们新建common/stylus/variable.styl文件,在里面先定义好颜色
在这里插入图片描述
然后呢,在theme.styl中引入这个文件,然后替换定义好的颜色
在这里插入图片描述
在这里插入图片描述
4-2 tab组件上下联动

利用cube-tab和cube-slide实现,当滚动slide的时候,对应的tab下划线也滚动

源码:
app.vue

在这里插入图片描述

<template>
  <div id="app">
    <!-- <img alt="Vue logo" src="./assets/logo.png"> -->
    <HelloWorld msg="Welcome to Your Vue.js App"/>
    <div class="tab-wrapper">
      <tab></tab>
    </div>
  </div>
</template>

<script>
import HelloWorld from './components/HelloWorld.vue'
import Tab from './components/tab/tab.vue'
export default {
  name: 'app',
  components: {
    HelloWorld,
    Tab
  }
}
</script>
<style lang="stylus">
#app{
  position fixed
  top 0
  bottom 0
  left 0
  right 0
}
</style>

tab.vue

<template>
  <div class="tab">
    <cube-tab-bar
      :useTransition=false
      :showSlider="true"
      v-model="selectedLabel"
      :data="tabs"
      ref="tabBar"
      class="border-bottom-1px"
    ></cube-tab-bar>
    <div class="slide-wrapper">
      <cube-slide
        :loop="false"
        :auto-play="false"
        :show-dots="false"
        :initial-index="index"
        ref="slide"
        @change="onChange"
        @scroll="onScroll"
        :options="slideOptions"
      >
        <cube-slide-item>
          <goods></goods>
        </cube-slide-item>
        <cube-slide-item>
          <ratings></ratings>
        </cube-slide-item>
        <cube-slide-item>
          <seller></seller>
        </cube-slide-item>
      </cube-slide>
    </div>
  </div>
</template>
<script>
import goods from '../goods/goods.vue'
import ratings from '../ratings/ratings'
import seller from '../seller/seller'
export default {
  name: 'tab',
  data () {
    return {
      index: 0,
      tabs: [
        {
          label: '商品'
        },
        {
          label: '评价'
        },
        {
          label: '商家'
        }
      ],
      slideOptions: {
        listenScroll: true, // 是否监控scroll事件
        probeType: 3, // 0 不派发scroll事件,1:非实时;2:滑动过程中;3:不仅在屏幕滑动的过程中,而且momentum 滚动动画运行过程中实时派发
        dirctionLockThreshold: 0
      }
    }
  },
  methods: {
    // 页面切换时触发
    onChange (current) {
      this.index = current
    },
    onScroll (pos) {
      // console.log(pos.x)
      const tabBarWidth = this.$refs.tabBar.$el.clientWidth
      const slideWidth = this.$refs.slide.slide.scrollerWidth
      const transform = -pos.x / slideWidth * tabBarWidth
      this.$refs.tabBar.setSliderTransform(transform)
    }
  },
  computed: {
    selectedLabel: {
      get () {
        return this.tabs[this.index].label
      },
      set (newVal) {
        // 点击菜单切换  计算当前index是什么,
        this.index = this.tabs.findIndex(value => {
          return value.label === newVal
        })
      }
    }
  },
  components: { seller, ratings, goods }
}
</script>
<style lang="stylus" scoped>
  // @import "~cube-ui/lib/tab-bar/style.css"
  .tab
    >>> .cube-tab
      padding 10px 0
      // display flex
      flex-dirction column
      height 100%
      .slider-wrapper
        flex 1
        overflow hidden
</style>

在这里插入图片描述
考虑到tab页面如果增加列表,不方便改,把tab抽象成组件,从父组件传进来
在这里插入图片描述
app.vue

<template>
  <div id="app">
    <!-- <img alt="Vue logo" src="./assets/logo.png"> -->
    
    <div class="tab-wrapper">
      <tab :tabs="tabs"></tab>
    </div>
  </div>
</template>

<script>

import Tab from './components/tab/tab'
import Goods from './components/goods/goods'
import Ratings from './components/ratings/ratings'
import Seller from './components/seller/seller'
import { getSeller } from 'api'

export default {
  name: 'app',
  data () {
    return {
      seller:{}
    }
  },
  computed: {
    tabs () {
      return [
        {
          label: '商品',
          component: Goods,
          data: {
            seller: this.seller
          }
        },
        {
          label: '评论',
          component: Ratings,
          data: {
            seller: this.seller
          }
        },
        {
          label: '商家',
          component: Seller,
          data: {
            seller: this.seller
          }
        }
      ]
    }
  },
  components: { Tab, Seller, Ratings, Goods }
}
</script>
<style lang="stylus">
#app {
  position: fixed;
  top: 0;
  bottom: 0;
  left: 0;
  right: 0;
}
</style>

seller怎么来?api文件
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
index.styl

@import './icon'
@import './base'

icon.styl

base.styl

html,body{
    height 100%
    overflow hidden
}

maxin.styl

@import '~cube-ui/src/common/stylus/mixin.styl'

api/helpers.js

import axios from 'axios'

const ERR__OK = 0

export function get(url) {
  return function (params) {
    return axios.get(url, {
      params
    }).then((res) => {
        const { errno, data } = res.data
        if (errno === ERR__OK) {
            return data
        }
    }).catch(() => {
    })
  }
}

api/index.js

import { get } from './helpers'

const getSeller = get('/api/seller')

export {
    getSeller
}

npm WARN checkPermissions Missing write access to D:\react-native-workspace\react-native\react-native-cli\node_modules\axios
解决办法

删除掉 C:\Users\dd\AppData\Roaming\npm-cache\
C:\Users\dd\AppData\Roaming\npm\  两个文件夹 重新执行 npm install -g

数据获取,axios的封装

app.vue

import { getSeller } from 'api'

vue.config.js

const path = require('path')
const appData = require('./data.json')
const seller = appData.seller
const goods = appData.goods
const ratings = appData.ratings

function resolve(dir) {
  // dir,当前文件的地址
  return path.join(__dirname, dir)
}
module.exports = {
  css: {
    loaderOptions: {
      stylus: {
        'resolve url': true,
        'import': [
          './src/theme'
        ]
      }
    }
  },
  pluginOptions: {
    'cube-ui': {
      postCompile: true,
      theme: true
    }
  },
  devServer: {
    before(app) {
      app.get('/api/seller', function (req, res) {
        res.json({
          errno: 0,
          data: seller
        })
      })
      app.get('/api/goods', function (req, res) {
        res.json({
          errno: 0,
          data: goods
        })
      })
      app.get('/api/ratings', function (req, res) {
        res.json({
          errno: 0,
          data: ratings
        })
      })
    }
  },
  chainWebpack(config) {
    config.resolve.alias
      .set('components', resolve('src/components'))
      .set('common', resolve('src/common'))
      .set('api', resolve('src/api'))
  }
}

tab标签里面

// 页面切换时触发
    onChange(current) {
      // 切到某个tab下,再去请求数据
      this.index = current
    },

然后在第一个tab组件下,我们去设置一个方法,一个钩子

fetch(){}, 在这个fetch里面去获取数据

import { getgoods } from 'api'

fetch(){
	getGood().then(goods)=>{
	this.goods=goods}
}

fetch方法什么时候调用,在tab下,拿到每个组件的实例
加一个ref="component"

<cube-slide-item v-for="(tab, index) in tabs" :key="index">
          <component ref="component" :is="tab.component" :data="tab.data"></component>
        </cube-slide-item>

在onchange里面

const component = this.$refs.component[current]
component.fetch && component.fetch()

因为我们是在一个列表上,获取的是一个数组 即refs.component是一个数组,current获取当前组件
这个时候判断一下component定义fetch方法就去获取fetch数据,并不是所有组件都要获取fetch数据

这样就会执行第一个组件刚定义的fetch方法了,这样就出现一个问题,onChange实际上只会在切换时候才有,刚进来就没有,为了解决,我们决定加一个mounted(),调用一下onChange方法就可以了

mounted(){
	this.onChange(this.index)
}

>>> 这个可以修改我们的一样式
在这里插入图片描述
在这里插入图片描述
三个箭头怎么来的?
vue loader 官网直通
在这里插入图片描述

视频5-1

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值