封裝組件
我這里選擇的是表情的一個組件例子胸私,npm 包名稱 aimee-plugins-emoji
首先創(chuàng)建組件項目
通過Vue 腳手架創(chuàng)建簡易webpage項目
vue init webpack-simple aimee-plugins-emoji
生成后的目錄如下
安裝依賴 并 運行
cd webpack-simple aimee-plugins-emoji
npm install
npm run dev
添加自己的組件
創(chuàng)建組件文件
<!-- 留言評論模塊 -->
<template>
<div class="box">
<div class="face-box">
<textarea name="face" ref="textareaBox" cols="30" rows="10" v-model="message" placeholder="說點什么呢``" ></textarea>
<div class="face-sina">
<div class="face-logo" @click="pBody=!pBody">
<span>sina表情</span>
</div>
<div class="face-sina-body" v-show="pBody">
<ul class="face-sina-items face-sina-items-show">
<li v-for="(item, index) in faceList" :key="index" class="face-sina-item" @click="choseHandle(item.title)">
<img :src="require('../../assets/emot/image/'+item.url)" alt="">
</li>
</ul>
</div>
</div>
</div>
<div class="face-show-box" v-html="messageshow">
</div>
</div>
</template>
<script>
export default {
name: 'aimee-emoji',
data() { //選項 / 數(shù)據(jù)
return {
faceList:[//表情包和表情路徑
{'title':'微笑','url':'weixiao.gif'},
{'title':'嘻嘻','url':'xixi.gif'},
{'title':'哈哈','url':'haha.gif'},
{'title':'可愛','url':'keai.gif'},
{'title':'可憐','url':'kelian.gif'},
{'title':'挖鼻','url':'wabi.gif'},
{'title':'吃驚','url':'chijing.gif'},
{'title':'害羞','url':'haixiu.gif'},
{'title':'擠眼','url':'jiyan.gif'},
{'title':'閉嘴','url':'bizui.gif'},
{'title':'鄙視','url':'bishi.gif'},
{'title':'愛你','url':'aini.gif'},
{'title':'淚','url':'lei.gif'},
{'title':'偷笑','url':'touxiao.gif'},
{'title':'親親','url':'qinqin.gif'},
{'title':'生病','url':'shengbing.gif'},
{'title':'太開心','url':'taikaixin.gif'},
{'title':'白眼','url':'baiyan.gif'},
{'title':'右哼哼','url':'youhengheng.gif'},
{'title':'左哼哼','url':'zuohengheng.gif'},
{'title':'噓','url':'xu.gif'},
{'title':'衰','url':'shuai.gif'},
{'title':'吐','url':'tu.gif'},
{'title':'哈欠','url':'haqian.gif'},
{'title':'抱抱','url':'baobao.gif'},
{'title':'怒','url':'nu.gif'},
{'title':'疑問','url':'yiwen.gif'},
{'title':'饞嘴','url':'chanzui.gif'},
{'title':'拜拜','url':'baibai.gif'},
{'title':'思考','url':'sikao.gif'},
{'title':'汗','url':'han.gif'},
{'title':'困','url':'kun.gif'},
{'title':'睡','url':'shui.gif'},
{'title':'錢','url':'qian.gif'},
{'title':'失望','url':'shiwang.gif'},
{'title':'酷','url':'ku.gif'},
{'title':'色','url':'se.gif'},
{'title':'哼','url':'heng.gif'},
{'title':'鼓掌','url':'guzhang.gif'},
{'title':'暈','url':'yun.gif'},
{'title':'悲傷','url':'beishang.gif'},
{'title':'抓狂','url':'zhuakuang.gif'},
{'title':'黑線','url':'heixian.gif'},
{'title':'陰險','url':'yinxian.gif'},
{'title':'怒罵','url':'numa.gif'},
{'title':'互粉','url':'hufen.gif'},
{'title':'書呆子','url':'shudaizi.gif'},
{'title':'憤怒','url':'fennu.gif'},
{'title':'感冒','url':'ganmao.gif'},
{'title':'心','url':'xin.gif'},
{'title':'傷心','url':'shangxin.gif'},
{'title':'豬','url':'zhu.gif'},
{'title':'熊貓','url':'xiongmao.gif'},
{'title':'兔子','url':'tuzi.gif'},
{'title':'喔克','url':'ok.gif'},
{'title':'耶','url':'ye.gif'},
{'title':'棒棒','url':'good.gif'},
{'title':'不','url':'no.gif'},
{'title':'贊','url':'zan.gif'},
{'title':'來','url':'lai.gif'},
{'title':'弱','url':'ruo.gif'},
{'title':'草泥馬','url':'caonima.gif'},
{'title':'神馬','url':'shenma.gif'},
{'title':'囧','url':'jiong.gif'},
{'title':'浮云','url':'fuyun.gif'},
{'title':'給力','url':'geili.gif'},
{'title':'圍觀','url':'weiguan.gif'},
{'title':'威武','url':'weiwu.gif'},
{'title':'話筒','url':'huatong.gif'},
{'title':'蠟燭','url':'lazhu.gif'},
{'title':'蛋糕','url':'dangao.gif'},
{'title':'發(fā)紅包','url':'fahongbao.gif'}
],
pBody:false,//是否展示表情框
message: '',
lastposition: 0
}
},
computed: {
messageshow(){
var pat01 = /\[[\u4e00-\u9fa5]+\]/g;
var pat02 = /\[[\u4e00-\u9fa5]+\]/;
var content = this.message.match(pat01);
var str = this.message;
if(content){
for(var i=0;i<content.length;i++){
for(var j=0;j<this.faceList.length;j++){
if("["+this.faceList[j].title +"]" == content[i]){
var src = this.faceList[j].url;
break;
}
}
str = str.replace(pat02,'<img src="'+require('../../assets/emot/image/'+src)+'"/>');
}
}
return str
}
},
methods: {
getCursortPosition (ctrl) {
var CaretPos = 0 // IE Support
if (document.selection) {
ctrl.focus()
var Sel = document.selection.createRange()
Sel.moveStart('character', -ctrl.value.length)
CaretPos = Sel.text.length
} else if (ctrl.selectionStart || ctrl.selectionStart == '0') { // Firefox support
CaretPos = ctrl.selectionStart
}
return (CaretPos)
},
choseHandle(title) {
var position = this.getCursortPosition(this.$refs.textareaBox)
this.message = this.message.substring(0, position) + '[' + title + ']' + this.message.substring(position, this.message.length)
this.pBody = false
}
}
}
</script>
<style lang="less">
.box{
width:600px;
margin: 0 auto;
}
.face-box textarea{
background:#f4f6f7;
width:100%;
height:100px;
margin-bottom: 10px;
border-radius: 5px;
box-sizing: border-box;
}
.face-sina{
position: relative;
z-index: 1;
}
.face-sina .face-logo ,.face-sina .face-showbtn{
position: relative;
border-radius: 4px;
color:#444;
display: inline-block;
background: #fff;
border:1px solid #ddd;
font-size: 13px;
padding:0 6px;
cursor: pointer;
height:30px;
box-sizing: border-box;
z-index: 2;
line-height: 30px;
margin-right:20px;
transition:all 0.3s ease;
}
.face-sina .face-logo:hover,.face-sina .face-showbtn:hover{
background-color: #f4f6f7;
}
.face-sina .face-sina-body{
position: absolute;
background: #fff;
border:1px solid #ddd;
z-index: 1;
top:29px;
border-radius: 0 4px 4px 4px;
}
.face-sina-open .face-sina-body{
display: block;
}
.face-sina-open .face-logo{
border-radius: 4px 4px 0 0;
}
.face-sina-open .face-logo:hover{
animation:none;
-webkit-animation:none;
}
.face-sina .face-sina-items {
max-height: 197px;
overflow: scroll;
font-size: 0;
padding:10px;
z-index: 1
}
.face-sina .face-sina-items .face-sina-item{
background: #f7f7f7;
padding:5px 10px;
border-radius: 5px;
display: inline-block;
margin: 0 10px 12px 0;
transition: 0.3s;
line-height: 19px;
font-size: 20px;
cursor: pointer;
}
.face-sina .face-sina-items .face-sina-item:hover{
background: #eee;
box-shadow: 0 2px 2px 0 rgba(0,0,0,.14),
0 3px 1px -2px rgba(0,0,0,.2),
0 1px 5px 0 rgba(0,0,0,.12);
animation:a 5s infinite ease-in-out;
-webkit-animation:a 5s infinite ease-in-out;
}
.face-show-box{
width:100%;
margin: 300px 0;
padding:20px;
border: 1px solid #999;
background: #f4f6f7;
box-sizing: border-box;
border-radius: 5px;
vertical-align: middle;
img{
vertical-align: middle;
}
}
</style>
在main.js 入口文件的同級目錄下床玻,添加index.js 打包的入口文件
import emoji from './plugins/emoji/index.vue'
const components = [
emoji
]
const install = function (Vue, opts = {}) {
components.map(component => {
Vue.component(component.name, component)
})
}
/* 支持使用標(biāo)簽的方式引入 */
if (typeof window !== 'undefined' && window.Vue) {
install(window.Vue)
}
export default {install, emoji}
可以在入口文件main.js 中正常引用
import aimeePluginsEmoji from './index.js'
Vue.use(aimeePluginsEmoji)
這樣在項目中任何地方可以直接使用組件,如下我在app.vue 文件中直接引入<aimee-emoji></aimee-emoji>使用
<template>
<div id="app">
<aimee-emoji></aimee-emoji>
</div>
</template>
<script>
export default {
name: 'app',
data () {
return {
msg: 'Welcome to Your Vue.js App'
}
}
}
</script>
<style>
#app {
font-family: 'Avenir', Helvetica, Arial, sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
text-align: center;
color: #2c3e50;
margin-top: 60px;
}
</style>
到這個地方項目已經(jīng)創(chuàng)建完了 淀弹,接下來就是修改配置文件
修改配置文件
主要修改的配置文件為 webpack.config.js 和 package.json
webpack.config.js設(shè)置
首先項目中因為有圖片的引用债鸡,需要設(shè)置圖片為base64捌木,可以通過設(shè)置limit 的值來實現(xiàn)。
{
test: /\.(png|jpg|gif|svg)$/,
loader: 'url-loader',
options: {
limit: 50000000,
name: '[name].[ext]?[hash]'
}
}
設(shè)置入口和輸出路徑
entry: process.env.NODE_ENV === 'production'? './src/index.js' : './src/main.js',
output: {
path: path.resolve(__dirname, './dist'),
publicPath: '/dist/',
filename: 'aimee-plugins-emoji.js',
library: 'aimee-plugins-emoji', // 指定的就是你使用require時的模塊名
libraryTarget: 'umd', // libraryTarget會生成不同umd的代碼,可以只是commonjs標(biāo)準(zhǔn)的焕窝,也可以是指amd標(biāo)準(zhǔn)的蹬挺,也可以只是通過script標(biāo)簽引入的
umdNamedDefine: true, // 會對 UMD 的構(gòu)建過程中的 AMD 模塊進(jìn)行命名。否則就使用匿名的 define
},
package.json設(shè)置
設(shè)置private屬性為false它掂,默認(rèn)為true巴帮,npm 發(fā)布的時候如果為true會失敗。
添加node_module 的入口文件設(shè)置虐秋,"main": "dist/aimee-plugins-emoji.js"
"private": false,
"main": "dist/aimee-plugins-emoji.js",
上傳到git 倉庫管理
注意 這里gitignore中需要取消對dist文件夾的忽略
倉庫管理項目文件
發(fā)布到npm
前提:需要注冊npm 賬號并激活
登錄 npm login
需要看清楚是否是注冊的registry榕茧,如果是淘寶的會報錯
發(fā)布 npm publish

生成后的npm包https://www.npmjs.com/package/aimee-plugins-emoji
如果要修改組件內(nèi)容,需要修改package.json中的版本號客给,然后重新發(fā)布
在項目中使用
通過npm install aimee-plugins-emoji --save-dev 安裝到本地
在 項目的main.js 中引用
import aimeePluginsEmoji from 'aimee-plugins-emoji'
Vue.use(aimeePluginsEmoji)
組件中可以通過<aimee-emoji></aimee-emoji> 使用