Vue文字走马灯(文字轮播)组件
生活随笔
收集整理的這篇文章主要介紹了
Vue文字走马灯(文字轮播)组件
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
有幾次遇到文字超長不能在布局內顯示完整信息,只能通過ellipsis加上省略號顯示內容,再補充title去提示完整信息,其實知道這個辦法能解決問題,但是不夠對于動效來說屬于不優雅,查詢看了部分人的想法是將文字使用translateX來移動,當然能實現,感覺動畫效果處理起來有點費勁,會很呆板。又想起vant-ui的通知欄有這個效果,就花了點時間的修改組件的源碼,進行修改成常用組件代碼的格式。整體效果功能同官網一致。將里面的rander模板換成了template模板,將里面使用的common方法直接簡化放在正常文件導入的位置了。現在完完整整就是一個單頁面組件。只是移除了close和right-icon的slot和方法。
鏈接: 這是vant-ui的官網效果,屬性也是根據官方去進行傳遞使用
調用代碼塊
<template><div style="width: 360px"><!-- <marquee left-icon="volume-o" scrollable text="無論我們能活多久,我們能夠享受的只有無法分割的此刻,此外別無其他。"></marquee> --><marquee scrollable wrapable><p>無論我們能活多久,我們能夠享受的只有無法分割的此刻,此外別無其他。</p></marquee></div> </template><script> import marquee from "@/components/marquee.vue"; export default {name: "Index",components: { marquee },data() {return { };},mounted() { },methods: {},// End }; </script>組件代碼塊
<template><div role="alert" :class="bem({ wrapable })" :style="wrapStyl" v-show="show" @click="onClickIcon"><i v-if="leftIcon" :class="[bem('left-icon'), leftIcon]" /><div ref="wrap" role="marquee" :class="bem('wrap')"><div ref="content" :class="[bem('content'), (!!scrollable && !wrapable) && 'ellipsis']" :style="contentStyl" @transitionend="onTransitionEnd"><slot>{{ text }}</slot></div></div></div> </template><script> const isDef = (val) => val !== undefined && val !== null; const raf = fn => window.requestAnimationFrame.call(window, fn);// double raf for animation function doubleRaf(fn) {raf(raf.bind(null, fn)); }export default {name: 'marquee',props: {text: String,mode: String,color: String,leftIcon: String,wrapable: Boolean,background: String,scrollable: { type: Boolean, default: null },delay: { type: [Number, String], default: 1 },speed: { type: [Number, String], default: 50 }},data() {return {show: true,offset: 0,duration: 0,wrapWidth: 0,contentWidth: 0}},activated() {this.start();this.bind((bind) => { bind(window, 'pageshow', this.start); });},mounted() {this.bind((bind) => { bind(window, 'pageshow', this.start); });},computed: {wrapStyl() {const { color, background } = this;return { color, background }},contentStyl() {return { transform: this.offset ? "translateX(" + this.offset + "px)" : '', transitionDuration: this.duration + 's' }},bem() {return (...cls) => this.createBem('grid-item')(...cls);}},methods: {onClickIcon(event) {return;if (this.mode === 'closeable') {this.show = false;this.$emit('close', event);}},onTransitionEnd() {this.offset = this.wrapWidth;this.duration = 0; // 等待Vue渲染偏移raf(() => {// 使用雙raf確保動畫可以開始doubleRaf(() => {this.offset = -this.contentWidth;this.duration = (this.contentWidth + this.wrapWidth) / this.speed;this.$emit('replay');});});},reset() {this.offset = 0;this.duration = 0;this.wrapWidth = 0;this.contentWidth = 0;},start() {const delay = isDef(this.delay) ? this.delay * 1000 : 0;this.reset();clearTimeout(this.startTimer);this.startTimer = setTimeout(() => {const refsNode = this.$refs;const wrap = refsNode.wrap;const content = refsNode.content;if (!wrap || !content || this.scrollable === false) return;const wrapWidth = wrap.getBoundingClientRect().width;const contentWidth = content.getBoundingClientRect().width;if (this.scrollable || contentWidth > wrapWidth) {doubleRaf(() => {this.offset = -contentWidth;this.duration = contentWidth / this.speed;this.wrapWidth = wrapWidth;this.contentWidth = contentWidth;});}}, delay);},bind(handler) {handler.call(this, (target, event, handler, passive) => {if (passive === void 0) passive = false;target.addEventListener(event, handler, false);}, true);},unbind() {handler.call(this, (target, event, handler) => {target.removeEventListener(event, handler);}, true);},createBem(name) {/*** bem helper* b() // 'button'* b('text') // 'button__text'* b({ disabled }) // 'button button--disabled'* b('text', { disabled }) // 'button__text button__text--disabled'* b(['disabled', 'primary']) // 'button button--disabled button--primary'*/return function (el, mods) {function gen(name, mods) {if (!mods) return '';if (typeof mods === 'string') return " " + name + "--" + mods;if (Array.isArray(mods)) return mods.reduce((ret, item) => ret + gen(name, item), '');return Object.keys(mods).reduce((ret, key) => ret + (mods[key] ? gen(name, key) : ''), '');}if (el && typeof el !== 'string') {mods = el; el = '';}el = el ? name + "__" + el : name;return "" + el + gen(el, mods);};}},deactivated() {this.unbind((bind) => { bind(window, 'pageshow', this.start);});},beforeDestroy() {this.unbind((bind) => { bind(window, 'pageshow', this.start);});} } </script><style scoped> .notice-bar {position: relative;display: -webkit-box;display: -webkit-flex;display: flex;-webkit-box-align: center;-webkit-align-items: center;align-items: center;height: 40px;padding: 0 16px;color: #ed6a0c;font-size: 14px;line-height: 24px;background-color: #fffbe8; }.notice-bar__left-icon, .notice-bar__right-icon {min-width: 24px;font-size: 16px; }.notice-bar__right-icon {text-align: right;cursor: pointer; }.notice-bar__wrap {position: relative;display: -webkit-box;display: -webkit-flex;display: flex;-webkit-box-flex: 1;-webkit-flex: 1;flex: 1;-webkit-box-align: center;-webkit-align-items: center;align-items: center;height: 100%;overflow: hidden; }.notice-bar__content {position: absolute;white-space: nowrap;-webkit-transition-timing-function: linear;transition-timing-function: linear; }.notice-bar__content.ellipsis {max-width: 100%; }.notice-bar--wrapable {height: auto;padding: 8px 16px; }.notice-bar--wrapable .notice-bar__wrap {height: auto; }.notice-bar--wrapable .notice-bar__content {position: relative;white-space: normal;word-wrap: break-word; } </style>總結
以上是生活随笔為你收集整理的Vue文字走马灯(文字轮播)组件的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 【POJ 3311】Hie with t
- 下一篇: Linux CGroup之freezer