vue打包部署
1先提前备份之前的包文件,然后删除之前的文件,复制新的包文件
vue 本地可以运行,打包到服务运行报错,
1问题背景:本地运行不需要服务器环境,打包到服务器,服务器的二级域名的地址可能改变了
比如:服务器的目录是msupplier/wx/
config的地址配置文件路径:
assetsPublicPath: '/mssupplier/wx/',
导致资源文件找不到,导致项目运行报错
vue cannot get / 报错
问题:当前项目从node8升级node10,导致npm的包的版本不兼容有问题
解决:需要重新安装对应版本的npm包 ,node-sass的版本不兼容,卸载重新安装
原来的版本,
"node-sass": "^4.5.2"
改成
"node-sass": "^4.14.1",
再安装下新的版本,cnpm run dev
微信js扫一扫,扫条码去掉code_128
wx.scanQRCode({
needResult: 0, // 默认为0,扫描结果由微信处理,1则直接返回扫描结果,
scanType: ["qrCode","barCode"], // 可以指定扫二维码还是一维码,默认二者都有
success: function (res) {
var result = res.resultStr; // 当needResult 为 1 时,扫码返回的结果
var barCode = getBarCode(result);
}
});
function getBarCode(resultStr){
var serial = resultStr.split(",");
var barCode = serial[serial.length-1];
return barCode;
}
微信js扫描二维码 ios系统扫码没返回结果-官方解决方案
mounted()
{
this.getShopInfo(); // 获取供应商信息
if(!security.isIOS())
{
security.getSignature(); // 获取微信签名
}
},
methods:
{
getScanQRCode()
{
let self = this
wx.ready(()=>
{
wx.checkJsApi
({
jsApiList: ['scanQRCode'],
success:(checkRes)=>
{
wx.scanQRCode
({
needResult: 1, // 默认为0,扫描结果由微信处理,1则直接返回扫描结果,
scanType: ["qrCode","barCode"], // 可以指定扫二维码还是一维码,默认二者都有
success:(res)=>
{
// ios系统扫码官方解决方案
setTimeout(()=>
{
let scanCode = res.resultStr.split('=')[1]; // 当needResult 为 1 时,扫码返回的结果 scanCode
self.$router.push({ path: '/scanDetail', query:{ "oid": scanCode}});
},1000)
}
});
}
});
})
},
// 微信签名
getSignature()
{
let self = this,
params =
{
'url': location.href.split('#')[0]
};
signature
({
params:params,
success: (res)=>
{
wx.config
({
debug: false, // 开启调试模式
appId: res.appId, // 必填,唯一标识
timestamp: res.timestamp, // 必填,时间戳
nonceStr: res.noncestr, // 必填,随机串
signature: res.signature, // 必填,签名
jsApiList: ['checkJsApi','scanQRCode'] // 必填,需要使用的JS接口列表,所有JS接口列表见附录2
});
},
failure: (message)=>
{
alert(message);
}
})
},
}
vue使用iconfont
下载资源:
https://www.iconfont.cn/api/project/download.zip?ids=6889246|-1&ctoken=6DcOjHva_wd1-dBW4OCgseHX
main.js引入
import './assets/iconfont/iconfont.js'
使用:
<template>
<div>
<div>taobao</div>
<svg class="icon" aria-hidden="false">
<use xlink:href="#icon-taobao"></use>
</svg>
</div>
</template>
<script>
export default {
name: "PostOne"
}
</script>
<style scoped>
.icon {
width: 40px;
height: 40px;
fill: red;
}
</style>
symbol引用参考:https://www.iconfont.cn/help/detail?spm=a313x.7781069.1998910419.16&helptype=code
使用vue+better-scroll实现横向滚动效果
重点:必须使用li
http://www.imooc.com/article/272021
<template>
<div class="container">
<div class="one">
<div>111</div>
</div>
<div class="personTap">
<div class="person-wrap" ref="personWrap">
<ul class="person-list" ref="personTab">
<li class="person-item">1</li>
<li class="person-item">2</li>
<li class="person-item">3</li>
<li class="person-item">4</li>
<li class="person-item">5</li>
</ul>
</div>
</div>
<div class="two">
<div>222</div>
</div>
</div>
</template>
<script>
import BScroll from 'better-scroll';
export default {
name: "Traffic",
data() {
return {
a: ''
}
},
created() {
this.$nextTick(() => {
this.personScroll();
});
},
mounted() {
},
computed: {},
methods: {
personScroll() {
// 默认有六个li子元素,每个子元素的宽度为120px
let width = 6 * 120;
this.$refs.personTab.style.width = width + "px";
// this.$nextTick 是一个异步函数,为了确保 DOM 已经渲染
this.$nextTick(() => {
if (!this.scroll) {
this.scroll = new BScroll(this.$refs.personWrap, {
startX: 0,
click: true,
scrollX: true,
// 忽略竖直方向的滚动
scrollY: false,
eventPassthrough: "vertical"
});
} else {
this.scroll.refresh();
}
});
}
},
}
</script>
<style scoped>
.container {
width: 375px;
height: 100%;
}
.personTap {
width: 375px;
height: 100px;
background: rgba(246, 245, 250, 1);
border-radius: 15px 15px 0px 0px;
margin-top: 10px;
background: red;
touch-action: none;
}
li,
ul {
list-style-type: none;
margin: 0;
padding: 0;
}
.person-item {
display: inline-block;
width: 120px;
height: 90px;
background: rgba(255, 255, 255, 1);
box-shadow: 0px 2px 16px 0px rgba(127, 127, 127, 0.22);
border-radius: 7px;
margin-left: 15px;
text-align: center;
}
.one {
display: flex;
width: 375rpx;
height: 50px;
background: #0f0;
}
.two {
display: flex;
width: 375rpx;
height: 50px;
background: #0f0;
}
</style>
移动端字体放大导致布局错乱的解决方案
解决方案:
1.页面限制用户缩放【防止页面被缩小和放大】
<meta content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0" name="viewport"/>
针对iOS,调整字体大小本身只是改变body
的css属性,因此可以通过覆盖样式来控制。
body {
-webkit-text-size-adjust: 100% !important;
}
Android微信浏览器:
在编写本文时,通过网上一些资料,发现在Android微信中,也可以借助WeixinJSBridge
对象来阻止字体大小调整。实测也有效。
justSize: function () {
if (typeof WeixinJSBridge == "object" && typeof WeixinJSBridge.invoke == "function") {
this.handleFontSize();
} else {
document.addEventListener("WeixinJSBridgeReady", this.handleFontSize, false);
}
},
handleFontSize: function () {
// 设置网页字体为默认大小
WeixinJSBridge.invoke('setFontSizeCallback', {'fontSize': 0});
// 重写设置网页字体大小的事件
WeixinJSBridge.on('menu:setfont', function () {
WeixinJSBridge.invoke('setFontSizeCallback', {'fontSize': 0});
});
},
vuex中遇到 [vuex] unknown action type: xxx报错
最后找出是store导出错误
export default new Vuex.Store({
state,
actions,//action错误写法
mutations//mutations也会容易出现此类问题,需要避免
})
vue单独给页面设置body属性
因项目需求:用户个人详细信息页面设置背景色,之前在这个页面设置最外层div发现不行。因为app.vue影响了它。后来直接在页面上用body设置样式,发现影响了其他页面。
后来想了通过vue的生命周期来解决。这个页面创建前设置我的样式,销毁之前移除我设置的样式。
代码如下:
//创建前设置
beforeCreate () {
document.querySelector('body').setAttribute('style', 'background-color:#efeff4;')
},
//销毁前清除
beforeDestroy () {
document.querySelector('body').removeAttribute('style')
},
vue项目中解决type=”file“ change事件只执行一次的问题
问题描述
在最近的项目开发中遇到了这样的一个问题,当我上传了一个文件时,我将获取到的文件名清空后,却无法再次上传相同的文件
因为我只是将data中的属性值清空而已,文件名没有变当然会不出发change事件
目前网上有好多解决办法,但基本上都无法在vue上使用,于是我想到了v-if
v-if 是“真正”的条件渲染,因为它会确保在切换过程中条件块内的事件监听器和子组件适当地被销毁和重建。
于是在代码中加入了一个小的开关,唤起change事件时就将他销毁
事件结束时再将它重建,这样问题就轻松的解决了
注意要引入n-zepto:
npm install n-zepto --save-dev
<template>
<div class="hello">
<input type="button" value="上传文件" name="" id="" @click="updata">
<input v-if="ishowFile" type="file" style="display:none" @change="getFile" id="input-file">
<div v-if="fileName">
<p>上传的文件名:{{fileName}}</p>
<button @click="delFile">清空文件</button>
</div>
</div>
</template>
<script>
import $ from 'n-zepto'
export default {
name: 'HelloWorld',
data () {
return {
fileName: '',
ishowFile: true,
}
},
methods:{
updata(){ // 唤起change事件
$('#input-file').click()
this.ishowFile = false // 销毁
},
getFile(e){ // change事件
this.doSomething()
this.ishowFile = true // 重建
},
doSomething(){ // do something
this.fileName = e.target.files[0].name
},
delFile(){
this.fileName=''
}
}
}
</script>
input type = file 取消事件
问题描述
点击了取消,下次再点击不会触发上传图片的方法
解决:
组件被销毁的逻辑写在用户点击了图片的逻辑中
<template>
<div class="hello">
<input type="button" value="上传文件" name="" id="" @click="updata">
<input v-if="ishowFile" type="file" style="display:none" @change="getFile" id="input-file">
<div v-if="fileName">
<p>上传的文件名:{{fileName}}</p>
<button @click="delFile">清空文件</button>
</div>
</div>
</template>
<script>
import $ from 'n-zepto'
export default {
name: 'HelloWorld',
data () {
return {
fileName: '',
ishowFile: true,
}
},
methods:{
updata(){ // 唤起change事件
$('#input-file').click()
},
getFile(e){ // change事件
this.doSomething()
this.ishowFile = true // 重建
},
doSomething(){ // do something
//用户选择了图片
this.ishowFile = false // 销毁
this.fileName = e.target.files[0].name
//上传图片的逻辑
let reader = new FileReader();
let $this = this;
this.ishowFile = false // 销毁
//文件预览
reader.onload = function (evt) {
$this.fp = evt.target.result;
};
reader.readAsDataURL(file);
//上传文件
if (!/image\/\w+/.test(file.type)) {
$this.$toast("请选择图片");
return false;
}
// 原生ajax实现文件上传
let form = new FormData();
form.append("file", file);
let xhr = null; //得到xhr对象
if (XMLHttpRequest) {
xhr = new XMLHttpRequest();
} else {
xhr = new ActiveXObject("Microsoft.XMLHTTP");
}
xhr.open("post", g.baseUrl + "/core/wechatpublic/upload", true);//设置提交方式,url,异步提交
xhr.onload = function () {
let obj = JSON.parse(xhr.responseText);
$this.imgName = obj.data;
$this.isUpdateImg=true;
console.log('$this.isUpdateImg='+$this.isUpdateImg);
console.log('$this.imgName='+$this.imgName);
};
xhr.send(form)
xhr.cancel=function () {
console.log('xhr.cancel')
}
},
delFile(){
this.fileName=''
}
}
}
</script>
vue打包后部分功能无效果,换台电脑有效果
1,清理npm缓存
2 清理代码缓存
监听手机返回键事件
window.addEventListener("popstate", function (e) {
//根据自己的需求实现自己的功能
}, false);
监听手机锁屏
window.addEventListener('visibilitychange', () => {
if (document.hidden) {
console.log("离开页面了")
this.massage = "离开页面了"
} else {
console.log('进入页面')
// this.msg="进入页面"
}
})
@click是点击事件,那么如何触发vue长按事件
1,触屏事件
touchstart: //手指放到屏幕上时触发
touchmove: //手指在屏幕上滑动式触发
touchend: //手指离开屏幕时触发
touchcancel: //系统取消touch事件的时候触发,这个好像比较少用
由于这次不需要计算移动的距离,所以一只用touchstart和touchend这两个事件
<div @touchstart="touchin()" @touchend="cleartime()" />
@touchstart.prevent是阻止浏览器的默认行为,如果不需要的话,就不用添加了,根据自己的实际情况
2,直接在methods里写长按方法和点击事件
一定在data里声明Loop =0;不然不管用
data() {
return {
Loop : 0
}
}
500表示触屏时间,可以根据实际情况写,只要达到这个时间就会触发setTimeout里的事件
touchin(){
var that=this;
this.Loop = setTimeout(function() {
that.Loop = 0;
//执行长按事件要执行的内容,如弹出菜单
}, 500);
},
触屏离开的事件
cleartime() {
var that=this;
clearTimeout(this.Loop);
if(that.Loop!=0){
//这里写点击要执行的内容(就像@onclick事件)
}
return false;
},
vue query param 两种传参方式区别
param:
父组件中:通过路由属性中的name来确定匹配的路由,通过params来传递参数。
this.$router.push({
name: 'Describe',
params: {
id: id
}
})
对应路由配置: 注意这里不能使用:/id来传递参数了,因为父组件中,已经使用params来携带参数了。
{
path: '/describe',
name: 'Describe',
component: Describe
}
子组件中: 这样来获取参数
this.$route.params.id
query:
父组件:使用path来匹配路由,然后通过query来传递参数
这种情况下 query传递的参数会显示在url后面?id=?
this.$router.push({
path: '/describe',
query: {
id: id
}
})
对应路由配置:
{
path: '/describe',
name: 'Describe',
component: Describe
}
对应子组件: 这样来获取参数
this.$route.query.id
最重要的一点,既然要传参肯定是要一直使用的,我们不能保证用户不去刷新页面吧,所以还是用 query传参吧,param传参刷新页面后无效,query反之
vue路由回退到指定页面
A页面->B页面->C页面,点返回的时候,需要返回到A页面
在B页面:
router.replace('/C');
// 不会记录路由,回退的话,是回退不到上一个页面,适合单页面的切换;
vue项目引入字体-使用字体.ttf
1.把字体文件放到assets目录font下
bahnschrift.ttf
设置less样式:
font.less
@font-face {
font-family: 'Bahnschrift-Regular'; //重命名字体名
src: url('bahnschrift.ttf'); //引入字体
font-weight: normal;
font-style: normal;
}
main.js引入:
import './assets/font/font.less'
第一次引入如果报错:
Module not found: Error: Can't resolve 'less-loader' in
原因:这个less是需要安装的,
cnpm install --save-dev less-loader less
https://blog.youkuaiyun.com/lilongwei4321/article/details/81364727
Vue-cli引用有fonts字体的组件,打包后路径不正确
字体文件没有效果
解决
主要是需要单独为 css 配置 publicPath 。
ExtractTextWebpackPlugin 提供了一个 options.publicPath 的 api,可以为css单独配置 publicPath 。
更改 build/utils.js 文件中 ExtractTextPlugin 插件的options 配置:
publicPath: '../../',
if (options.extract) {
return ExtractTextPlugin.extract({
use: loaders,
publicPath: '../../', // 注意配置这一部分,根据目录结构自由调整
fallback: 'vue-style-loader'
})
} else {
return ['vue-style-loader'].concat(loaders)
}
链接:https://www.jianshu.com/p/0d8883f339f5
'@/'路径和'./'路径是什么意思
在vue项目中,我们常遇到以下路径引用的方式:
@import './common/var.scss';
@import '../../scss/common/var';
@import '~@/scss/common/var';
其中,
* ./ 表示当前目录下
* ../ 表示父级目录下
* @/ 是webpack设置的路径别名,代表什么路径,要看webpack的build文件夹下webpack.base.conf.js里面对于@是如何配置
resolve: {
// 路径别名
alias: {
'public': path.resolve(__dirname, '../public'),
'vue': 'vue/dist/vue.js',
'@': path.resolve('src'),
}
},
上述例子 @/ 代表着到src这个文件夹的路径。
原文:https://blog.youkuaiyun.com/qq_28319203/article/details/81004836
v-for
:key提高性能,保障每项key值不同
v-if和v-show
v-show = true时显示,false时是在标签内加入一个display=none,不是删除这一标签。
<!--v-show是改变div标签中的style属性值display:none。适合多次显示隐藏,性能更高-->
<!--v-if是将hello world从div标签中删除然后在新增-->
vue 打包上线后 css3渐变属性丢失的问题解决方案
/*! autoprefixer: off */
background: -webkit-gradient(linear, center bottom, center top, from(#146b22), to(#54e475));
background: -webkit-linear-gradient(bottom,#146b22,#54e475);
/* autoprefixer: on */
background: -moz-linear-gradient(bottom,#146b22,#54e475);
background: -o-linear-gradient(bottom,#146b22,#54e475);
background: linear-gradient(bottom,#146b22,#54e475);
使用花生壳vue返回 invalid host header
问题:使用花生壳返回304,invalid host header
原因:新版的webpack-dev-server出于安全考虑,默认检查hostname,如果hostname不是配置内的,将中断访问。
解决:webpack.dev.conf.js添加配置 disableHostCheck: true,
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,
quiet: true, // necessary for FriendlyErrorsPlugin
watchOptions: {
poll: config.dev.poll,
},
disableHostCheck: true,
},
原文:https://blog.youkuaiyun.com/renzhehongyi/article/details/80953319
vue项目让局域网能访问
No 'Access-Control-Allow-Origin' header is present on the requested resource.'Ajax跨域访问解决方案
1.我的项目路径是http://192.168.0.234:4864/#/login 端口为4864
然后我设置了新的入站规则为4864
解决办法
vue的配置文件config下面的index.js把host改成0.0.0.0就行了
参考:https://blog.youkuaiyun.com/qq_32340877/article/details/79738949
Vue项目中,防止页面被缩放和放大
<meta content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0" name="viewport" />
vue组件中使用iframe元素的方法示例
坑:href必须是带http请求头的地址
参考:http://www.php.cn/js-tutorial-382515.html
background-image 打包路径问题
重点:修改打包后的路径,不然图片不展示
https://www.cnblogs.com/qiuyueding/p/8953396.html
npm install --save 与 npm install --save-dev 的区别
npm install -S -D -g 有什么区别
在安装 npm 包时,有两种方式把依赖包信息写入 package.json 文件,一种是npm install --save,会把依赖包 dependencies,
另一个是 npm install --save-dev,则写进devDependencies
-D 即 --save-dev 是你开发环境依赖的东西
-S 即 --save 是你线上环境依赖的东西
你开发一个前端项目,在项目中你需要使用gulp构建你的开发和本地运行环境,这时你就要放到dependencies里。gulp是你用来压缩代码,打包等需要的工具,程序实际运行的时候并不需要,所以放到dev里就ok了。
你写程序要用element-ui,生产环境运行项目时肯定要用到element-ui,这时element-ui就应该安装到dependencies中去。
效果:
单独执行npm install的时候,会同时安装devDependencies和dependencies字段中的依赖包,
当使用npm install - -production 或者注明NODE_ENV为production时,只会安装dependencies中的依赖包。
使用原则:
运行时需要用到的包使用–save,否则使用–save-dev。
npm 常用命令 查看版本、安装、卸载
npm list // 查看本地已安装模块清单
npm list [packageName] // 查看本地已安装模块版本
npm info [packageName] //查看模块的详细信息 包括各版本号等
npm view [packageName] version // 查看模块远程最新版本
npm view [packageName] versions // 查看模块远程所有版本
npm install [packageName] //安装模块
npm install [packageName]@xxx.xx //安装模块的指定版本
npm install [packageName] -g //全局安装模块
npm install [packageName] --save 安装好后写入package.json的dependencies中(生产环境依赖)
npm install [packageName] --save-dev 安装好后写入package.json的devDepencies中(开发环境依赖)
npm uninstall [packageName] // 删除模块
npm uninstall [packageName] -g //卸载全局模块
npm uninstall [packageName] --save // 删除模块,同时删除模块留在package.json中dependencies下的对应信息
npm uninstall [packageName] --save-dev // 删除模块,同时删除模块留在package.json中devDependencies下的对应信
拷贝相同项目npm run dev运行报错
错误提示:webpack-dev-server --inline --progress --config build/webpack.dev.conf.js
解决:原因是因为你的node_modules有意外改动,导致依赖库不完整。
删除项目下的node_modules,在你的项目目录下,重新执行npm install,这会重新生成node_modules,
执行npm run dev.
参考:https://blog.youkuaiyun.com/m0_37948170/article/details/80694229
。。。