个人的Vue学习和使用踩坑记录,持续更新中,欢迎指正。
-
import导入组件或@import导入样式时,@作为别名表示src目录。对于scss样式,需要在前面加波浪号,即使用~@才能使用该别名。 -
vue.config.js默认的打包相关的配置都在里面,比如webpack相关设置。 -
本地调试时需要访问外部链接或接口时会有跨域问题,此时在
vue.config.js下配置devServer.proxy代理即可绕过跨域问题。如下配置对api开头的接口代理到https://www.realapi.com:devServer: { proxy: { '/api': { target: 'https://www.realapi.com', changeOrigin: true } }
}
4. pointer-events: none; /* 禁止鼠标点击 */
5. `$router.back()`和`$router.go(-1)`都能返回上一页,但是`$router.go(-1)`原页面表单中的内容会丢失。
6. 自定义组件在被使用时,最终渲染出来的dom上出现了名为组件名的节点(如ComponentTest组件显示成了component-test,而不是自带的html节点div)。
原因在于组件的导入方式import和组件的导出方式export是否对应,要理解import和export的使用细节。
---
*import和export科普开始*
假设现在有下面这样一个index.js:
```javascript
var str = 'Hello World';
export str;
export var count = 4;
export default {
slogan: "fight",
time: 12
};
导入时这样导入:
import {count} from './index.js';
import who from './index.js';
console.log('nested-export', who, count);
这个时候count和who都能如预期般获取并打印出一个对象和数字4。但如果反过来像这样:
import count from './index.js';
import {who} from './index.js';
console.log('nested-export', who, count);
打印出来的结果就是nested-export undefined {slogan: 'fight', time: 12}。也就是说,who并没有指向任何对象,而count指向了index.js中导出的default对象。
出现这样的结果原因在于,
import count from './index.js';是import {default as count} from './export';的简写
import {who} from './index.js';是import {who as who} from './index.js';的简写
index.js中导出的对象中没有名为who的对象,import时也就无法解构赋值给who,所以who是undefined。
import和export科普结束
说回Vue组件,假设现在有ComponentTest组件,大部分情况下,components/ComponentTest/index.vue文件内使用的导出方式是export default {components: ,methods:, ...},
外部需要导入这个组件时例举两种写法:
写法1. import ComponentTest from '@/components/ComponentTest';
这种写法,定义的ComponentTest指向的是ComponentTest/index.vue中导出的default对象,所以ComponentTest的内部模板能被解析成html自带的标签。
写法2. import { ComponentTest } from '@/components/ComponentTest';
通过我们对import和export的科普一节我们知道,这种写法中ComponentTest是undefined,神奇的是编译和运行都不会报错,最终渲染出来的dom上空有一对<component-test></component-test>标签,并不会有ComponentTest的功能。
但是有一种情况下,是需要用写法2而非写法1。那就是在使用组件合并导出的时候,比如在@/components/index.js中有如下的代码:
export { default as ComponentA } from './ComponentA';
export { default as ComponentTest } from './ComponentTest';
需要注意一下,export { default as ComponentTest } from './ComponentTest';的作用相当于
import { default as ComponentTest } from './ComponentTest';
export ComponentTest;
也就是说,index.js的导出对象中,包含一个key为ComponentTest的ComponentTest对象,所以在从index.js中导入组件时,要使用以上的写法2,即:
import { ComponentTest } from '@/components';
-
window.location.search和window.location.hash的区别 location.search是第一个问号(含问号)到第一个井号之间的部分,location.hash是第一个井号(含井号)到链接结束的部分。(一个链接中,可能会有多个问号,即如下例子所示,第一个问号后面跟的是针对html页面的参数,第二个问号后面跟的是针对该路由的参数;井号目前只发现一个的情况,如果有多个井号,对于SPA页面路由会混乱 或者 以遇到的第一个井号为准?)
假设有这样一个链接
http://www.hello.com/index.html?userid=123&phone=6553525#/user/findpwd?time=156534456。window.location.search的值为?userid=123&phone=6553525,window.location.hash的值为#/user/findpwd?time=156534456。对于VueRouter,this.$router.query取到的其实就是window.location.hash对应的字符串转换成的js对象。
-
代码更新时出现了A删除了某一个文件夹及其中的文件,但是自己拉到时文件夹还在的情况,此时这个文件夹无法被访问更无法删除。解决办法是关掉VSCode。。。应该是VSCode进程锁住了该目录,外部git工具更新时无法删除掉它。
-
$router.push和$router.replace的区别以及踩到的坑$router.push会把导航堆栈累加,$router.replace会替换导航堆栈最上层的页面为目标页面。对于这样的情形:A push B push C,此时从C后退会依次回到B和A,但如果是A push B replace C,此时从C后退会直接回到A。 坑:页面流转时为了让子页面能方便的取到用户id、token等数据,在query中带上了用户token等公共参数,在VuewRouter的导航守卫上加了钩子,类似这样:router.beforeEach((to, from, next) => { if (from.query.userid) { next({ path: to.path, query: { ...to.query, token: from.query.token, userid: from.query.userid } }); } else { next(); } });这样一来,子页面也能通过query取到用户id、token等数据了,但是由于beforeEach钩子中带参数的行为,其实是相当于是对页面做了重定向,这样钩住会带来以下问题:
- 调用
$router.push或$router.replace会报错Uncaught (in promise) Error: Redirected when going from “abcdefg” to “hijklmn” via a navigation guard.,这个错误并不会导致跳转失败,如果要规避报错也很简单,使用如下代码hook住原有的push和replace方法即可:
const originalPush = router.push; router.push = function(...args) { return originalPush.call(this, ...args).catch(failure => { if (!isNavigationFailure(failure, NavigationFailureType.redirected)) { // beforeEach路由守卫会抛出异常,详情见 https://github.com/vuejs/vue-router/issues/3221 console.error(failure); } }); }; const originalReplace = router.replace; router.replace = function(...args) { return originalReplace.call(this, ...args).catch(failure => { if (!isNavigationFailure(failure, NavigationFailureType.redirected)) { console.error(failure); } }); };$router.replace带来的导航堆栈行为变得与$router.push一样了
- 调用