本节内容来自这里。
在我们对vue项目进行打包的时候,会遇到一些组件问题,比如说分页组件的箭头,下拉框组件的箭头打包完成后会出现方框显示的问题.具体解决办法如下:
本节内容来自这里。
如果是 sass 的,执行 npm install sass sass-loader --save-dev 安装依赖就行。或者($npm intall sass-loader --save ; $npm install node-sass --save)
由于npm会限制此包,所有可以使用cnpm:
cnpm install node-sass
本节内容来自这里。
本节内容来自这里。
console.log(JSON.stringify(this.inputForm))
本节内容来自这里。
背景:因为axios中只能使用get和post方法来进行请求数据,没有提供jsonp等方法进行跨域访问数据。
// axios中的GET请求
axios.get('/user', {
params: {
ID: ‘001’
}
})
.then(function (response) {
console.log(response);
})
.catch(function (error) {
console.log(error);
});
// axios中的POST请求
axios.post('/user', {
firstName: '1',
lastName: '2'
})
.then(function (response) {
console.log(response);
})
.catch(function (error) {
console.log(error);
});
既然使用axios直接进行跨域访问不可行,我们就需要配置代理了。代理可以解决的原因:因为客户端请求服务端的数据是存在跨域问题的,而服务器和服务器之间可以相互请求数据,是没有跨域的概念(如果服务器没有设置禁止跨域的权限问题),也就是说,我们可以配置一个代理的服务器可以请求另一个服务器中的数据,然后把请求出来的数据返回到我们的代理服务器中,代理服务器再返回数据给我们的客户端,这样我们就可以实现跨域访问数据。
准备工作:安装所需中间件和插件等,比如axios,http-proxy-middleware等。
具体案例:这里以访问豆瓣Top250为例,直接访问如下:
axios.get("http://api.douban.com/v2/movie/top250")
.then(res=>{
console.log(res)
})
.catch(err=>{
console.log(err)
})
当执行npm run dev
时,控制台报错如下:
事实证明直接请求确实出现跨域问题了,下面具体演示解决跨域问题的步骤:
上面所说的必备条件都已安装完成的情况下,执行以下步骤即可解决问题:
1、配置BaseUrl
在main.js中,配置数据所在服务器的前缀(即固定部分),代码如下:
// 项目入口,配置全局vue
import Vue from 'vue'
import VueRouter from './router/routes.js'
import Store from './store/index.js'
import './assets/less/index.less'
import App from './App.vue'
import ElementUI from 'element-ui'
import 'element-ui/lib/theme-default/index.css'
import axios from 'axios'
Vue.prototype.$axios = axios
axios.defaults.baseURL = '/api' //关键代码
Vue.config.productionTip = false
Vue.use(ElementUI);
new Vue({
router:VueRouter,
store:Store,
template:' ',
components: {App}
}).$mount('#app')
// 默认进入商品模块
// VueRouter.push({ path: '/home' })
关键代码:axios.defaults.baseURL = '/api'
,作用是我们每次发送的请求都会带一个/api
的前缀。
2、配置代理
在config文件夹下的index.js文件中的proxyTable字段中,作如下处理:
dev: {
env: require('./dev.env'),
port: 8090,
autoOpenBrowser: true,
assetsSubDirectory: 'static',
assetsPublicPath: '/',
proxyTable: {
'/api': {
target:'http://api.douban.com/v2', // 你请求的第三方接口
changeOrigin:true, // 在本地会创建一个虚拟服务端,然后发送请求的数据,并同时接收请求的数据,这样服务端和服务端进行数据的交互就不会有跨域问题
pathRewrite:{ // 路径重写,
'^/api': '' // 替换target中的请求地址,也就是说以后你在请求http://api.douban.com/v2/XXXXX这个地址的时候直接写成/api即可。
}
}
},
// CSS Sourcemaps off by default because relative paths are "buggy"
// with this option, according to the CSS-Loader README
// (https://github.com/webpack/css-loader#sourcemaps)
// In our experience, they generally work as expected,
// just be aware of this issue when enabling this option.
cssSourceMap: false
}
3、在具体使用axios的地方,修改url如下即可:
axios.get("/movie/top250")
.then((res) => {
res = res.data
if (res.errno === ERR_OK) {
this.themeList=res.data;
}
})
.catch((error) => {
console.warn(error)
})
4、重新启动项目之后,已经解决了跨域问题,结果如下:
5、区分一下生产环境和开发环境,集体配置如下:
在config文件夹里面创建一个api.config.js的配置文件
const isPro = Object.is(process.env.NODE_ENV, 'production')
console.log(isPro);
module.exports = {
baseUrl: isPro ? 'https://www.***/index.php/Official(线上地址)' : 'api/'
}
在main.js文件里面引入上面文件,这样就可以保证动态的匹配生产和开发环境的定义前缀了,代码如下:
import Vue from 'vue'
import App from './App'
import router from './router'
import 'bootstrap/dist/js/bootstrap.min'
import 'bootstrap/dist/css/bootstrap.min.css'
import axios from 'axios'
import apiConfig from '../config/api.config'
Vue.prototype.$axios = axios;
Vue.config.productionTip = false;
axios.defaults.baseURL = apiConfig.baseUrl;// 配置接口地址
axios.defaults.withCredentials = false;
以上两步即可解决vue的跨域问题,并且可以可以直接build打包到线上。
原理:
因为我们给url加上了前缀/api,我们访问/movie/top250就当于访问了:localhost:8080/api/movie/top250(其中localhost:8080是默认的IP和端口)。
在index.js中的proxyTable中拦截了/api,并把/api及其前面的所有替换成了target中的内容,因此实际访问Url是http://api.douban.com/v2/movie/top250。
至此,纯前端配置代理解决axios跨域得到解决。
后端处理跨域问题,加个过滤器即可解决,如下:
import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
/*
* 跨域过滤器
* @author jitwxs
* @since 2018/10/16 20:53
*/
public class CorsFilter implements Filter {
@Override
public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {
HttpServletResponse response = (HttpServletResponse) res;
HttpServletRequest request = (HttpServletRequest) req;
// 不使用*,自动适配跨域域名,避免携带Cookie时失效
String origin = request.getHeader("Origin");
if(StringUtils.isNotBlank(origin)) {
response.setHeader("Access-Control-Allow-Origin", origin);
}
// 自适应所有自定义头
String headers = request.getHeader("Access-Control-Request-Headers");
if(StringUtils.isNotBlank(headers)) {
response.setHeader("Access-Control-Allow-Headers", headers);
response.setHeader("Access-Control-Expose-Headers", headers);
}
// 允许跨域的请求方法类型
response.setHeader("Access-Control-Allow-Methods", "*");
// 预检命令(OPTIONS)缓存时间,单位:秒
response.setHeader("Access-Control-Max-Age", "3600");
// 明确许可客户端发送Cookie,不允许删除字段即可
response.setHeader("Access-Control-Allow-Credentials", "true");
chain.doFilter(request, response);
}
@Override
public void init(FilterConfig filterConfig) {
}
@Override
public void destroy() {
}
/*
注册过滤器:
@Bean
public FilterRegistrationBean registerFilter() {
FilterRegistrationBean bean = new FilterRegistrationBean<>();
bean.addUrlPatterns("/*");
bean.setFilter(new CorsFilter());
// 过滤顺序,从小到大依次过滤
bean.setOrder(Ordered.HIGHEST_PRECEDENCE);
return bean;
}
*/
}
分两种情况,NPM命令可以查看npmjs服务器上的包的版本信息,也可以查看本地安装的包的版本信息。
查看npmjs服务器上的包的版本信息
1、npm view pkg version
查看服务器上包pkg的最新的版本信息。
npm view gulp version
4.0.0
2、npm view pgk versions
查看npmjs服务器上包pkg的所有的版本信息。
npm view gulp versions
3、npm info pkg
查看npmjs服务器上包pkg的最新的版本信息,和 npm view pkg version
的功能类似,但比 npm view pkg version
提供的信息更丰富。
npm info gulp
查看本地安装包的版本信息
1、npm ls pkg
查看某个项目下包 pkg 的版本信息,注意该命令需要在某个项目下执行。
npm ls webpack
[email protected] /本地的项目路径
└── [email protected]
2、npm ls pkg -g 查看本地全局安装的pkg版本。
npm ls webpack -g
/Users/mac/.nvm/versions/node/v8.8.0/lib
└── [email protected]
“Yarn是由Facebook、Google、Exponent 和 Tilde 联合推出了一个新的 JS 包管理工具 ,正如官方文档中写的,Yarn 是为了弥补 npm 的一些缺陷而出现的。”这句话让我想起了使用npm时的坑了:
npm install的时候巨慢。特别是新的项目拉下来要等半天,删除node_modules,重新install的时候依旧如此。
同一个项目,安装的时候无法保持一致性。由于package.json文件中版本号的特点,下面三个版本号在安装的时候代表不同的含义。
“5.0.3”,
“~5.0.3”,
“^5.0.3”
“5.0.3”表示安装指定的5.0.3版本,“~5.0.3”表示安装5.0.X中最新的版本,“^5.0.3”表示安装5.X.X中最新的版本。这就麻烦了,常常会出现同一个项目,有的同事是OK的,有的同事会由于安装的版本不一致出现bug。
安装的时候,包会在同一时间下载和安装,中途某个时候,一个包抛出了一个错误,但是npm会继续下载和安装包。因为npm会把所有的日志输出到终端,有关错误包的错误信息就会在一大堆npm打印的警告中丢失掉,并且你甚至永远不会注意到实际发生的错误。
带着这些坑,我开始了解Yarn的优势及其解决的问题。
速度快 。速度快主要来自以下两个方面:
并行安装:无论 npm 还是 Yarn 在执行包的安装时,都会执行一系列任务。npm 是按照队列执行每个 package,也就是说必须要等到当前 package 安装完成之后,才能继续后面的安装。而 Yarn 是同步执行所有任务,提高了性能。
离线模式:如果之前已经安装过一个软件包,用Yarn再次安装时之间从缓存中获取,就不用像npm那样再从网络下载了。
安装版本统一:为了防止拉取到不同的版本,Yarn 有一个锁定文件 (lock file) 记录了被确切安装上的模块的版本号。每次只要新增了一个模块,Yarn 就会创建(或更新)yarn.lock 这个文件。这么做就保证了,每一次拉取同一个项目依赖时,使用的都是一样的模块版本。npm 其实也有办法实现处处使用相同版本的 packages,但需要开发者执行 npm shrinkwrap 命令。这个命令将会生成一个锁定文件,在执行 npm install 的时候,该锁定文件会先被读取,和 Yarn 读取 yarn.lock 文件一个道理。npm 和 Yarn 两者的不同之处在于,Yarn 默认会生成这样的锁定文件,而 npm 要通过 shrinkwrap 命令生成 npm-shrinkwrap.json 文件,只有当这个文件存在的时候,packages 版本信息才会被记录和更新。
更简洁的输出:npm 的输出信息比较冗长。在执行 npm install 的时候,命令行里会不断地打印出所有被安装上的依赖。相比之下,Yarn 简洁太多:默认情况下,结合了 emoji直观且直接地打印出必要的信息,也提供了一些命令供开发者查询额外的安装信息。
多注册来源处理:所有的依赖包,不管他被不同的库间接关联引用多少次,安装这个包时,只会从一个注册来源去装,要么是 npm 要么是 bower, 防止出现混乱不一致。
更好的语义化: yarn改变了一些npm命令的名称,比如 yarn add/remove,感觉上比 npm 原本的 install/uninstall 要更清晰。
npm | yarn |
---|---|
npm install | yarn |
npm install react --save | yarn add react |
npm uninstall react --save | yarn remove react |
npm install react --save-dev | yarn add react --dev |
npm update --save | yarn upgrade |
有了yarn的压力之后,npm做了一些类似的改进。
默认新增了类似yarn.lock的 package-lock.json;
git 依赖支持优化:这个特性在需要安装大量内部项目(例如在没有自建源的内网开发),或需要使用某些依赖的未发布版本时很有用。在这之前可能需要使用指定 commit_id 的方式来控制版本。
文件依赖优化:在之前的版本,如果将本地目录作为依赖来安装,将会把文件目录作为副本拷贝到 node_modules 中。而在 npm5 中,将改为使用创建 symlinks 的方式来实现(使用本地 tarball 包除外),而不再执行文件拷贝。这将会提升安装速度。目前yarn还不支持。
在npm5.0之前,yarn的优势特别明显。但是在npm之后,通过以上一系列对比,我们可以看到 npm5 在速度和使用上确实有了很大提升,值得尝试,不过还没有超过yarn。
综上我个人的建议是如果你已经在个人项目上使用 yarn,并且没有遇到更多问题,目前完全可以继续使用。但如果有兼容 npm 的场景,或者身处在使用 npm,cnpm,tnpm 的团队,以及还没有切到 yarn 的项目,那现在就可以试一试 npm5 了。
webpack创建vue工程以后,运行项目后控制台提示{ parser: “babylon” } is deprecated; we now treat it as { parser: “babel” }.
解决方法:
找到工程里面文件夹:node_modules\vue-loader\lib\template-compiler\index.js,将以下代码:
if (!isProduction) {
code = prettier.format(code, { semi: false, parser: 'babylon' })
}
修改为:
if (!isProduction) {
code = prettier.format(code, { semi: false, parser: 'babel' })
再次运行项目npm run dev即可。