国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

vue3自定義封裝組件:消息提示、輪播圖、加載更多、骨架屏組件

這篇具有很好參考價(jià)值的文章主要介紹了vue3自定義封裝組件:消息提示、輪播圖、加載更多、骨架屏組件。希望對(duì)大家有所幫助。如果存在錯(cuò)誤或未考慮完全的地方,請(qǐng)大家不吝賜教,您也可以點(diǎn)擊"舉報(bào)違法"按鈕提交疑問。

加載更多組件?

定義組件:src/components/library/xtx-infinite-loading.vue

<template>
  <div class="xtx-infinite-loading" ref="container">
    <div class="loading" v-if="loading">
      <span class="img"></span>
      <span class="text">正在加載...</span>
    </div>
    <div class="none" v-if="finished">
      <span class="img"></span>
      <span class="text">親,沒有更多了</span>
    </div>
  </div>
</template>

<script>
import { ref } from 'vue'
import { useIntersectionObserver } from '@vueuse/core'
export default {
  name: 'XtxInfiniteLoading',
  props: {
    loading: {
      type: Boolean,
      default: false
    },
    finished: {
      type: Boolean,
      default: false
    }
  },
  setup (props, { emit }) {
    const container = ref(null)
    useIntersectionObserver(
      container,
      ([{ isIntersecting }], dom) => {
        if (isIntersecting) {
          if (props.loading === false && props.finished === false) {
            emit('infinite')
          }
        }
      },
      {
        threshold: 0
      }
    )
    return { container }
  }
}
</script>

<style scoped lang='less'>
.xtx-infinite-loading {
  .loading {
    display: flex;
    align-items: center;
    justify-content: center;
    height: 200px;
    .img {
      width: 50px;
      height: 50px;
      background: url(../../assets/images/load.gif) no-repeat center / contain;
    }
    .text {
      color: #999;
      font-size: 16px;
    }
  }
  .none {
    display: flex;
    align-items: center;
    justify-content: center;
    height: 200px;
    .img {
      width: 200px;
      height: 134px;
      background: url(../../assets/images/none.png) no-repeat center / contain;
    }
    .text {
      color: #999;
      font-size: 16px;
    }
  }
}
</style>

注冊(cè)組件:src/components/library/index.js

import XtxInfiniteLoading from './xtx-InfiniteLoading.vue'
export default {
    install(app) {
        app.component(XtxInfiniteLoading.name, XtxInfiniteLoading)
    }
}

?引用組件:src/main.js

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

// 導(dǎo)入自定插件
import ui from './components/library'

// 創(chuàng)建一個(gè)vue應(yīng)用實(shí)例
createApp(App).use(store).use(router).use(ui).mount('#app')

使用組件: .vue文件

 <XtxInfiniteLoading :loading="loading" :finished="finished" 
   @infinite="getData" />

<script>
import { ref} from 'vue'
import { useRoute } from 'vue-router'
import { findSubCategoryGoods } from '@/api/category'
export default {
  name: 'SubCategory',
  setup () {
    const loading = ref(false)
    const finished = ref(false)
    const route = useRoute()
    const goodsList = ref([])
    // 查詢參數(shù)
    let reqParams = {
      page: 1,
      pageSize: 20
    }

    // 獲取數(shù)據(jù)函數(shù)
    const getData = () => {
      loading.value = true
      reqParams.categoryId = route.params.id
      findSubCategoryGoods(reqParams).then(({ result }) => {
        if (result.items.length) {
          goodsList.value.push(...result.items)
          reqParams.page++
        } else {
          // 加載完畢
          finished.value = true
        }
        // 請(qǐng)求結(jié)束
        loading.value = false
      })
    }
    return { loading, finished, getData }
  }
}
</script>

輪播圖組件?

首先是輪播圖的樣式:src/components/library/xtx-carousel.vue?

<template>
</template>

<script>
</script>

<style scoped lang="less">
.xtx-carousel {
    width: 100%;
    height: 100%;
    min-width: 300px;
    min-height: 150px;
    position: relative;

    .carousel {
        &-body {
            width: 100%;
            height: 100%;
        }

        &-item {
            width: 100%;
            height: 100%;
            position: absolute;
            left: 0;
            top: 0;
            opacity: 0;
            transition: opacity 0.5s linear;

            &.fade {
                opacity: 1;
                z-index: 1;
            }

            img {
                width: 100%;
                height: 100%;
            }

            // 輪播商品
            .slider {
                display: flex;
                justify-content: space-around;
                padding: 0 40px;

                >a {
                    width: 240px;
                    text-align: center;

                    img {
                        padding: 20px;
                        width: 230px !important;
                        height: 230px !important;
                    }

                    .name {
                        font-size: 16px;
                        color: #666;
                        padding: 0 40px;
                    }

                    .price {
                        font-size: 16px;
                        color: @priceColor;
                        margin-top: 15px;
                    }
                }
            }
        }

        &-indicator {
            position: absolute;
            left: 0;
            bottom: 20px;
            z-index: 2;
            width: 100%;
            text-align: center;

            span {
                display: inline-block;
                width: 12px;
                height: 12px;
                background: rgba(0, 0, 0, 0.2);
                border-radius: 50%;
                cursor: pointer;

                ~span {
                    margin-left: 12px;
                }

                &.active {
                    background: #fff;
                }
            }
        }

        &-btn {
            width: 44px;
            height: 44px;
            background: rgba(0, 0, 0, .2);
            color: #fff;
            border-radius: 50%;
            position: absolute;
            top: 228px;
            z-index: 2;
            text-align: center;
            line-height: 44px;
            opacity: 0;
            transition: all 0.5s;

            &.prev {
                left: 20px;
            }

            &.next {
                right: 20px;
            }
        }
    }

    &:hover {
        .carousel-btn {
            opacity: 1;
        }
    }
}
</style>

然后是輪播圖的結(jié)構(gòu)與邏輯封裝:src/components/library/xtx-carousel.vue

<template>
  <div class='xtx-carousel' @mouseenter="stop()" @mouseleave="start()">
    <ul class="carousel-body">
    <!--  fade是控制顯示那的那張圖片 需要一個(gè)默認(rèn)索引數(shù)據(jù),
    渲染第一張圖和激活第一個(gè)點(diǎn) -->
      <li class="carousel-item" v-for="(item,i) in sliders" :key="i" 
       :class="{fade:index===i}">
        <RouterLink to="/">
          <img :src="item.imgUrl" alt="">
        </RouterLink>
      </li>
    </ul>
    <!-- 左右點(diǎn)擊按鈕 -->
    <a @click="toogle(-1)" href="javascript:;" class="carousel-btn prev">
       <i class="iconfont icon-angle-left"></i>
    </a>
    <a @click="toogle(1)" href="javascript:;" class="carousel-btn next">
       <i class="iconfont icon-angle-right"></i>
    </a>
    <!-- 跟隨的小點(diǎn) -->
    <div class="carousel-indicator">
      <span v-for="(item,i) in sliders" :key="i" 
       :class="{active:index===i}"></span>
    </div>
  </div>
</template>
<script>
import { onUnmounted, ref, watch } from 'vue'
export default {
    name: 'XtxCarousel',
    props: {
        silders: {
            type: Array,
            default: () => []
        },
        //自動(dòng)輪播的間隙
        duration: {
            type: Number,
            default: 3000
        },
        //是否自動(dòng)輪播
        antoPlay: {
            type: Boolean,
            default: true
        }
    },
    setup(props) {
        // 設(shè)置默認(rèn)索引
        const index = ref(0)
        // 自動(dòng)播放
        let timer = null
        const autoPlayFn = () => {
            clearInterval(timer)
            timer = setTimeout(() => {
                index.value++

                if (index.value >= props.silders.length) {
                    index.value = 0
                }
            }, props.duration)
        }

        watch(() => index.value, () => {
            // 有數(shù)據(jù) 并且開啟了自動(dòng)播放,才調(diào)用自動(dòng)播放
            if (props.sliders.length && props.antoPlay) {
                autoPlayFn()
            }
        }, { immediate: true })

        // 鼠標(biāo)進(jìn)入輪播 計(jì)時(shí)停止
        const stop = () => {
            if (timer) clearInterval(timer)
        }

        // 鼠標(biāo)離開輪播 計(jì)時(shí)開始
        const start = () => {
            if (props.silders.length && props.antoPlay) {
                autoPlayFn()
            }
        }

        // 左右按鈕切換
        const toogle = (step) => {
            const newIndex = index.value + step
            if (newIndex >= props.silders.length) {
                index.value = 0
            } else if (newIndex < 0) {
                index.value = props.silders.length - 1
            } else {
                index.value = newIndex
            }

        }

        // 銷毀計(jì)時(shí)器
        onUnmounted(() => {
            clearInterval(timer)
        })
        return {
            index,
            stop,
            start,
            timer,
            toogle
        }
    }
}
</script>

插件注冊(cè):src/components/library/index.js

+import XtxCarousel from './xtx-carousel.vue'


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

插件使用:src/main.js

import { createApp } from 'vue'
import App from './App.vue'
import router from './router'
import store from './store'
import 'normalize.css'

+import ui from './components/library'

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

在.vue文件中使用

<XtxCarousel :sliders="sliders" />

消息提示組件

封裝組件:?src/components/library/xtx-message.vue

<template>
  <div class="xtx-message" :style="style[type]">
    <!-- 上面綁定的是樣式 -->
    <!-- 不同提示圖標(biāo)會(huì)變 -->
    <i class="iconfont" :class="[style[type].icon]"></i>
    <span class="text">{{text}}</span>
  </div>
</template>
<script>
export default {
  name: 'XtxMessage',
  props: {
    text: {
      type: String,
      default: ''
    },
    type: {
      type: String,
      // warn 警告  error 錯(cuò)誤  success 成功
      default: 'warn'
    }
  },
  setup () {
    // 定義一個(gè)對(duì)象,包含三種情況的樣式,對(duì)象key就是類型字符串
    const style = {
      warn: {
        icon: 'icon-warning',
        color: '#E6A23C',
        backgroundColor: 'rgb(253, 246, 236)',
        borderColor: 'rgb(250, 236, 216)'
      },
      error: {
        icon: 'icon-shanchu',
        color: '#F56C6C',
        backgroundColor: 'rgb(254, 240, 240)',
        borderColor: 'rgb(253, 226, 226)'
      },
      success: {
        icon: 'icon-queren2',
        color: '#67C23A',
        backgroundColor: 'rgb(240, 249, 235)',
        borderColor: 'rgb(225, 243, 216)'
      }
    }
    return { style }
  }
}
</script>
<style scoped lang="less">
.xtx-message {
  width: 300px;
  height: 50px;
  position: fixed;
  z-index: 9999;
  left: 50%;
  margin-left: -150px;
  top: 25px;
  line-height: 50px;
  padding: 0 25px;
  border: 1px solid #e4e4e4;
  background: #f5f5f5;
  color: #999;
  border-radius: 4px;
  i {
    margin-right: 4px;
    vertical-align: middle;
  }
  .text {
    vertical-align: middle;
  }
}
</style>

插件定義:src/componets/library/index.js

import XtxMessage from './xtx-message.vue'

export default {
  install (app) {
    // 在app上進(jìn)行擴(kuò)展,app提供 component directive函數(shù)
    // component是用來進(jìn)行全局組件注冊(cè)的
    // directive主要是用來自定義指令的
    // 如果要掛載原型 app.config.globalProperties 方式
    app.component(XtxMessage.name, XtxMessage)
  }
}

使用插件:src/main.js

import { createApp } from 'vue'
import App from './App.vue'
import router from './router'
import store from './store'
import 'normalize.css'
+import ui from './components/library'

+// 插件的使用,在main.js使用app.use(插件)
+createApp(App).use(store).use(router).use(ui).mount('#app')

在.vue文件中使用:文章來源地址http://www.zghlxwxcb.cn/news/detail-652642.html

 <XtxMessage text="賬號(hào)密碼錯(cuò)誤" type="error"/>

骨架屏組件

?封裝組件:src/components/library/xtx-skeleton.vue

<template>
  <div class="xtx-skeleton" :style="{width,height}" :class="{shan:animated}">
    <!-- 1 盒子-->
    <div class="block" :style="{backgroundColor:bg}"></div>
    <!-- 2 閃效果 xtx-skeleton 偽元素 --->
  </div>
</template>
<script>
export default {
  name: 'XtxSkeleton',
  // 使用的時(shí)候需要?jiǎng)討B(tài)設(shè)置 高度,寬度,背景顏色,是否閃下
  props: {
    bg: {
      type: String,
      default: '#efefef'
    },
    width: {
      type: String,
      default: '100px'
    },
    height: {
      type: String,
      default: '100px'
    },
    animated: {
      type: Boolean,
      default: false
    }
  }
}
</script>
<style scoped lang="less">
.xtx-skeleton {
  display: inline-block;
  position: relative;
  overflow: hidden;
  vertical-align: middle;
  .block {
    width: 100%;
    height: 100%;
    border-radius: 2px;
  }
}
.shan {
  &::after {
    content: "";
    position: absolute;
    animation: shan 1.5s ease 0s infinite;
    top: 0;
    width: 50%;
    height: 100%;
    background: linear-gradient(
      to left,
      rgba(255, 255, 255, 0) 0,
      rgba(255, 255, 255, 0.3) 50%,
      rgba(255, 255, 255, 0) 100%
    );
    transform: skewX(-45deg);
  }
}
@keyframes shan {
  0% {
    left: -100%;
  }
  100% {
    left: 120%;
  }
}
</style>

插件定義:?src/componets/library/index.js

import XtxSkeleton from './xtx-skeleton.vue'

export default {
  install (app) {
    // 在app上進(jìn)行擴(kuò)展,app提供 component directive 函數(shù)
    // 如果要掛載原型 app.config.globalProperties 方式
    // component是用來進(jìn)行全局組件注冊(cè)的
    // directive主要是用來自定義指令的
    app.component(XtxSkeleton.name, XtxSkeleton)
  }
}

使用插件:?src/main.js

import { createApp } from 'vue'
import App from './App.vue'
import router from './router'
import store from './store'
import 'normalize.css'
+import ui from './components/library'

+// 插件的使用,在main.js使用app.use(插件)
+createApp(App).use(store).use(router).use(ui).mount('#app')

在.vue文件中使用:

<XtxSkeleton bg="#e4e4e4" width="306px" height="306px" animated />
<XtxSkeleton width="50px" height="18px" bg="rgba(255,255,255,0.2)" />

到了這里,關(guān)于vue3自定義封裝組件:消息提示、輪播圖、加載更多、骨架屏組件的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點(diǎn)僅代表作者本人,不代表本站立場。本站僅提供信息存儲(chǔ)空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請(qǐng)注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實(shí)不符,請(qǐng)點(diǎn)擊違法舉報(bào)進(jìn)行投訴反饋,一經(jīng)查實(shí),立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

  • Vue3.0項(xiàng)目——打造企業(yè)級(jí)音樂App(一)Tab欄、輪播圖、歌單列表、滾動(dòng)組件

    Vue3.0項(xiàng)目——打造企業(yè)級(jí)音樂App(一)Tab欄、輪播圖、歌單列表、滾動(dòng)組件

    內(nèi)容 參考鏈接 Vue3.0 項(xiàng)目啟動(dòng) Vue3.0 項(xiàng)目啟動(dòng)(打造企業(yè)級(jí)音樂App) Vue3.0項(xiàng)目——打造企業(yè)級(jí)音樂App(一) Tab欄、輪播圖、歌單列表、滾動(dòng)組件 Vue3.0項(xiàng)目——打造企業(yè)級(jí)音樂App(二) 圖片懶加載、v-loading指令的開發(fā)和優(yōu)化 vue3.0-music 該項(xiàng)目為移動(dòng)端的項(xiàng)目,我們要設(shè)置縮放

    2023年04月11日
    瀏覽(21)
  • vue項(xiàng)目中使用vant輪播圖組件(桌面端)

    vue項(xiàng)目中使用vant輪播圖組件(桌面端)

    vue使用vant輪播圖組件(桌面端) 2.1 Visual Studio Code 1.75.0 2.2 chrome瀏覽器 2.3 node v18.14.0 3.1 安裝環(huán)境 3.2 添加代碼 3.3 結(jié)果展示 4.1 安裝環(huán)境 先安裝包 然后桌面端適配 4.2 添加代碼 注冊(cè)組件 相比于官方給的代碼,有兩個(gè)方面需要注意,一個(gè)是適配桌面端,還有一個(gè)就是我以為vant組

    2024年02月04日
    瀏覽(35)
  • vue3 實(shí)現(xiàn)門戶網(wǎng)站頁面鼠標(biāo)滾輪控制頁面上下滾動(dòng)---類似輪播圖

    案例參考:首頁_CNESA 儲(chǔ)能研究平臺(tái) //監(jiān)聽鼠標(biāo)滾動(dòng)事件 ?window.addEventListener(\\\'mousewheel\\\', debounce(methodB,300), true)||window.addEventListener(\\\"DOMMouseScroll\\\",debounce(methodB,300),false) const debounce = (func, wait) ={ ? ? ? ? let timeout; ? ? ? ? return ?function() { ? ? ? ? ? ? let context = this; ? ? ? ? ? ?

    2024年02月12日
    瀏覽(172)
  • 教程6 Vue3+Element Plus el-carousel制作輪播圖(后面有修改樣式的方法)

    教程6 Vue3+Element Plus el-carousel制作輪播圖(后面有修改樣式的方法)

    (1)引入Element開發(fā)環(huán)境 (2)自動(dòng)引入Element (3)在配置文件中進(jìn)行配置,本人使用的是Vit構(gòu)建工具 如果使用Vite作為構(gòu)建工具,配置文件為vite.config.js,配置方法如下: (4)Element Plus全局引入 main.ts中增加下面的代碼: (1)運(yùn)行效果 (2)Rotation.vue參考代碼 (3)卡片式輪

    2024年02月06日
    瀏覽(49)
  • 基于VUE3+Layui從頭搭建通用后臺(tái)管理系統(tǒng)(前端篇)八:自定義組件封裝上

    基于VUE3+Layui從頭搭建通用后臺(tái)管理系統(tǒng)(前端篇)八:自定義組件封裝上

    ??本章實(shí)現(xiàn)一些自定義組件的封裝,包括數(shù)據(jù)字典組件的封裝、下拉列表組件封裝、復(fù)選框單選框組件封裝、單選框組件封裝、文件上傳組件封裝、級(jí)聯(lián)選擇組件封裝、富文本組件封裝等。 1. 詳細(xì)課程地址: https://edu.csdn.net/course/detail/38183 2. 源碼下載地址: 點(diǎn)擊下載

    2024年02月12日
    瀏覽(27)
  • vue2與vue3項(xiàng)目中,分別使用element組件的message消息提示只出現(xiàn)一次的實(shí)現(xiàn)

    vue2與vue3項(xiàng)目中,分別使用element組件的message消息提示只出現(xiàn)一次的實(shí)現(xiàn)

    比如出現(xiàn)以上現(xiàn)象,想要讓上一次提示沒有結(jié)束,下一次提示不會(huì)出現(xiàn)就可以用以下方法解決 解決后的現(xiàn)象一:上一次提示框顯示后,提示框出現(xiàn)的提示時(shí)間沒有結(jié)束,再次點(diǎn)擊,提示框不會(huì)有反應(yīng),在該提示的時(shí)間內(nèi)一只顯示,下一次提示不會(huì)出現(xiàn),直到該提示的時(shí)間過了

    2024年02月02日
    瀏覽(28)
  • vue3 + vite自定義封裝vue + element-ui 表格組件,發(fā)布到npm包的全過程。

    vue3 + vite自定義封裝vue + element-ui 表格組件,發(fā)布到npm包的全過程。

    當(dāng)我們項(xiàng)目中用到的表格太多的話,就會(huì)導(dǎo)致我們的代碼量一直增加,所以我們要封裝一個(gè)公共得組件,通過傳參引入來使用,下面這篇文章主要給大家介紹了關(guān)于vue3+vite自定義封裝vue組件發(fā)布到npm包的相關(guān)資料,需要的朋友可以參考下。 提示我們要安裝 create-vite@4.1.0 得依賴

    2024年02月02日
    瀏覽(26)
  • Taro + vue3 + js + nutUI 框架中自定義tabbar的組件封裝以及頁面跳轉(zhuǎn)的邏輯

    1.需求: ? 在H5 中需要封裝一個(gè)自定義的tabbar 菜單跳轉(zhuǎn) 通過nut-ui 進(jìn)行二次封裝 2. 注意點(diǎn) ? H5 中原生的tabbar 在ios 中會(huì)出現(xiàn)問題 所以進(jìn)行 封裝tabbar 3. 代碼操作 首先全部的代碼? 4.解析 tabList: 菜單的內(nèi)容數(shù)組? 根據(jù)自己菜單的數(shù)量 來決定 const tabList = reactivemenu[]([ ? ? { ? ?

    2024年04月17日
    瀏覽(96)
  • 前端項(xiàng)目-05-輪播圖banner和Floor組件開發(fā)-全局輪播圖組件抽取

    前端項(xiàng)目-05-輪播圖banner和Floor組件開發(fā)-全局輪播圖組件抽取

    目錄 1-輪播圖模塊數(shù)據(jù)開發(fā) 2-floor組件開發(fā) 3-抽取全局輪播圖組件 輪播圖需要用到swiper插件,先安裝5.4.5版本的swiper: npm ?install --save swiper@^5.4.5 --force 模擬從服務(wù)器獲取數(shù)據(jù); 1-編寫mockRequests的js文件和之前編寫的request的js文件類似,就修改一下baseURL,我們模擬的數(shù)據(jù)請(qǐng)求路

    2023年04月08日
    瀏覽(19)
  • Vue3 + Vite + Ts自己封裝的基礎(chǔ)組件庫發(fā)布npm ,npm安裝使用(Volar )支持TS 類型提示功能(vite-plugin-dts 使用)

    Vue3 + Vite + Ts自己封裝的基礎(chǔ)組件庫發(fā)布npm ,npm安裝使用(Volar )支持TS 類型提示功能(vite-plugin-dts 使用)

    在開發(fā)Vue3 + Ts項(xiàng)目時(shí):使用自己二次封裝的基礎(chǔ)組件,沒有 Ts類型提示 ,不能像 Element-plus 鼠標(biāo)停在標(biāo)簽或者屬性上就能提示當(dāng)前組件有哪些屬性(即props)及其屬性的類型,如下圖是 Element-plus 組件的 使用Vs Code Volar的提示: 此插件的作用:為打包的庫里加入聲明文件(即生

    2024年02月09日
    瀏覽(26)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請(qǐng)作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包