1. 程式人生 > 程式設計 >vue開發公共元件之返回頂部

vue開發公共元件之返回頂部

本文例項為大家分享了開發公共元件之返回頂部的具體程式碼,供大家參考,具體內容如下

記錄一下開發公共元件的流程。

背景: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.com
ent; 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 = winZejJmSl
dow.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>

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支援我們。