一、使用icomoon
1.生成和下載圖標相關文件
先使用icomoon獲取我們要使用的圖標,例如播放、暫停、停止、全屏等圖標。
icomoon網站:https://icomoon.io/app/#/select
在其中選擇我們需要的圖標:

然后點擊右下角的 "Generate Font":

將我們圖標的名字修改成自己想要的。
然后點擊右下角的 "Download"。會幫我們下載一個zip壓縮包。
解壓,獲取以下文件:

2.使用style.css
將style.css文件和fonts文件夾拷貝到項目中(路徑自己決定):

在main.js中導入style.css:
import "./styles/style.css"
導入后,就可以使用圖標了。
二、自定義播放器代碼結構
1.基本代碼結構
MyVideo.vue:
<template>
<div class="video">
<video>
<source src="https://video.pearvideo.com/mp4/third/20200212/cont-1651180-11487675-112807-hd.mp4"/>
</video>
<div class="controls">
<div class="con_left">
<span class="icon-play"></span>
<span class="icon-stop"></span>
<span>00:00/10:00</span>
</div>
<div class="con_right">
<span class="icon-volume"></span>
<span class="icon-enlarge"></span>
</div>
</div>
</div>
</template>
<script>
export default {
name: "MyVideo",
}
</script>
<style scoped>
.video {
position: relative;
}
.video video {
width: 100%;
height: 100%;
}
.controls {
width: 100%;
height: 40px;
position: absolute;
bottom: 0;
left: 0;
background-color: #99a9bf;
display: flex;
justify-content: space-between;
align-items: center;
}
.controls span {
padding: 0 5px;
color: #fff;
}
</style>
這是自定義播放器的基本代碼結構,其中我們使用class指定了幾個icomoon圖標。
2.當前效果

三、實現controls中的各功能
<template>
<div class="video" ref="video">
<video ref="myvideo" @canplay="getTotalTime" @timeupdate="timeUpdate">
<source :src="src"/>
</video>
<div class="controls">
<div class="con_left">
<span @click="togglePlay" :class="{'icon-play':isPaused,'icon-pause':!isPaused,'cursor':true}"></span>
<span @click="stopPlay" class="icon-stop cursor"></span>
<span>{{currentTime}}/{{totalTime}}</span>
</div>
<div class="con_right">
<span @click="toggleMuted" :class="{'icon-volume':!isMuted,'icon-volume-mute':isMuted,'cursor':true}"></span>
<span @click="toggleFullScreen"
:class="{'icon-enlarge':!isFullScreen ,'icon-shrink':isFullScreen,'cursor':true}"></span>
</div>
</div>
</div>
</template>
<script>
export default {
name: "MyVideo",
props: [
'src' // 這里接收父組件傳來的src參數,視頻的url
],
data() {
return {
// 用於存放<video>標簽對象,方便調用原生API
myvideo: null,
video: null,
// 是否暫停,用於控制播放與暫停
isPaused: true,
// 播放當前時間
currentTime: "00:00",
totalTime: "00:00",
// 聲音是否靜音
isMuted: false,
// 是否全屏
isFullScreen: false,
}
},
mounted() {
// 加載完畢后,先獲取<video>標簽DOM對象
this.myvideo = this.$refs.myvideo
this.video = this.$refs.video
},
methods: {
// 播放與暫停,注意,這里isPause的變化,對應圖標的變化
togglePlay() {
this.isPaused = !this.isPaused;
if (this.isPaused) {
this.myvideo.pause()
} else {
this.myvideo.play()
}
},
// 停止播放
stopPlay() {
this.myvideo.pause()
this.myvideo.currentTime = 0
// 停止播放了,要將播放圖標從暫停切換到播放,isPaused為true的時候,圖標是播放
this.isPaused = true
},
// 定義一個時間處理函數,例如將100秒,處理成1:40
timeFormat(time) {
let minute = Math.floor((time % 3600) / 60); // 取余
let second = Math.floor(time % 60);
minute = minute < 10 ? "0" + minute : minute;
second = second < 10 ? "0" + second : second;
return `${minute}:${second}`;
},
// 當事件oncanplay觸發時,獲取視頻的總時間信息,然后通過timeFormat函數處理成00:00的格式,並渲染到template中
getTotalTime() {
this.currentTime = this.timeFormat(this.myvideo.currentTime);
this.totalTime = this.timeFormat(this.myvideo.duration);
},
// 時間timeupdate觸發時,更新當前播放時間
timeUpdate() {
this.currentTime = this.timeFormat(this.myvideo.currentTime)
},
// 聲音是否靜音
toggleMuted() {
this.isMuted = !this.isMuted
this.myvideo.muted = !this.myvideo.muted
},
// 切換全屏,注意,這里進入全屏時,使用的元素是this.video,而不是this.myvideo。video是myvideo的父標簽,這樣控制條才能正確顯示
toggleFullScreen(event) {
let fullscreen = document.webkitIsFullScreen || document.fullscreen;
this.isFullScreen = fullscreen
if (!this.isFullScreen) {
this.isFullScreen = !this.isFullScreen
const inFun = this.video.requestFullscreen || this.video.webkitRequestFullScreen;
inFun.call(this.video);
} else {
this.isFullScreen = !this.isFullScreen
const exitFun = document.exitFullscreen || this.document.webkitExitFullScreen;
exitFun.call(document);
}
}
}
}
</script>
<style scoped>
.video {
position: relative;
}
video::-webkit-media-controls {
display: none !important;
}
.video video {
width: 100%;
height: 100%;
}
.controls {
width: 100%;
height: 30px;
position: absolute;
bottom: 0;
left: 0;
background-color: black;
opacity: 0.5;
display: flex;
justify-content: space-between;
align-items: center;
}
.controls span {
padding: 0 5px;
color: #fff;
}
.cursor {
cursor: pointer;
}
</style>
四、打包組件
1.打包環境
由於新版本的vue-cli使用webpack模板創建的vue環境,打包一直出錯,所以我們在這里選擇使用webpack-simple模板創建的環境作為打包環境。
webpack模板和webpack-simple模板有一些不同,例如配置文件的結構。我們以webpack-simple模板環境為例:

2.components中的index.js
import MyVideo from './MyVideo.vue' MyVideo.install = function (Vue) { if (this.installed) return; Vue.component(MyVideo.name, MyVideo) }; // auto install if (typeof window !== 'undefined' && window.Vue) { MyVideo.install(window.Vue); } export default MyVideo
3.修改webpack.config.js配置文件
module.exports = { entry: './src/components/index.js', externals:{ vue:'vue' }, output: { path: path.resolve(__dirname, './dist'), publicPath: '/dist/', filename: 'MyVideo.js', library:'MyVideo', libraryTarget:'umd', umdNamedDefine: true }, ... ...
entry要修改為我們需要打包的組件同目錄下的index.js(該文件編寫參考2.節)
externals是排除不需要打包的組件,這里指定vue不打包
output設置輸出目錄以及輸出名稱為MyVideo.js
這里注意:
如果打包的組件中使用了一些特殊的文件,例如ttf字體文件等,我們需要安裝對應的loader來對其進行處理,在該配置文件中需要添加對應的配置,例如:
{ test: /\.(woff2?|eot|ttf|otf)$/, loader: 'file-loader', options: { name: '[name].[ext]?[hash]' } }
4.修改package.json配置文件
{ "name": "leeoovideo123", "main": "dist/MyVideo.js", "description": "Leeoo Video Component", "version": "1.0.0", "author": "leokale", "license": "MIT", "private": false, "scripts": { "dev": "cross-env NODE_ENV=development webpack-dev-server --open --hot", "build": "cross-env NODE_ENV=production webpack --display-error-details --config webpack.config.js" }, "files": [ "dist" ], ... ...
標黃部分都很重要:
name表示上傳包的名稱(放在npm倉庫中的名稱),下載時也是指定這個名字。注意,名字中不能有大寫,例如leeooPlayer就不行。
main表示上傳哪個文件
private設置非私有
files表示要打包的目錄,這里我們只打包了dist目錄,如果該組件使用到了其他的文件,例如字體文件在assets目錄中,css文件在src/styles目錄中,則都需要打包進去:
"files": [ "dist", "assets", "src/styles" ],
如果文件沒打包齊全,可能組件的樣式,字體,圖標等無法正確顯示。
5.編寫README
對於組件的安裝和使用方法,可以寫到README文件中。
README的內容會顯示在npm網站中。
6.打包
配置文件修改完畢后,使用命令進行打包:
npm run build
會在dist目錄中生成js文件:

至此,組件打包完畢。
五、上傳到npm倉庫
1.注冊npm
npm網站:https://www.npmjs.com/
1)注冊個人賬號
2)認證郵箱(一定要去郵箱里點擊鏈接認證)
2.上傳組件
1)運行命令登錄:
npm login
按提示輸入npm的賬號密碼和郵箱。
2)在項目目錄下運行命令
npm publish
上傳成功后,可以在npm網站的個人packages中查看到上傳成功的包。
如果上傳的組件名(package.json中配置的name)與倉庫中已存在的包名字相同或很像,則會提示報錯,需要重新修改名稱再上傳。
3)刪除包
npm unpublish
注意,刪除包后,如果再上傳同名字的包會有24小時的限制。
3.更新組件版本
只需要保證上傳組件的名稱一致,然后修改package.json的版本,重新打包上傳即可。
六、下載和使用包
1.npm安裝
npm i leeoovideo123 -S
2.cnpm安裝
cnpm每10分鍾從npm同步數據,所以10分鍾后cnpm就可以安裝我們上傳的包了
cnpm i leeoovideo123 -S
3.檢查包是否安裝
在node_modules目錄下可以找到我們安裝的包:

在檢查package.json:
"dependencies": { "leeoovideo123": "^1.0.0", "vue": "^2.5.2", "vue-router": "^3.0.1" },
如果沒有對應的配置,可以手工添加。
4.導入和使用包
在main.js中:
import MyVideo from 'leeoovideo123' import 'leeoovideo123/src/styles/style.css' Vue.use(MyVideo)
這里注意,雖然我們上傳到npm的包名是"leeoovideo123",但是組件的名稱實際上是"MyVideo"。
所以,我們在使用的時候一定要導入"MyVideo"。
盡量在打包時保證組件名與包名一致,以免使用不便(可以在ReadMe中說明)。
在我們的組件App中使用:
// App.vue <template> <div id="app"> <MyVideo src="https://video.pearvideo.com/mp4/third/20200212/cont-1651180-11487675-112807-hd.mp4"></MyVideo> </div> </template>
頁面效果:

(✿◠‿◠)
