Electron + Vue + Vscode構建跨平臺應用(一)知識點補充
Electron + Vue + Vscode構建跨平臺應用(二)Electron + Vue環境搭建
Electron + Vue + Vscode構建跨平臺應用(三)利用webpack搭建vue項目
Electron + Vue + Vscode構建跨平臺應用(四)利用Electron-Vue構建Vue應用詳解
Electron + Vue + Vscode構建跨平臺應用(五)Electron-Vue項目源碼分析
Electron + Vue跨平臺應用(六)效果還不錯的登錄頁面
Electron + Vue跨平臺應用(七)基礎技法(一)
Electron + Vue跨平臺應用(八)基礎技法(二)
這篇主要對如下內容做個解答
2. 配置config/index.js中host爲0.0.0.0或者localhost的區別
3. Vue項目結構分析
3.1. build/webpack.dev.conf.js
3.2. process.env
4. vscode中利用git更新,上傳等操作
4.1 上傳
4.2 更新
4.3 查看歷史記錄
4.4 git的一些圖標說明
4.5 切換分支
4.6 clone到指定目錄
4.7 windows10上VsCode如何更改Git賬戶
4.8 開發分支合併到master分支
4.9 拉取代碼報錯:You have not concluded your merge
9. 調試
9.1 VConsole
9.2 Chrom / 360瀏覽器調試面板介紹
10. Vue 深度監聽/watch函數和計算屬性compute
node應用是由模塊組成的,那麼模塊之間必然存在將數據暴露給其他模塊使用,在暴露數據的時候,需要遵循兩個基本規範: CommonJS 模塊規範和ES6語法規範
在CommonJS 規範中,我們使用module.exports和exports來導出數據,通過require來引入數據,在查看源碼的時候,我們經常看到這種方式來導入和導出數據;
在CommonJS 規範中每一個文件就是一個模塊,我的理解是相當於java class,那麼在這個文件(類)中定義的屬性/方法是私有的,類似java的private屬性,那麼我們就會已module來代表當前文件(類),在這個module裏面有一個exports屬性,這個exports就相當於對外暴露的接口,當需要對外暴露數據的時候,只需要把對應的數據添加到exports屬性上即可;當其他模塊需要使用另一個模塊數據的時候,可以通過require方法用於加載模塊,require方法返回一個對象,通過該對象就可以讀取暴露的數據,如
var comJs = require('./sample.js')
vat xValue = comJs.x
第2行,通過comJs對象獲取暴露的x屬性
在ES6語法規範中,我們利用export和export default導出模塊,import導入模塊。我們先看下其用法說明
- export default表示一個模塊的默認輸出,所以在一個模塊中,export default有且僅有一個; export表示按需導出,所以可以用多個
- 使用export向外暴露的成員,只能使用{ }的形式來接收
- 導出的時候可以通過as來設置別名
- 導出一個變量/對象,應注意導出對象或者變量時不需要使用let或者var來定義,導出對象或者變量時需要注意使用{},如果寫爲export user則會報錯
列舉一些常用的導出的例子
// 導出自定義函數
export function add (a, b) {
return a + b
}
// 導出一個變量/對象,
const user = {name: '1', schole: '1'}
export {user}
// 通過別名的方式來導出
const world = {city: ''}
export {world as earth}
// 定義變量,export defalut來導出
const filterByName = name => {
if (name.length > 0) {
let temp = [{name: '5', schoole: '5'}]
return temp
}
return null
}
export default{
filterByName
}
再列舉一些常見的import用法
import xxx from 'xxx'
import person, {title, content as content1} from './xxx'
2. 配置config/index.js中host爲0.0.0.0或者localhost的區別
首先我們先弄明白config/index.js下host或者port這兩個屬性的作用是什麼
// Various Dev Server settings
host: '0.0.0.0', // can be overwritten by process.env.HOST
port: 8080, // can be overwritten by process.env.PORT, if port is in use, a free one will be determined
當我們執行npm run dev的時候,會得到下圖的提示
這裏的localhost就是index.js文件中的host,後面的端口號就是index.js中的port,當然如果index.js中設定的端口號如8080被佔用,則會使用一個新的端口號
那host爲0.0.0.0或者localhost到底有什麼區別?我們先說下host爲0.0.0.0的含義
0.0.0.0的配置代表本機的所有ip地址,這樣做的目的是在同一個局域網下,別的瀏覽器也可以訪問你運行的項目。
舉個例子:你配置vue-li項目的config/index.js文件中的host爲0.0.0.0,當你運行你的項目之後,別的協同開發的同學就可以在自己的電腦上看到你的項目效果了
此處我們應該注意:關閉掉你的防火牆
localhost: 他的含義就是綁定到localhost的服務只能被本機訪問
首先我們看下從npm run dev命令說起,他是執行package.json裏面的dev命令
"dev": "webpack-dev-server --inline --config build/webpack.dev.conf.js",
從上面的代碼我們可以分析出,他會編譯webpack.dev.conf.js,那麼我們打開它看下(截取部分代碼)
const http = require('http'),
httpProxy = require('http-proxy')
let internalIPAdress, proxyPort
proxyPort = 8000
httpProxy
.createProxyServer({
target: `http://${config.dev.host}:${config.dev.port}`
})
.listen(proxyPort) // See (†)
const HOST = process.env.HOST
const PORT = process.env.PORT && Number(process.env.PORT)
const devWebpackConfig = merge(baseWebpackConfig, {
module: {
rules: utils.styleLoaders({
sourceMap: config.dev.cssSourceMap,
usePostCSS: true
})
},
// cheap-module-eval-source-map is faster for development
devtool: config.dev.devtool,
// these devServer options should be customized in /config/index.js
devServer: {
clientLogLevel: 'warning',
historyApiFallback: {
rewrites: [
{
from: /.*/,
to: path.posix.join(
config.dev.assetsPublicPath,
'index.html'
)
}
]
},
hot: true,
contentBase: false, // since we use CopyWebpackPlugin.
compress: true,
host: HOST || config.dev.host,
port: PORT || config.dev.port,
open: config.dev.autoOpenBrowser,
overlay: config.dev.errorOverlay
? {
warnings: false,
errors: true
}
: false,
publicPath: config.dev.assetsPublicPath,
proxy: config.dev.proxyTable,
headers: {
'Access-Control-Allow-Origin': '*'
},
quiet: true, // necessary for FriendlyErrorsPlugin
watchOptions: {
poll: config.dev.poll
}
},
plugins: [
new DashboardPlugin(),
new webpack.DefinePlugin({
'process.env': require('../config/dev.env'),
__DEV__: true
}),
new webpack.HotModuleReplacementPlugin(),
new webpack.NamedModulesPlugin(), // HMR shows correct file names in console on update.
new webpack.NoEmitOnErrorsPlugin(),
// https://github.com/ampedandwired/html-webpack-plugin
new HtmlWebpackPlugin({
filename: 'index.html',
template: `${config.dev.folder}/index.html`,
inject: true,
isDev: true
}),
module.exports = new Promise((resolve, reject) => {
portfinder.basePort = process.env.PORT || config.dev.port
portfinder.getPort((err, port) => {
if (err) {
reject(err)
} else {
// publish the new Port, necessary for e2e tests
process.env.PORT = port
// add port to devServer config
devWebpackConfig.devServer.port = port
// Add FriendlyErrorsPlugin
devWebpackConfig.plugins.push(new FriendlyErrorsPlugin({
compilationSuccessInfo: {
messages: [`Your application is running here: http://${devWebpackConfig.devServer.host}:${port}`],
},
onErrors: config.dev.notifyOnErrors
? utils.createNotifierCallback()
: undefined
}))
resolve(devWebpackConfig)
}
})
})
第1行,利用require引入http組件,進行http通訊
第2行,引入http-proxy組件,當跨域通訊的時候,會利用http-proxy組件進行處理
第6行,創建http代理server
第14行,通過merge方法將webpack.base.conf.js裏面的配置和webpack.dev.conf.js裏面的配置進行整合
第25行,這裏就是我們創建server的地方,host指向 HOST || config.dev.host,這裏的config.dev.host就是config/index.js中的dev.host,port指向PORT || config.dev.port,這裏的config.dev.port就是config/index.js中的dev.port;所以通過設置config/index.js中的host和port就可以指定server的host和端口。即產生了如下效果
第51行,爲本地server設置代碼,其代理配置指向config.dev.proxyTable,所以我們通過設置config/index.js中的proxyTable即可做跨域處理
第53行,爲本地server設置Access-Control-Allow-Origin’: ‘*’,這樣做的目的是當我們設置host爲0.0.0.0的時候,其他機器就能訪問本機項目了,這樣做就解決了跨域的問題
第70行,當我們執行npm run dev命令之後,你會發現在dist目錄下有如下兩個文件
這裏的index.html的生成就是通過HtmlWebpackPlugin生成的
第72行,設置生成index.html生成的路徑
第78行,設置basePort的值,這個變量代表開啓服務的時候最小的端口值
第79行,通過getPort方法獲取到一個可運行的端口好
第84行,設置當前node.js進程中當前環境下的端口
第86行,設置啓動cli server的端口號
第91行,就是我們通過執行npm run dev之後打印的信息
所以在開發中運行npm run dev之後端口號總是隨意變化怎麼辦?
通過上面的分析,我們只要在第84行指定端口號爲你所希望的就好,比如你想讓服務端在端口爲8999上運行,那個代碼如下
當我們clone遠程代碼之後,就可以通過vscode中的源代碼管理器查看已經修改的部分,如圖所示
1:確認代碼之後,需要將代碼提交到暫存區,如下圖點擊 + 號,暫存所有更改
2:暫存完成會後,你會發現在暫存區(STAGED CHANGES)已經保存了對應的文件
3:提交代碼到本地庫,輸入提交信息 點擊enter完成
4: 此時代碼已經上傳到本地倉庫,這時候你需要更新下git服務器上最新代碼
5:更新完之後,需要推送本次修改的代碼到遠端,即完成上傳
1:使用Git History插件進行歷史記錄查看,在應用商店搜索git history,點擊install即可完成安裝(我這邊已經安裝了,所以顯示爲卸載)
2:安裝完成之後,你可以通過右擊文件打開git history,也可以點擊右上角的按鈕打開;這兩者的區別是
前者是查看該文件的歷史記錄,後者是查看整個git的歷史提交記錄
3:我們以點擊右上角的git history按鈕爲例查看下全部的提交記錄
4:點擊某一個文件會出現下圖,點擊對應列表項,即可查看文件內容,對比上一版本和查看該文件歷史記錄
如上圖表示在develop分支上,有0個更新,1個本地倉庫存儲需要上傳
點擊左下角的develop處,便會彈出如圖分支,選擇對應分支即可
git clone 項目代碼地址 代碼保存位置
如: git clone http://xxxxxx/xxx.git E:/workspace/
- 打開win10的控制版本(輸入控制面板進行搜索)
- 點擊用戶賬戶
- 點擊管理Window憑據
- 修改新的用戶名或者密碼
git checkout dev_20200101
- 更新開發分支代碼
git pull
- 切換到master分支
git checkout master
- 開發分支合併到master分支
git merge dev_20200101
- 推送代碼到遠程服務器,完成開發分支的代碼合併到master分支
git push
4.9 拉取代碼報錯:You have not concluded your merge
1. 如果你想保留本地的修改: 中止合併->重新合併->重新拉取git merge --abort
git reset --merge
git pull
- 如果不想保留本地的修改:棄本地代碼,遠端版本覆蓋本地版本
git fetch --all
git reset --hard origin/master
git fetch
npm run dev 和 npm run build執行的腳本是不一樣的,
npm run dev執行build/webpack.dev.conf.js完成開發模式下的打包
npm run build執行node build/build.js完成生產環境模式下的打包,
這兩者最大的區別就是
npm run dev模式下,process.env.NODE_ENV = ‘dev’
npm run dev模式下process.env.NODE_ENV = ‘production’
所以快捷切換URL代碼如下
const devUrl = 'https://www.baidu.com/'
const proUrl = 'https://www.aiqiyi.com'
let url = ‘’
process.env.NODE_ENV === 'development' ? url = devUrl : url = proUrl
相較於普通javascript,我們可以在通過document.createElement('script')
的方式創建一個script標籤,然後指定src的位置即可,具體代碼如下(該方法我封裝在Tools.js文件中)
// 加載外部js
loadScript (src, attributes = {}) {
return new Promise((resolve, reject) => {
const vds = document.createElement('script')
vds.type = 'text/javascript'
vds.async = true
vds.src = src
vds.onload = () => {
resolve()
}
vds.onerror = err => {
reject(err)
}
if (attributes && typeof attributes === 'object') {
for (let key in attributes) {
vds.setAttribute(key, attributes[key])
}
}
var s = document.getElementsByTagName('script')[0]
s.parentNode.insertBefore(vds, s)
})
}
第6行,表示該外部js文件爲異步引用,這樣是爲了加速DOM的渲染(html會按照順序來加載並執行腳本,在腳本加載&執行的過程中,會阻塞後續的DOM渲染。)
第7行,指定外部js文件位置
第9行,如果加載成功,通過promise執行resolve成功方法
第12行,如果加載失敗,通過promise執行reject失敗方法
第20行,將該外部js作爲第一個script標籤,優先加載
然後我們通過如下代碼引入即可
mounted () {
Tools.loadScript('./static/js/xxx.js')
.then(() => {
})
.catch(() => {
})
},
第4行,如果加載xxx.js成功則執行對應的方法,反之則執行第6行的代碼
QS模塊可以將URL解析成對象,也可以將對象 序列化成URL的形式,以&進行拼接他默認安裝在npm包裏面,所以在使用的時候只要require就好
舉例說明:將URL解析成對象
const Qs = require('qs')
let url = 'http://baidu.com?where=1&page=2'
Qs.parse(url);
其輸出爲
{http://baidu.com?where: "1", page: "2"}
這樣我們就可以通過解析結構獲取其中的key字段了
舉例說明:將對象 序列化成URL的形式,以&進行拼接
const Qs = require('qs');
let obj = {
where: 1,
page: 2
}
Qs.stringify(obj);
其輸出爲
where=1&page=2
在介紹video之前我們先說下同層播放,其含義是不脫離文檔流,在video元素的上方可以顯示其他元素;同層頁面內播放是標準的視頻播放形態; 而在未設置爲同層頁面播放的時候,video的播放的接管者爲系統自身,他會已一個新的頁面/全屏/來播放視頻;
下面兩個代碼將說明非同層播放效果和同層播放效果
// 未加同層播放的video,其播放效果被系統接管,效果是在瀏覽器和微信瀏覽器都是新起一個頁面,全屏展示
<div class="video">
<video
id="myVideo"
:src="videoUrl"
:key="keyUrl"
preload="auto">
</video>
</div>
// 加了同層播放的video, 其播放效果在瀏覽器上會在當前頁面全屏播放,但不是新起一個頁面,所以無法返回;在微信瀏覽器的效果和未加同層播放效果一樣,但是在手機其他瀏覽器上雖然效果同未加同層播放效果,但是在返回之後,video元素會顯示在頁面上層
<div class="video">
<video
id="myVideo"
:src="videoUrl"
:key="keyUrl"
x5-video-player-type="h5-page"
preload="auto">
</video>
</div>
在看下內聯播放:內聯播放指的是視頻在文檔流中直接進行播放,不會彈出新的播放窗口的方式,我的理解是內聯播放是在IOS上的專業說法,而同層播放是在Android上的專業說法,其是由騰訊H5同層播放器接入規範引入的
關於Video元素,一般我們會着重在android和ios上進行適配,ios因爲其封閉性,在適配上還是比較方便的;但是android上,我們就需要考慮多種瀏覽器的處理方法了;這裏我們有騰訊瀏覽器(TBS),webkit內核瀏覽器,在微信內打開網頁的視頻播放效果等等
先看下HTML5中Video元素的主要屬性和API
屬性1:fullscreenElement 該屬性返回當前處於全屏模式的DOM元素。
屬性2:fullscreenEnabled 該屬性返回當前 document 是否進入了可以請求全屏模式的狀態。
方法1:requestFullscreen() 請求進入全屏模式。
方法2:exitFullscreen() 退出全屏模式。
事件1:fullscreenchange 進入/退出全屏模式切換時會觸發。
事件2:fullscreenerror 進入/退出全屏模式失敗時會觸發
再看下在HTML5中Video元素設置object-fit屬性的用法
object-fit屬性類似background-position,來的作用主要用來設置video元素封面(poster)的展示效果,其有如下幾個值,
fill: 中文釋義“填充”。默認值。替換內容拉伸填滿整個content box, 不保證保持原有的比例。
contain: 中文釋義“包含”。保持原有尺寸比例。保證替換內容尺寸一定可以在容器裏面放得下。因此,此參數可能會在容器內留下空白。
cover: 中文釋義“覆蓋”。保持原有尺寸比例。保證替換內容尺寸一定大於容器尺寸,寬度和高度至少有一個和容器一致。因此,此參數可能會讓替換內容(如圖片)部分區域不可見。
none: 中文釋義“無”。保持原有尺寸比例。同時保持替換內容原始尺寸大小。
scale-down: 中文釋義“降低”。就好像依次設置了none或contain, 最終呈現的是尺寸比較小的那個
接着我們在看下在IOS中常見的屬性
airplay: 用於控制ios的airplay設備,一般設置爲true
x-webkit-airplay: 用於控制ios的airplay設備,一般設置爲true,這是一種兼容性表達
playsinline: 內聯播放屬性,布爾屬性,不需要賦值(存在即是true)
webkit-playsinline: 內聯播放屬性,布爾屬性,不需要賦值(存在即是true),這是一種兼容性表達
然後還有在騰訊瀏覽器(TBS)中常見的屬性設置,
x5-video-player-type: 在video標籤中添加x5-video-player-type:h5-page屬性來控制網頁內部同層播放,可以在視頻上方顯示html元素
x5-video-player-fullscreen: 視頻播放時將會進入到全屏模式,X5內核視頻默認播放形態,用戶點擊視頻區域後開始進入全屏播放,視頻區域內的所有事件行爲會由X5內核視頻組件全權託管。視頻層級最高,會遮擋所在區域所有html元素。(僅使用於安卓微信、手機QQ等非安卓QQ瀏覽器的X5內核場景)
x5-video-orientation : 聲明播放器支持的方向,可選值: landscape 橫屏, portraint豎屏,默認值:portraint
x5videoenterfullscreen: 進入全屏通知,我們可以通過JS監聽事件
myVideo.addEventListener("x5videoenterfullscreen", function(){
alert("player enterfullscreen");
})
x5videoexitfullscreen: 退出全屏的通知
更詳細的我們可以參考TBS的文檔
最後說下我們最終需要實現的效果:在微信/Android/IOS上點擊視頻,全屏自動播放視頻,當退出全屏的時候,可以暫停視頻播放並將video元素至於頁面底層,效果如下:點擊下方的播放按鈕進入到播放頁面
通過我們有三種做法:
1:通過瀏覽器加載視頻地址
2: 通過調用requestFullscreen方法進入全屏
3:通過在頁面下方加載一個全屏的video組件
先看下方法一:
這個方法比較簡單,直接指定瀏覽器爲MP4地址即可
window.location.href = '.............mp4'
這個方案的優點: 簡單,實在簡單。一行代碼;
那這個方案的確認也很明顯
1:在微信內部並不是百分百能夠播放,甚至無法加載
2:在外部瀏覽器中,我們無法控制視頻的播放,視頻的播放就交由瀏覽器處理,是否全屏會根據視頻源的大小來由系統決定
再看方法二:
<!--全屏自動播放視頻-->
<template>
<div class="tab-video">
<div class="video-img"></div>
<div class="video-play" @click="playFullScreen()"></div>
<div class="video-time">01:30</div>
<div class="video-sum">
<video
id="myVideo"
:src="videoUrl"
preload="auto"
x-webkit-airplay="allow"
x5-video-player-type="h5"
x5-video-player-fullscreen="false"
x5-video-orientation="portraint"
@fullscreenchange="changeFull"
@webkitfullscreenchange="changeFull"
@mozfullscreenchange="changeFull"
style="object-fit: contain;"
></video>
</div>
</div>
</template>
<script>
export default {
components: {},
data () {
return {
videoUrl: '填寫你自己的視頻地址',
isfull: false
}
},
methods: {
playFullScreen () {
setTimeout(() => {
const videoObj = document.getElementById('myVideo')
videoObj.setAttribute('src', this.videoUrl)
videoObj.play()
if (videoObj.requestFullscreen) {
videoObj.requestFullscreen()
} else if (videoObj.webkitRequestFullScreen) {
if (navigator.userAgent.indexOf('UCBrowser') > -1) {
window.open(this.videoUrl)
} else {
videoObj.webkitRequestFullScreen()
}
} else if (videoObj.mozRequestFullScreen) {
videoObj.mozRequestFullScreen()
} else if (videoObj.msRequestFullscreen) {
videoObj.msRequestFullscreen()
} else {
videoObj.webkitEnterFullscreen()
}
videoObj.play()
}, 600)
},
changeFull () {
if (this.isfull) {
setTimeout(() => {
const videoObj = document.getElementById('myVideo')
videoObj.pause()
if (videoObj.exitFullscreen) {
videoObj.exitFullscreen()
} else if (videoObj.mozCancelFullScreen) {
videoObj.mozCancelFullScreen()
} else if (videoObj.webkitCancelFullScreen) {
videoObj.webkitCancelFullScreen()
}
this.videoUrl = ''
}, 100)
}
this.isfull = !this.isfull
}
}
}
</script>
<!-- Add "scoped" attribute to limit CSS to this component only -->
<style>
.tab-video {
position: relative;
background-color: #000;
width: 16.72rem;
height: 9rem;
border-radius: 0.32rem;
margin: 0 auto;
}
.video-time {
width: 1.25rem;
height: 0.44rem;
position: absolute;
z-index: 101;
right: 0.8rem;
bottom: 0.2rem;
font-size: 0.26rem;
color: #fff;
line-height: 0.44rem;
text-align: center;
background-size: 100%;
}
.video-play {
position: absolute;
top: 50%;
left: 50%;
width: 5rem;
height: 5rem;
margin-left: -2.65rem;
margin-top: -1.65rem;
z-index: 200;
background-image: url("../assets/play.png");
background-repeat: no-repeat;
background-size: 100%;
}
.video-img {
position: absolute;
top: 0;
left: 0;
width: 16.72rem;
height: 9rem;
border-radius: 0.32rem;
background-size: 6.72rem 3.98rem;
z-index: 99;
background-image: url("../assets/f_bg.jpg");
background-repeat: no-repeat;
background-size: 100%;
}
.video-sum {
position: absolute;
width: 5.08rem;
height: 3.34rem;
border-radius: 0.32rem;
left: 5.7rem;
top: 0.96rem;
}
video {
width: 5.08rem;
height: 3.34rem;
border-radius: 0.32rem;
}
</style>
這個方法實現的好處是,即使我們可以在頁面下方創建一個1*1的video元素,但是你會發現webkitRequestFullScreen()這個方法並沒有將視頻進入到全屏模式
最後看下方法三:
最後如果你想實現在某個區域內不脫離文檔流的播放效果,如下圖圖一,點擊播放按鈕,就在頁面區域內部播放(如圖二)
此時你可以將這個video修改成和屏幕固定大小,這樣播放起來就可以全屏了,但是這個方案的缺點也比較明顯:無論視頻的大小,視頻都將豎屏,並且居中播放
<template>
<div class="tab-video">
<div class="video-img" v-show="!showVideo"></div>
<div class="video-play" @click="plaVideo()" v-show="!showVideo"></div>
<div class="video-time" v-show="!showVideo">01:30</div>
<div class="video-sum" v-show="showVideo">
<video
id="myVideo"
:src="videoUrl"
preload="auto"
autoplay
style="object-fit: fill;"
></video>
</div>
</div>
</template>
<script>
export default {
components: {},
data () {
return {
videoUrl: '填寫你mp4的地址',
isfull: false,
showVideo: false
}
},
methods: {
plaVideo () {
this.showVideo = true
setTimeout(() => {
const videoObj = document.getElementById('myVideo')
videoObj.play()
}, 600)
}
}
}
</script>
<!-- Add "scoped" attribute to limit CSS to this component only -->
<style>
.tab-video {
position: relative;
background-color: #000;
width: 16.72rem;
height: 9rem;
border-radius: 0.32rem;
margin: 0 auto;
}
.video-time {
width: 1.25rem;
height: 0.44rem;
position: absolute;
z-index: 101;
right: 0.8rem;
bottom: 0.2rem;
font-size: 0.26rem;
color: #fff;
line-height: 0.44rem;
text-align: center;
background-size: 100%;
}
.video-play {
position: absolute;
top: 50%;
left: 50%;
width: 5rem;
height: 5rem;
margin-left: -2.65rem;
margin-top: -1.65rem;
z-index: 200;
background-image: url("../assets/play.png");
background-repeat: no-repeat;
background-size: 100%;
}
.video-img {
position: absolute;
top: 0;
left: 0;
width: 16.72rem;
height: 9rem;
border-radius: 0.32rem;
background-size: 6.72rem 3.98rem;
z-index: 99;
background-image: url("../assets/f_bg.jpg");
background-repeat: no-repeat;
background-size: 100%;
}
.video-sum {
position: absolute;
width: 17.08rem;
height: 9.34rem;
border-radius: 0.32rem;
}
video {
width: 17.08rem;
height: 9.34rem;
border-radius: 0.32rem;
}
</style>
至於其他效果,比如你想解決在微信打開自動全屏的問題,可以在github上參考這個工程
alilmq
在我們構建項目的時候,在使用npm run test或者npm run build編譯的時候,如果你使用console.log會產生
unexpected console statement
的錯誤的時候,這是由於你在構建項目初期使用了ESLint檢查項目代碼規範導致的。這時候我們又想在移動端或者PC端輸入日誌信息,我們可以使用如下輸入方式:
window.console.log(res);
安裝和使用方法
npm install vconsole //安裝
watch和computed都是以Vue的依賴追蹤機制爲基礎的,它們都試圖處理這樣一件事情: 當某一個數據(稱它爲依賴數據)發生變化的時候,所有依賴這個數據的“相關”數據“自動”發生變化, 也就是自動調用相關的函數去實現數據的變動。// 使用
var vConsole = new VConsole();
console.log(‘Hello world’);
計算屬性:
1. 計算屬性默認只有 getter, 寫法上通過一個函數的方式來定義, 當然也可以自己定義 setter
computed: {
// 計算屬性的 getter
lowerCaseMessage: function () {
// `this` 指向 vm 實例
return this.message.toLowerCase()
},
}
2. 計算屬性也可以自定義get 和 setter, 如下當我們對 fullName重新賦值的時候, set方法就會被調用.
computed: {
// 計算屬性的 自定義get 和 setter, 當我們對 fullName重新賦值的時候, set方法就會被調用
fullName: {
// getter
get: function () {
return this.message
},
// setter
set: function (newValue) {
var names = newValue.split(' ')
this.message = names[0]
}
}
},
watch
這是一種監聽方法 用於檢測某個值是否方法變化,這種寫法當值第一次綁定的時候,不會執行監聽函數,只有值發生改變纔會執行
watch: {
// 如果 `message` 發生改變,這個函數就會運行
message: function (newMessage, oldMessage) {
console.log('**監聽函數被調用**')
},
}
上面的代碼我們需要第一次綁定的時候是不會執行的,只有當值發生變化纔會執行;如果需要立即執行,則需要用到immediate屬性
immediate表示在watch中首次綁定的時候,是否執行handler,值爲true則表示在watch中聲明的時候,就立即執行handler方法,值爲false,則和一般使用watch一樣,在數據發生變化的時候才執行handler。
watch: {
// 第一次綁定playVideoTitle` handler函數就會運行
// 監聽的數據後面寫成對象形式,包含handler方法和immediate,
// 上面的函數其實就是在寫這個handler方法;
playVideoTitle: {
handler (newTitle, oldTitle) {
console.log('**監聽函數立即被調用**')
},
immediate: true
},
}
watch方法同樣可以對一個對象進行監聽,此時就需要使用deep屬性,設置deep: true 此時會給watchObject的所有屬性都加上這個監聽器,
當對象屬性較多時,每個屬性值的變化都會執行handler。
watch: {
watchObject: {
handler (newTitle, oldTitle) {
console.log('**監聽對象函數立即被調用**')
},
deep: true,
immediate: true
},
}
如果只想監聽對象中的某一個屬性,則使用字符串的形式監聽對象屬性,如此處只監聽name屬性是否發生了變化
watch {
'watchObject.name': {
handler (newTitle, oldTitle) {
console.log('**監聽對象函數立即被調用**')
},
deep: true,
immediate: true
}
}
btoa 函數用於將字符轉爲base64編碼格式
atob 函數用於將base64編碼格式的字符進行轉碼
同時在使用btoa函數的時候,如果字符串中包含中文字符,則會拋出如下異常
The string to be encoded contains characters outside of the Latin1 range.
此時我們需要使用如下方法進行編碼和解碼
var str = "China,中國";
window.btoa(window.encodeURIComponent(str))
//"Q2hpbmElRUYlQkMlOEMlRTQlQjglQUQlRTUlOUIlQkQ="
window.decodeURIComponent(window.atob('Q2hpbmElRUYlQkMlOEMlRTQlQjglQUQlRTUlOUIlQkQ='))
//"China,中國"