项目部署遇到的那些坑
- 页面URL中“#”的处理;
使用vue-cli生成的项目模板,运行时在url地址栏多了一个“#”号,服务器部署后会出现“http://localhost:80/#/”的情况;
解决方案:修改“src/router/index.js"文件,修改 vue-router 模式为history
,设置bash
url效果正常了
2. 服务器部署 vue 子模块项目
有一个项目地址为http://localhost:80/,这个项目下又添加了一个子模块,子模块是单独的一个项目,域名效果变成http://localhost:80/sk的形式访问子模块项目的首页,通过http://localhost:80/sk/home的方式访问子模块项目路由页面
解决方案:
第一步:修改src/router/index.js
文件中 router 的bash
配置,效果如下
Vue.use(Router)export default new Router({mode: 'history',base: '/sk',routes: [{path: '/',name: 'home',component: home}]
})
第二步:修改npm run build
命令打包生成的目录结构。打开前端项目根目录下/config/index.js
文件,打包的默认路径为生成dist
静态文件目录,默认路径配置如下
...build: {index: path.resolve(__dirname, '../dist/index.html'),assetsRoot: path.resolve(__dirname, '../dist'),assetsSubDirectory: 'static',assetsPublicPath: '/',...
修改打包路径配置,静态文件目录下添加一个sk
子目录,其他打包文件放到sk
目录下,注意目录中的/
, 前端项目中的配置完成了
...build: {index: path.resolve(__dirname, '../dist/sk/index.html'),assetsRoot: path.resolve(__dirname, '../dist/sk'),assetsSubDirectory: 'static',assetsPublicPath: '/sk/',
...
第三步:修改dev
属性下的assetsPublicPath
路径配置,由原来的/
修改为/sk/
...dev: {// PathsassetsSubDirectory: 'static',assetsPublicPath: '/sk/',proxyTable: {},// Various Dev Server settingshost: 'localhost', // can be overwritten by process.env.HOSTport: 8080, // can be overwritten by process.env.PORT, if port is in use, a free one will be determinedautoOpenBrowser: false,
...
第四步:修改服务器 nginx 的配置,设置sk
路径访问内容,配置如下
...
server {listen 80;server_name example.com;location / {try_files $uri /index.html;root /xxx/projects/example/frontend/dist;}location /sk {try_files $uri /sk/index.html;alias /xxx/projects/example-sk/frontend/dist/sk;}}
...
项目开发中遇到的那些坑
- 父组件引用子组件
第一步:引入子组件:
import StateWatchListPage from '子组件的路径';
第二步:将子组件名称加入到components对象
components:{StateWatchListPage}
第三步:使用子组件
2. 路由变化页面数据不刷新问题:
出现这种情况是因为依赖路由的params参数获取写在created生命周期里面,因为路由懒加载的关系,退出页面再进入另一个文章页面并不会运行created组件生命周期,导致文章数据还是第一次进入的数据
解决方法:watch监听路由是否变化
watch: {// 方法1'$route' (to, from) { //监听路由是否变化if(this.$route.params.articleId){// 判断条件1 判断传递值的变化//获取文章数据}}//方法2'$route'(to, from) {if (to.path == "/page") { /// 判断条件2 监听路由名 监听你从什么路由跳转过来的this.message = this.$route.query.msg }}
}
3. 异步回调函数中使用this无法指向vue实例对象
//setTimeout/setInterval ajax Promise等等
data(){return{...}
},
methods (){setTimeout(function () { //其它几种情况相同console.log(this);//此时this指向并不是vue实例 导致操作的一些ma'f},1000);
}
解决方案:使用变量赋值或是箭头函数
//使用变量访问this实例
let self=this; setTimeout(function () { console.log(self);//使用self变量访问this实例},1000);//箭头函数访问this实例 因为箭头函数本身没有绑定thissetTimeout(() => { console.log(this);}, 500);
插播:ES6中var和let的区别
- 通过var定义的变量,作用域是整个封闭函数,是全域的 。通过let定义的变量,作用域是在块级或是子块中
for (let i &#61; 0; i <10; i&#43;&#43;) {
// ...
}
console.log(i);// ReferenceError: i is not defined//计数器i只在for循环体内有效&#xff0c;在循环体外引用就会报错。
- 变量提升现象&#xff1a;浏览器在运行代码之前会进行预解析&#xff0c;首先解析函数声明&#xff0c;定义变量&#xff0c;解析完之后再对函数、变量进行运行、赋值等。
-不论var声明的变量处于当前作用域的第几行&#xff0c;都会提升到作用域的头部。
-var 声明的变量会被提升到作用域的顶部并初始化为undefined&#xff0c;而let声明的变量在作用域的顶部未被初始化
// var 的情况
console.log(foo);// 输出undefined
var foo &#61;2;
//相当于
var foo; //声明且初始化为undefined
console.log(foo);
foo&#61;2;
// let 的情况
console.log(bar); // 报错ReferenceError
let bar &#61; 2; //
相当于在第一行先声明bar但没有初始化&#xff0c;直到赋值时才初始化
- 但是直接用let声明变量不赋值是会打印undefined&#xff0c;还是初始化了&#xff0c;只是let声明放在赋值之后&#xff0c;let声明会提前但不会初始化。
let a;
alert(a);//值为undefined
alert b;//会报错
let b;
- 只要块级作用域内存在let命令&#xff0c;它所声明的变量就“绑定”这个区域&#xff0c;不再受外部的影响。总之&#xff0c;在代码块内&#xff0c;使用let命令声明变量之前&#xff0c;该变量都是不可用的&#xff0c;尽管代码块外也存在相同全局变量。
var tmp &#61; 123; if (true) { tmp &#61; &#39;abc&#39;; // ReferenceErrorlet tmp;
}
alert(tmp); //输出值为123&#xff0c;全局tmp与局部tmp不影响
- let不允许在相同作用域内&#xff0c;重复声明同一个变量。
// 报错
function() {
let a &#61; 10;
var a &#61; 1;
}// 报错function() {
let a &#61; 10;
let a &#61; 1;
}
4. setInterval路由跳转继续运行并没有及时进行销毁
一些弹幕&#xff0c;走马灯文字&#xff0c;这类需要定时调用的&#xff0c;路由跳转之后&#xff0c;因为组件已经销毁了&#xff0c;但是setInterval还没有销毁&#xff0c;还在继续后台调用&#xff0c;控制台会不断报错&#xff0c;如果运算量大的话&#xff0c;无法及时清除&#xff0c;会导致严重的页面卡顿。
解决办法&#xff1a;在组件生命周期beforeDestroy停止setInterval
//组件销毁前执行的钩子函数&#xff0c;跟其他生命周期钩子函数的用法相同。
beforeDestroy(){//我通常是把setInterval()定时器赋值给this实例&#xff0c;然后就可以像下面这么停止。clearInterval(this.intervalId);
},
5. 实现vue路由拦截浏览器的需求,进行一系列操作 草稿保存等等
场景&#xff1a;为了防止用户失误点错关闭按钮等等&#xff0c;导致没有保存已输入的信息(关键信息)。
解决办法&#xff1a;
//监听当前页面返回事件beforeRouteLeave(to, from, next) {//next方法传true或者不传为默认历史返回&#xff0c;传false为不执行历史回退if(this.backStatu){next(true);}else{next(false);}this.tipshow &#61; true;},
点击查看完整代码blog.csdn.net
添加好友&#xff0c;拉入微信群