一、直接引入`import vue from 'vue'` 报vue-warn错误
//如果直接使用import Vue from 'vue' 会对应引入dist/vue.runtime.common.js
// 因为package.json main对应dist/vue.runtime.common.js
解决办法是
`import vue from 'vue/dist/vue.runtime.common.js'`
或者webpack配置resolve
resolve:{
alias:{
'vue':'vue/dist/vue.js'
}
}
2.webpack-dev-server热刷新失败
webpack-dev-server --progress --colors --host 0.0.0.0 --port 8088 --content-base dist
module.exports={
....省略。。。
devServer:{
historyApiFallback:true,
inline:true,
hot:false //如果刷新不成功 就是用hot关掉
},
....省略。。。
}
以下为使用vue-cli中遇到的坑和解决办法
使用vue全家桶搭建项目 vue vuex vueRouter axios vee-validate
一 、eslint的使用
这里只对vue-cli没有默认添加的部分规则配置进行说明,如下:
/**
* "off" 或 0 - 关闭规则
* "warn" 或 1 - 开启规则,使用警告级别的错误:warn (不会导致程序退出),
* "error" 或 2 - 开启规则,使用错误级别的错误:error (当被触发的时候,程序会退出)
*/
在.eslintrc.js 文件的rules进行配置
"linebreak-style":0,//在 windows 操作系统中换行符通常是回车 (CR) 加换行分隔符 (LF),也就是回车换行(CRLF),然而在 Linux 和 Unix 中只使用简单的换行分隔符 (LF)。对应的控制字符为 "\n" (LF) 和 "\r\n"(CRLF)。
'indent':0//忽略缩进: 关闭tab和space造成的indent 缩进错误提示
1.出现Newline required at end of file but not found 即表示为每个js文件写完后 要多写一行的空白行
原因 eslint rules规则限制了:
/*eslint eol-last: ["error", "always"]*/
/*eslint eol-last: ["warn", "never"]*/
/*eslint eol-last:0*/关闭不限制即可
"always"(默认) 强制使用换行 (LF)
"never"强制文件末尾不要有换行符
2、出现
Missing space before value for key 'counter'
G:\fe\app\src\components\Hello.vue:29:15
counter:0,
原因是因为你的冒号:后面没有跟空格,这个限制书写的,还行就不要去掉了!
2、no-console 意思就是你不要写console在里面 不然就警告
http://eslint.org/docs/rules/no-console Unexpected console statement
G:\fe\app\src\components\Hello.vue:33:5
console.log(this.$store);
关闭方法还是:
no-console:0
3、space-before-blocks 表示括号和大括号之间要不要空间 默认就是必须要啊 这样看起来美观呀!
http://eslint.org/docs/rules/space-before-blocks Missing space before opening brace
G:\fe\app\src\components\Hello.vue:32:12
mounted(){
^
关闭方法:
space-before-blocks:0
4、Absolute imports should come before relative imports出错(原因是相对import 在绝对的import之前 你需要把下面两行换一下就行了)
import router from './router';
import { sync } from 'vuex-router-sync';
使用eslint进行代码检查开发的过程中出现报错 如果您能够找到对应的错误可以进行修改,如果找不到只能使用一招就是禁用eslint
在代码前面加上
/* eslint-disable */
二、使用vee-validate的用法
1、使用v-validate=="'required|email'"/v-validate.initial="'required|email'" /data-rules="required|mobile" 报错问题
改为
v-model="regObj.createPW" name="createPW" v-validate data-vv-rules="required|min:6"
v-model name v-validate data-vv-rules 都是必填项
2、在页面上使用fields.fields.name.dirty[clean/failed/passed/valid] 的时候需要加入前面的fields.fields.name
eg:
fields.fields.createPW&&fields.fields.createPW.dirty
3、当使用了element-ui之后 还是强行加载了vee-validate 报出 The computed property "fields" is already defined in data.错误
原因是因为 element-ui 自带表单验证 已经把fields注入了
解决办法 在veeValidate配置的时候使用如下配置
const config={
fieldsBagName:'vee-fields',//默认为 fields
};
Vue.use(VeeValidate, config);
其实感觉还是直接 用element-ui的表单验证吧 要么 就直接写成原始的form表单 使用veevalidate
三、axios的使用
import axios from 'axios'
import VueAxios from 'vue-axios'
Vue.use(VueAxios,axios)
这样就可以使用 this.axios.get[post,delete,put]()的方法了
但是遇到跨域请求的时候总是会出现莫名的问题!
1、出现不容许跨域问题
后端使用Access-control-allow-origin:* 或者指定你的跨域Referer
2、出现只会发送potions方法,不会发送具体的get/post
axios 发送请求时的数据默认是 JSON 格式的。这是导致用 axios POST 跨域出错的主要原因。
根据 CORS 的标准,当浏览器发送跨域请求时,如果请求不是GET或者特定POST(Content-Type只能是 application/x-www-form-urlencoded, multipart/form-data 或 text/plain的一种)时,强烈要求浏览器必须先以 OPTIONS 请求方式发送一个预请求(preflight request),从而获知服务器端对跨源请求所支持 HTTP 方法。所以,使用 axios 直接发送 POST 的跨域请求,如果web后端对 OPTIONS 的响应有问题,就会报错。不过是先把 params 转换为字符串格式了,见末尾的官方用x-www-form-urlencoded格式的说明
import qs from 'qs';
import axios from 'axios';
let reqUrl ='http://xxx.com';
letreqParams = {name:'aaa'};
axios.post(url, qs.stringify({params: reqParams}),{
headers:{
'Content-Type': 'application/x-www-form-urlencoded'
}
})
.then(response=>{console.log(response);})
3.出现The credentials mode of requests initiated by the XMLHttpRequest is controlled by the withCredentials attribute.
The value of the 'Access-Control-Allow-Origin' header in the response must not be the wildcard '*' when the request's credentials mode is 'include'. Origin 'http://127.0.0.1:8082' is therefore not allowed access. The credentials mode of requests initiated by the XMLHttpRequest is controlled by the withCredentials attribute.
原因摘自MDN:
XMLHttpRequest。withCredentials属性是一个布尔值,指示是否跨站点访问控制请求应使用凭证如cookie,授权标头或TLS客户端证书。使用凭证设置对相同的站点请求没有影响。
此外,该标志还用于指示在响应中何时将忽略cookie。默认是假的。来自不同域的XMLHttpRequest不能为自己的域设置cookie值,除非在发出请求之前将凭据设置为true。第三方cookie将withCredentials设置为true仍将获得的荣誉同源策略,因此不能通过文件访问请求的脚本。cookie或响应头信息。
解决办法:
服务器端:add_header Access-Control-Allow-Credentia :true;
或者请求头:withCredentials:true
4.创建请求实力后 可以进行截断处理
//Add a request interceptor 请求截断
axios.interceptors.request.use(function(config){
//Do something before request is sent
returnconfig;
},function(error){
//Do something with request error
return Promise.reject(error);
});
//Add a response interceptor//返回截断
axios.interceptors.response.use(function(response){
//Do something with response data
returnresponse;
},function(error){
//Do something with response error
return Promise.reject(error);
});
var instance=axios.create(); //创建实力 的截断
instance.interceptors.request.use(function(){/*...*/});
instance.interceptors.response.use(function(){/*...*/});
四、vue常见问题
1.对于数组对象修改,新增属性的 dom视图不能更新的情况
vm .someObject.b=2 不起作用的情况
全局使用Vue.set(vm.someObject,'b', 2)
组件使用this.$set(this.someObject,'b',2)
2.vue中数组的操作总结:
一、根据索引设置元素:
1、调用$set方法:
this.arr.$set(index, val);
2、调用splice方法:
this.arr.splice(index,1, val);
二、合并数组:
this.arr= this.arr.concat(anotherArr);
三、清空数组:
this.arr=[];
四、主要的数组方法:
1、变异方法(修改了原始数组),vue为触发视图更新,包装了以下变异方法:
push()pop()shift()unshift()splice()//无论何时,使用该方法删除元素时注意数组长度有变化,bug可能就是因为她sort()reverse()
2、非变异方法(不会修改原始数组而是返回一个新数组),如concat()、filter(),使用时直接用新数组替换旧数组,如上面的合并数组例子。
3.click事件作用于<a></a> 的问题
@click事件 先于href跳转触发,对于原生a标签跳转,部分网站出现
Error 400--Bad Request
From RFC 2068Hypertext Transfer Protocol -- HTTP/1.1:
10.4.1 400 Bad Request
The request could not be understood by the server due to malformed syntax. The client SHOULD NOT repeat the request without modifications.
解决办法就是
基于HTML标准,可以在a标签内使用rel="noreferrer"来达到这一目的。
目前大部分基于Webkit的浏览器已经支持。
提供跨浏览器支持的更好的办法是使用一个第三方的库noreferrer.js,它可以自动识别浏览器并选择最优方案。
补充
Opera并没有提供可以实现不发送referrer的方法,noreferrer.js的解决方案是利用google的url中转。在国内的网络环境下,你懂的。。。
可以自己搭建一个跳转的页面,或者用其他站点的url跳转接口。
或者使用js实现(如果是新窗口打开,可以使用如下代码:)
html:
<a @click.prevent="target($event)"></a>
method:
//
target(e){
this.open_new_window('http://www.miitbeian.gov.cn/state/outPortal/loginPortal.action')
},
open_new_window(full_link){
window.open('javascript:window.name;', 'location.replace("'+full_link+'")<\/script>');
}
五、webpack2.0的配置问题
1.全局使用jquery
plugins: [
new webpack.ProvidePlugin({
$:"jquery",
jQuery:"jquery",
"window.jQuery":"jquery"
})
]
如何 只在webpack.base.conf.js里配置依然没用,就需要在webpack.dev.conf.js和webpack.prod.conf.js 里一起配置
2.修改vue-cli里发布版本的控制
首先vue-cli 已经很好的将我们写的代码进行懒加载设置和chunk处理了,但是他对于静态文件的处理只是将静态资源的名称+该资源的hash值作为后缀名,我们希望我们的版本同样能加上我们在package.json里设置的Version号 这样方便我们发布的时候能够与后端同步!
在webpack.prod.conf.js里引入package.json
var packageConfig = require('../package.json');
output: {
path: config.build.assetsRoot,
filename: utils.assetsPath('js/[name].[chunkhash:6].'+packageConfig.version+'.js'),//此处重点 [name]为文件名称 [chunkhash]为文件哈希值 这里取6位 packageConfig.version为我们发布的版本 即可
chunkFilename: utils.assetsPath('js/[id].[chunkhash:6].'+packageConfig.version+'.js')
},
3.生产环境下的index.html里资源的绝对路径引入的问题
出现这个的原因是在webpack的output里publicPath是'/'
需要在config/index.js里找到assetsPublicPath改成 './' 即变成相对引入 但是里面的文件资源的打包路径的引入也要相应的修改,因为他也是从当前文件下相对路径引入的资源
4.用vue官方脚手架vue-cli做项目一段时间了,今天突然热刷新失效了,手动刷新页面都不行,只能重启服务页面才刷新。在网上找到一个解决办法分享一下,经验证可以解决问题。(欢迎评论补充)
echo fs.inotify.max_user_watches=524288 | sudo tee -a /etc/sysctl.conf
&& sudo sysctl -p
六、element-ui 一些莫名其妙的问题
Error in render function: "TypeError: Converting circular structure to JSON"
1、在使用Message提醒框的时候 想使用vnode 而不是纯文本!会出现这个问题
原因是element-ui @1.4.2 对Message中添加vnode 而@1.3.7以前不支持vnode功能 会报错!
Uncaught TypeError: Cannot read property 'style' of undefined 在el-table 里出现 handlerMouseEnter出现error
2、一般是element-ui版本的问题 ,element-ui更新为最新版本 @1.4.2
如果是之前@1.3.7版本,此时的Switch开关的取值 刚好相反 需要处理
3、切记在npm install 或者uninstall的时候 需要把npm run dev 的服务停掉,因为如果不停掉,原始的版本会删除不掉,这样就只是简单的覆盖原文件,这样就会造成 依赖文件不同版本的混乱 ,尤其在使用npm和cnpm同时存在两种node_moudles的依赖包的时候
4、MessageBox里点击取消按钮时出现
Uncaught (in promise) cancel
报此种错误的愿意是 promise没有收到resolve或者reject
解决办法:1.不使用.then()的语法 使用callback的回调方法解决