首页 > 其他分享 >vue3项目-小兔鲜儿笔记-03-首页模块02

vue3项目-小兔鲜儿笔记-03-首页模块02

时间:2022-08-28 23:44:50浏览次数:56  
标签:02 03 轮播 default 鲜儿 app props import 255

1. 骨架效果

目的:为了在加载过程中等待效果更好,封装骨架屏组件

实现步骤:

  • 骨架屏组件需暴露的属性:高、宽、背景颜色,是否启用动画

  • 使用插件的方式进行全局注册

<template>
  <!-- 骨架屏,就是一个可定制高、宽、背景以及动画的盒子 -->
  <div class="xtx-skeleton" :style="{ width, height, backgroundColor: bg }">
    <!-- 额外多加一个盒子,在这个盒子上添加伪元素,做绝对定位 -->
    <div class="block" :class="{ animate: animated }"></div>
  </div>
</template>

<script setup>
defineProps({
  width: {
    type: String,
    default: '100px'
  },
  height: {
    type: String,
    default: '100px'
  },
  bg: {
    type: String,
    default: '#efefef'
  },
  animated: {
    type: Boolean,
    default: true
  }
})
</script>
<style lang="less" scoped>
.xtx-skeleton {
  position: relative;
  display: inline-block;
  vertical-align: middle;
  overflow: hidden;
  border-radius: 2px;

  .block {
    width: 100%;
    height: 100%;
  }

  .animate {
    &::after {
      content: '';
      // 设置绝对定位,这样动画可以调整left来实现移动的效果
      position: absolute;
      width: 50%;
      height: 100%;
      top: 0;
      // 使用动画,属性:name duration time-function delay iteration
      animation: move 1s ease 0s infinite;
      // 线性渐变,配合伪元素做出一个宽度只有盒子一半的图片,这个图片渐变色为黑白黑,向左倾斜45度,配合动画从左往右移动
      background-image: linear-gradient(to left,
      rgba(255, 255, 255, 0) 0,
      rgba(255, 255, 255, 0.3) 50%,
      rgba(255, 255, 255, 0) 100%);
      transform: skew(45deg);
    }
  }
}

// 动画:从左到右移动
@keyframes move {
  0% {
    left: -100%;
  }
  100% {
    left: 120%;
  }
}
</style>

 

2. 封装轮播图组件

基础布局:

<template>
  <div class="xtx-carousel" @mouseenter="stopAutoPlay()" @mouseleave="startAutoPlay()">
    <!--  banner  -->
    <ul class="carousel-body">
      <template v-if="sliders.length">
        <li
            v-for="(slider, i) in sliders"
            :key="slider.id"
            class="carousel-item"
            :class="{fade: index === i}"
        >
          <router-link :to="slider.hrefUrl">
            <img :src="slider.imgUrl" alt="">
          </router-link>
        </li>
      </template>
    </ul>
    <!--  左右翻页指示器  -->
    <a href="javascript:;" class="carousel-btn prev" @click="toggle(-1)">
      <i class="iconfont icon-angle-left"></i>
    </a>
    <a href="javascript:;" class="carousel-btn next" @click="toggle(1)">
      <i class="iconfont icon-angle-right"></i>
    </a>
    <!--  指示器  -->
    <div class="carousel-indicator">
      <span
          v-for="(slider, i) in sliders"
          :key="slider.id"
          @click="index=i"
          :class="{active: index===i}"
      ></span>
    </div>
  </div>
</template>

 

暴露出轮播图数组、一幅banner的持续时间、是否自动轮播这三个属性,供父组件传入使用

const props = defineProps({
  sliders: {
    type: Array,
    default: []
  },
  duration: {
    type: Number,
    default: 2000
  },
  autoPlay: {
    type: Boolean,
    default: false
  }
})

 

自动轮播的逻辑:定时器令索引值更新,且在鼠标移入的时候清除定时器,鼠标移出的时候重新开启定时器

// 自动轮播
const index = ref(0)
let timer = null
const autoPlayFn = () => {
  clearInterval(timer)
  timer = setInterval(() => {
    index.value++
    if (index.value > props.sliders.length) {
      index.value = 0
    }
  }, props.duration)
}

// 鼠标移入,停止自动轮播
const stopAutoPlay = () => {
  if (timer) {
    clearInterval(timer)
  }
}

// 鼠标移出,如果是要求自动轮播,则开启自动轮播
const startAutoPlay = () => {
  if (props.autoPlay && props.sliders.length) {
    autoPlayFn()
  }
}

// 监听sliders,判断是否要开启自动轮播
watch(() => props.sliders, (newValue) => {
  if (newValue.length && props.autoPlay) {
    index.value = 0
    autoPlayFn()
  }
}, {immediate: true})

// 组件销毁时,销毁定时器
onUnmounted(() => {
  if (timer) {
    clearInterval(timer)
  }
})

 

点击更改轮播图的逻辑:点击上一张就使索引值-1,点击下一张就使索引值+1,判断边界范围

// 点击更改轮播图
const toggle = (step) => {
  let newIndex = index.value + step
  if (newIndex > props.sliders.length - 1) {
    newIndex = 0
  }
  if (newIndex < 0) {
    newIndex = props.sliders.length - 1
  }
  index.value = newIndex
}

 

3. Vue插件的使用

  • Vue2的使用插件的方式:导出一个对象,有install函数,默认传入Vue构造函数,install函数内部使用Vue构造函数扩展Vue功能

  • Vue3的使用插件的方式:导出一个对象,有install函数,默认传入了app应用实例,install函数内部使用app实例扩展Vue功能

import XtxSkeleton from './xtx-skeleton.vue'
import XtxCarousel from '@/components/library/xtx-carousel'

export default {
  install(app) {
    app.component(XtxSkeleton.name, XtxSkeleton)
    app.component(XtxCarousel.name, XtxCarousel)
  }
}

main.js中,app实例使用use方法就会自动调用install函数,并传入app应用实例

import { createApp } from 'vue'
import App from './App.vue'

import { createPinia } from 'pinia'
import persistedState from 'pinia-persistedstate'

import router from './router'

import 'normalize.css'
import '../src/assets/styles/common.less'

import UI from './components/library'

const store = createPinia()
store.use(
  persistedState({
    key: 'erabbit-shop',
    paths: ['user', 'cart']
  })
)

createApp(App).use(router).use(UI).use(store).mount('#app')

 

标签:02,03,轮播,default,鲜儿,app,props,import,255
From: https://www.cnblogs.com/jzhFlash/p/16634474.html

相关文章

  • 2022暑假集训新学知识点总结
    新学知识点图论树1、树链剖分(求lca,dfs序等)2、倍增lca流1、Dinic最大流2、匈牙利二分图最大匹配其他1、spfa最短路判负环字符串1、后缀自动机SAM2、回文自动......
  • 2022DAS_April warmup_php
    wp思路先简单代码审计一下,发现它是个渲染HTML表格的东西。可利用的RCE在Base::evaluateExpression中,类之间基本都有继承关系。回调函数在这段代码里也有挺多。利用链:Act......
  • 【django学习-02】MTV模式与django流程
    一:MVC和MTV模式著名的MVC模式:所谓MVC就是把web应用分为模型(M),控制器(C),视图(V)三层;他们之间以一种插件似的,松耦合的方式连接在一起。模型负责业务对象与数据库的对......
  • gym-103708E Erudite of words
    Eruditeofwords组合数学+容斥定义\(F_i\):表示由\(i\)个字母组成的长度为\(n\)的单词数(每个字母必须在单词中出现)显然答案就是\(F_k*C_{m}^{k}\)关于\(F_i......
  • PAT Advanced 1029 Median(25)
    题目描述:GivenanincreasingsequenceSofNintegers,themedianisthenumberatthemiddleposition.Forexample,themedianofS1={11,12,13,14}is1......
  • 20220815今天学了干了什么?努力过好今天
    看课给了两个bug   js的课,那今天开这个课,就把它学明白。 这个知识点是什么呢?把它弄明白。 今天我能学什么知识?好好努力,顺其自然,自然社交,尊重别人,话说三分,得......
  • 项目中索引的真实应用场景-2022新项目
    一、业务场景项目开发中,数据存储是一定少不了的,不管是存储关系型数据还是还是非关系型数据。可选择的范围也很广,比如mysql,postgresql,oracle,mongodb等等。一般都是根......
  • Day02
    基础知识Strings="abcdefg";//ch的值是"a"charch=s.charAt(0);//num的值是?(5?)intnum=s.indexOf("e",0);//链表ListNode例子://下面逆向存储链表相加后......
  • 2022 正睿 NOIP 十连测
    Day1100+100+70+60,rank5。A对\(\{a_n\}\)排序后,最优的方案一定是选一个前缀,于是二分一下即可。B钦定\(1\)为根,对于一条非树边\((u_i,v_i)\),在树上\(u_i\leadst......
  • 2022-08-24 day34 第一小组 王鸣赫
    目录JavaScriptJS的数据类型函数(相当于java的方法对象判断和循环常见工具对象JavaScript(独有的)DOM编程DocumentObjectModel获取元素节点innerHTML和innerText新增元素......