總結下最近工做上在移動端實現的一個跑馬燈效果,最終效果以下:css
印象中好像HTML標籤的‘marquee’的直接能夠實現這個效果,不過 HTML標準中已經廢棄了‘marquee’標籤
既然HTML標準已經廢棄了這個標籤,如今工做上用的是Vue,因此想着能不能本身也發佈一個基於Vue的文字跑馬燈組件包,這樣別人能夠經過npm install ...就能夠用,想一想還有點激動,因而開始個人第一個npm組件之旅!html
有點慚愧,以前經過npm install ...安裝package包時,我是不知道package包存在哪裏,在github上?折騰一番才知道是在npm上發佈的。vue
進入官網,註冊賬號node
進入已經寫好的組件, 登陸npm賬號 webpack
執行npm publish,最早遇到問題好像是這個 git
這裏注意的是由於國內網絡問題,許多小夥伴把npm的鏡像代理到淘寶或者別的地方了,這裏要設置回原來的鏡像。
npm config set registry=http://registry.npmjs.org
github
後面又遇到 web
這裏我還特地查了下ENEEDAUTH錯誤,但是卻沒看後面的提示:You need to authorize this machine using 'npm adduser'
因此這裏須要npm adduser
(發佈的包的名字也要注意,有可能會有重名問題,像我這個組件包原本取名爲vue-marquee,後面在npm上搜到已經有這個包了,不過他作的是垂直方向的跑馬燈。因此我把這個爲了區分這個組件包是水平方向的,更名爲vue-marquee-ho)vue-cli
大體瞭解怎麼發組件包之後,咱們再來看看須要發佈出去的組件包怎麼寫的。npm
這裏我仍是用到vue-cli,雖然有不少東西不須要,由於對這個比較熟悉,因此仍是按照這個步驟來,初始化該組件
vue init webpack vue-marquee-ho cd vue-marquee-ho cnpm install // 安裝依賴包 npm run dev // 啓動服務
首先看package.json
"name": "vue-marquee-ho", "version": "1.2.1", "description": "A Vue component to marquee", "author": "wangjuan", "private": false, "license": "MIT", "main": "dist/vue-marquee.min.js", "scripts": { "dev": "node build/dev-server.js", "start": "node build/dev-server.js", "build": "node build/build.js", "test": "node build/test.js" }, "dependencies": { "vue": "^2.2.6" }, "repository": { "type": "git", "url": "git+https://github.com/wj704/vue-marquee-ho.git" },
由於這個組件包是能公用的,因此"private": false,
而後 "main": "dist/vue-marquee.min.js",
這裏的配置意思是,別人用這個包 import VueMarquee from 'vue-marquee-ho';
時,引入的文件。
能夠看出,這個vue-marquee-ho最終須要打包出一個js文件,因此咱們須要修改webpack.prod.config.js文件
var webpackConfig = merge(baseWebpackConfig, { module: { rules: utils.styleLoaders({ sourceMap: config.build.productionSourceMap, extract: true }) }, devtool: config.build.productionSourceMap ? '#source-map' : false, // output: { // path: config.build.assetsRoot, // filename: utils.assetsPath('js/[name].[chunkhash].js'), // chunkFilename: utils.assetsPath('js/[id].[chunkhash].js') // }, output: { path: config.bundle.assetsRoot, publicPath: config.bundle.assetsPublicPath, filename: 'vue-marquee.min.js', library: 'VueMarquee', libraryTarget: 'umd' }, plugins: [ // http://vuejs.github.io/vue-loader/en/workflow/production.html new webpack.DefinePlugin({ 'process.env': env }), new webpack.optimize.UglifyJsPlugin({ compress: { warnings: false }, sourceMap: true }), // extract css into its own file new ExtractTextPlugin({ // filename: utils.assetsPath('css/[name].[contenthash].css') filename: 'vue-marquee.min.css' }), new OptimizeCSSPlugin() ] }) module.exports = webpackConfig
能夠看到個人output輸出配置改了下,而後有不少webpack.prod.config.js以前不須要的代碼去掉了,再看下對應的config配置,文件是config/index.js
bundle: { env: require('./prod.env'), assetsRoot: path.resolve(__dirname, '../dist'), assetsPublicPath: '/', assetsSubDirectory: '/', productionSourceMap: true, productionGzip: false, productionGzipExtensions: ['js', 'css'], bundleAnalyzerReport: process.env.npm_config_report },
至此配置差很少修改好了。接下來咱們看看實現關鍵功能的Marquee組件
思路:<span>標籤裏的文字所佔的寬度超過外面的div寬度時,增長一個內容相同的<span>標籤。這裏span標籤設置爲display: inline-block
;,能夠計算其寬度,把span標籤外面的父元素設置爲font-size: 0;display: inline-block;
,父級元素的寬度即爲二者寬度之和,也就是一個span標籤寬度的兩倍,而後將其父級元素經過CSS3動畫設置:
@keyframes marquee { 0% { transform: translateX(0); } 100% { transform: translateX(-50%);} }
便可完美實現跑馬燈效果。
具體代碼:
<template> <div class="marquee-box"> <div class="marquee-content" ref="out"> <p :class="run?speed:''"> <span class="text1" ref="in" >{{content}}</span> <span class="text2" v-if="showtwo||run">{{content}}</span> </p> </div> </div> </template>
js:
<script> export default { name: 'VueMarquee', data (){ return{ run: false, pWidth: '', } }, props: { content: { default: "暫無內容", type: String }, speed: { default: 'middle', type: String }, showtwo: { default: true } }, mounted (){ // let out = document.getElementById(this.pid.out).clientWidth; // let _in = document.getElementById(this.pid.in).clientWidth; var _this = this; this.$nextTick(()=>{ let out = _this.$refs.out.clientWidth; let _in = _this.$refs.in.clientWidth; _this.run=_in>out?true:false; }); } } </script>
css:
<style> .marquee-box { height: 50px; line-height: 50px; color: #000; font-size: 24px; background-size: 24px 24px; } .marquee-content{ overflow: hidden; width:100% } .marquee-content p{ display: inline-block; white-space: nowrap; margin: 0; font-size: 0; } .marquee-content span{ display: inline-block; white-space: nowrap; padding-right: 40px; font-size: 24px; } .quick{ -webkit-animation: marquee 5s linear infinite; animation: marquee 5s linear infinite; } .middle{ -webkit-animation: marquee 8s linear infinite; animation: marquee 8s linear infinite; } .slow{ -webkit-animation: marquee 25s linear infinite; animation: marquee 25s linear infinite; } @-webkit-keyframes marquee { 0% { -webkit-transform: translate3d(0,0,0); } 100% { -webkit-transform: translate3d(-50%,0,0); } } @keyframes marquee { 0% { transform: translateX(0); } 100% { transform: translateX(-50%);} } </style>
咱們知道 webpack.base.conf.js 中入口文件默認指定爲:
entry: { app: './src/main.js' },
因此,咱們只須要將main.js引入Marquee.vue組件就能夠。有兩種方式引入:
import VueMarquee from './Marquee.vue' export default VueMarquee; // var VueMarquee = require('./Marquee.vue'); // module.exports = VueMarquee
注意import 和module.exports不要一塊兒用,github看到其餘人提交的組件是這兩個一塊兒用的,這樣在windows下會報錯,好像mac不會有問題。
經過npm run build 便可看到目錄下生成了dist文件,dist文件裏有四個文件,分別是:
vue-marquee.min.js vue-marquee.min.js.map vue-marquee.min.css vue-marquee.min.css.map
咱們知道有一個這樣的文件.gitignore,裏面包含npm install時,不會安裝的東西,由於這裏要用到dist文件,因而我把.gitignore 裏的dist/去掉了。
.DS_Store node_modules/ npm-debug.log* yarn-debug.log* yarn-error.log*
打包好了後,經過npm publish 提交到npm上
須要屢次提交時注意修改package.json中的"version": "1.2.1",
我這裏已經提交了21次了(捂臉哭(┬_┬))
經過npm install vue-marquee-ho -s
安裝到相應的項目下,安裝成功以下圖所示:
到項目中的node_modules/目錄下將能夠看到:
須要用到該組件時能夠這樣引入(注意引入樣式)
import VueMarquee from 'vue-marquee-ho'; import Css from 'vue-marquee-ho/dist/vue-marquee.min.css' export default { name: 'app', components:{ "vue-marquee": VueMarquee }, }
看一個demo:
<template> <div id="app"> <div class="marquee-wrap" style="width: 100px;"><vue-marquee content="33333" class="two" :showtwo="false"></vue-marquee></div> <div class="marquee-wrap" style="width: 100px;"><vue-marquee content="22222" class="two" :showtwo="false"></vue-marquee></div> <div class="marquee-wrap" style="width: 100px;"><vue-marquee content="1" class="two" :showtwo="false"></vue-marquee></div> <router-view></router-view> </div> </template> <script> import VueMarquee from 'vue-marquee-ho'; import Css from 'vue-marquee-ho/dist/vue-marquee.min.css' export default { name: 'app', components:{ "vue-marquee": VueMarquee }, } </script>
效果:
總算髮布出去,能正常使用了!花了挺多時間的,雖然這個組件思路比較簡單,可是說不定別人能用上呢。這個組件的雛形代碼比如今多,不過以前在項目中直接引用也能正常使用。可是把他打包發佈出去再使用的過程,出了不少問題,反覆修改代碼,精簡代碼,最終終於成功了!21次的提交記錄,不容易呀,源代碼地址:
但願能獲得你們的star ^_^
參考資料:
一、http://www.jianshu.com/p/36d3...
二、http://www.cnblogs.com/maryme...
三、http://blog.csdn.net/gamesdev...
四、https://segmentfault.com/a/11...
五、https://stackoverflow.com/que...
六、http://www.mamicode.com/info-...
七、http://blog.csdn.net/crper/ar... (雖然調試技巧我仍是沒學會(✿◡‿◡))
八、https://github.com/xiaokaike/...
九、https://github.com/li-xianfen...