一,前言
总结下最近工作上在移动端实现的一个跑马灯效果,最终效果如下:
印象中好像 html 标签的'marquee'的直接可以实现这个效果,不过 HTML 标准中已经废弃了'marquee' 标签
既然 HTML 标准已经废弃了这个标签,现在工作上用的是 vue,所以想着能不能自己也发布一个基于 Vue 的文字跑马灯组件包,这样别人可以通过 npm install ... 就可以用,想想还有点激动,于是开始我的第一个 npm 组件之旅!
二,用 npm 发布一个包
有点惭愧,之前通过 npm install ... 安装 package 包时,我是不知道 package 包存在哪里,在 github 上?折腾一番才知道是在 npm 上发布的.
2.1 npm 发布包流程
进入 官网 ,注册帐号
进入已经写好的组件, 登录 npm 帐号
执行 npm publish,最先遇到问题好像是这个
这里注意的是因为国内网络问题,许多小伙伴把 npm 的镜像代理到淘宝或者别的地方了,这里要设置回原来的镜像.
npm config set registry=http://registry.npmjs.org
后面又遇到
这里我还特意查了下 ENEEDAUTH 错误,可是却没看后面的提示:
You need to authorize this machine using 'npm adduser'
所以这里需要 npm adduser
(发布的包的名字也要注意,有可能会有重名问题,像我这个组件包本来取名为 vue-marquee,后面在 npm 上搜到已经有这个包了,不过他做的是垂直方向的跑马灯.所以我把这个为了区分这个组件包是水平方向的,改名为 vue-marquee-ho)
三,基于 Vue 的文字跑马灯组件
大致了解怎么发组件包以后,我们再来看看需要发布出去的组件包怎么写的.
3.1 初始化组件
这里我还是用到 vue-cli,虽然有很多东西不需要,因为对这个比较熟悉,所以还是按照这个步骤来,初始化该组件
vue init webpack vue-marquee-ho
cd vue-marquee-ho
cnpm install // 安装依赖包
npm run dev // 启动服务
3.2 修改配置文件
首先看 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 组件
3.3 Marquee 组件
思路:标签里的文字所占的宽度超过外面的 div 宽度时,增加一个内容相同的标签.这里 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:
& lt;
style & gt;.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 % );
}
} & lt;
/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 不会有问题.
3.4 打包生成 dist/vue-marquee.min.js
通过 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 次的提交记录,不容易呀,源代码地址:
vue-marquee-ho
希望能得到大家的 star ^_^
参考资料:
, http://www.jianshu.com/p/36d3e0e00157
, http://www.cnblogs.com/marymei0107/p/6339710.html
, http://blog.csdn.net/gamesdev/article/details/49018629
, https://segmentfault.com/a/1190000006250554
, https://stackoverflow.com/questions/
, http://www.mamicode.com/info-detail-1694072.html
7, http://blog.csdn.net/crper/article/details/50722753 (虽然调试技巧我还是没学会 (✿◡‿◡))
, https://github.com/xiaokaike/vue-color
, https://github.com/li-xianfeng/vue-marquee
来源: http://www.cnblogs.com/wj204/p/6868375.html