vue開發公共元件之返回頂部
阿新 • • 發佈:2022-01-07
本文例項為大家分享了開發公共元件之返回頂部的具體程式碼,供大家參考,具體內容如下
記錄一下開發公共元件的流程。
背景:pc端使用element-ui框架,本身是有返回頂部的元件的。現在需要在移動端使用。照著葫蘆畫瓢弄一個。
記錄如何將公共元件通過install的方式,註冊為全域性的元件使用。
components目錄下,新建bacttop資料夾,內部包含一個index.檔案和一個src資料夾。
src資料夾內放backtop.vue元件檔案。
|--components
|--index.js
|-- backtop
|--index.js
|--src
|--backtop.vue
backtop下的index.js負責安裝,backtop.vue內部寫具體的元件程式碼
index.js檔案內容:
// index.js import Backtop from "./src/backtop"; // 引入元件 // 配置安裝方法 /* istanbul ignore next */ Backtop.install = function (Vue) { Vue.component(Backtop.name,Backtop); }; // 匯出模組 export default Backtop;
backtop.vue檔案內容:
<template> <!-- xl-backtop樣式名,需要自己在樣式檔案中定義這個樣式內容 --> <div v-if="visible" @click.stop="handleClick" :style="{ right: styleRight,bottom: styleBottom,}" class="xl-backtop" > <slot> <!-- 這裡是返回頂部的圖示 --> <van-icon name="arrow-up" /> </slot> </div> </template> <script> // 這裡引入了節流函式 import { _throttle } from "@/utils"; const cubic = (value) => Math.pow(value,3); const easeInOutCubic = (value) => value < 0.5 ? cubic(value * 2) / 2 : 1 - cubic((1 - value) * 2) / 2; export default { name: "XlBacktop",props: { visibilityHeight: { type: Number,default: 200,},target: [String],right: { type: Number,default: 40,bottom: { type: Number,data() { return { el: null,container: null,visible: false,}; },computed: { styleBottom() { return `${this.bottom}px`; },styleRight() { return `${this.right}px`; },mounted() { this.init(); this.throttledScrollHandler = _throttle(this.onScroll,300); this.container.addEventListener("scroll",this.throttledScrollHandler); },methods: { init() { this.container = document; this.el = document.documentElemwww.cppcns.coment; if (this.target) { this.el = document.querySelector(this.target); if (!this.el) { throw new Error(`target is not existed: ${this.target}`); } this.container = this.el; } },onScroll() { const scrollTop = this.el.scrollTop; this.visible = scrollTop >= this.visibilityHeight; },handleClick(e) { this.scrollToTop(); this.$emit("click",e); },scrollToTop() { const el = this.el; const beginTime = Date.now(); const beginValue = el.scrollTop; const rAF = winZejJmSldow.requestAnimationFrame || ((func) => setTimeout(func,16)); const frameFunc = () => { const progress = (Date.now() - beginTime) / 500; if (progress < 1) { el.scrollTop = beginValue * (1 - easeInOutCubic(progress)); rAF(frameFunc); } else { el.scrollTop = 0; } }; rAF(frameFunc); },beforeDestroy() { this.container.removeEventListener("scroll",}; </script>
返回頂部的樣式內容:
// 返回頂部
.xl-backtop {
position: fixed;
width: 40px;
height: 40px;
display: flex;
justify-content: center;
align-items: center;
font-size: 20px;
cursor: pointer;
box-shadow: 0 0 6px rgba(0,www.cppcns.com0,0.12);
border-radius: 50%;
z-index: 5;
}
為了一次性註冊多個自己寫的功能元件,我們在components資料夾下面寫一www.cppcns.com個index.js
components下的index負責一次性組合多個
// components/index.js import BackTop from "./backtop"; // 引入我們的返回頂部元件。其他的類似的一起寫在這裡 const components = [BackTop]; // 其他的元件以陣列形式繼續寫 const install = function (Vue,opts = {}) { components.map((component) => { Vue.component(component.name,component); }); }; /* istanbul ignore if */ if (typeof window !== "undefined" && window.Vue) { install(window.Vue); } // 組合匯出安裝方法 const exportsResult = { version: "1.0.0",install,}; Object.assign(exportsResult,components); export default exportsResult;
最後在專案的main.js安裝
// The Vue build version to load with the `import` command // (runtime-only or standalone) has been set in webpack.base.conf with an alias. import Vue from "vue"; import App from "./App"; import store from "./store"; import router from "./router"; // 自己封裝的公共安裝元件 import XlComponent from "@/components"; Vue.use(XlComponent); import "@/styles/index.less"; // 全域性 Vue.config.productionTip = false; /* eslint-disable no-new */ new Vue({ el: "#app",router,store,components: { App },template: "<App/>",});
補充:上述方法在安卓端會失效
原因是document.documentElement.scrollTop在安卓端始終是0;只有pc端和IOS端才是正常的。
改寫backtop元件中的程式碼,完成相容。
<template> <transition name="van-fade"> <div v-if="visible" @click.stop="handleClick" :style="{ right: styleRight,}" class="xl-backtop" > <slot> <van-icon name="arrow-up" color="#13b7f6" /> </slot> </div> </transition> </template> <script> import { _throttle } from "@/utils"; const cubic = (value) => Math.pow(value,methods: { init() { this.container = document; this.el = document.documentElement; if (this.target) { this.el = document.querySelector(this.target); if (!this.el) { throw new Error(`target is not existed: ${this.target}`); } this.container = this.el; } },onScroll() { // 這裡,如果document.documentElement.scrollTop 的值為0,就獲取document.body.scrollTop const scrollTop = this.el.scrollTop || document.body.scrollTop; this.visible = scrollTop >= this.visibilityHeight; },scrollToTop() { // 還有這裡,如果document.documentElement.scrollTop 的值為0,就獲取document.body元素 const el = this.el.scrollTop? thiswww.cppcns.com.el : document.body; const beginTime = Date.now(); const beginValue = el.scrollTop; const rAF = window.requestAnimationFrame || ((func) => setTimeout(func,this.throttledScrollHandler); this.el = null; },}; </script>
以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支援我們。