1、css盒模型和怪异模型
border-sizing: border-box/* 表示怪异盒模型 */
border-sizing: content-box/* 表示标准盒模型 */
怪异盒模型:
元素的总宽度 = width(包括内容宽度+border+padding) + margin
标准盒模型:
总宽度 = width + border + padding + margin
2、闭包
3、作用域链
要了解作用域链,首先要知道什么是作用域,作用域就是变量能够生效的区域,作用域分为全局作用域、局部作用域、ES6的块级作用域。
- 全局作用域:打开页面时,就生成了一个全局作用域,是挂载到 window 下的,定义在全局作用域下的变量,在任何地方都可以访问
window.x
; - 局部作用域:又叫函数作用域,是函数内部的一个范围,在函数内定义的变量,只能在该函数里面去访问,外部无法访问。
- ES6的块级作用域:简单来说就是用
let
和const
在任意的代码块中定义的变量都认为是块级作用域中的变量,例如在for循环中用let定义的变量,在if语句中用let定义的变量等等 (JS是没有块级作用域的) - 作用域链:
js查找变量的顺序就是作用域链。简单来说,就是有在最内部的 作用域 中,查找一个变量,内部作用域中没有,就会向上一级作用域查找,若还没有,就再往上一级查找…这个查找变量的过程形成的链条,就叫作用域链。
3、this指向
1)普通函数调用,this指向window对象
function fn() {
console.log(this)
}
fn() //window对象
2)构造函数调用,指向 实例对象
function Person(age,name) {
this.age = age;
this.name = name;
console.log(this) //Person {age: 18, name: '张三'}
}
var p1 = new Person(18,"张三");
3)对象方法调用,指向 该方法所属对象
var obj = {
fn: function () {
console.log(this); //{fn: ƒ}
}
}
obj.fn();
console.log()//{fn: ƒ}
4)事件绑定的方法,指向 绑定事件的对象(绑定事件的dom元素)
<button id="btn">按钮</button>
<script>
var btn = document.querySelector("#btn");
btn.onclick = function () {
console.log(this); //<button id="btn">按钮</button>
}
</script>
5)定时器函数,指向 window 对象
setInterval(function () {
console.log(this); //window 对象
},2000)
3-1、更改 this 指向的方法
1)apply
fn.call(Person,["hh",20]);
2)call
fn.call(Person,"hh",20);
3)bind
fn.bind(obj)()
4、promise、async、和await
5、set和map的区别
1)都是 ES6 的一种数据结构
2)都有增删改查方法,都可循环:
map:set、delete、get、has
set:add、delete、has、clear
3)set 是集合,存放的是 value,如 [value1,value2,value3],值是不可重复的;map 是字典,存放的是键值对,key 不可重复,value 可重复
6、http协议(状态码、八种请求方式、构成)
7、跨域
8、输入 url 到页面加载发生了什么
9、ajax和axios的区别
axios 是基于 promise 封装的;ajax 是异步请求技术。
axios 支持promise api;是从 node.js 创建的请求,接收一个对象,对象包含请求参数,请求成功后调用 promise 里的 then方法;
ajax 是基于原生的 XHR 开发的,接收一个对象,对象里包括请求参数,还有 success 和 error 后的回调方法。
10、路由传参的几种方式
分为两种,一是 query 方式传参,二是 params 传参。
1)query 传参
- 是将参数通过
?
和&
符号,将参数在跳转到新页面时,拼接到 url 上, - 不需要修改路由中的配置信息,
- 获取参数时用
this.$route.query.name
。 - 这种情况,有无参数都会加载对应组件,没有参数可能导致页面数据出错。
2)params 传参
- 是将参数直接通过
/
拼接到 url 上, - 另外需要修改对应的路由的 path 参数:
/about/:name/:id
, - 获取参数时用
this.$route.params.name
。 - 这种情况下,有参数时,才会加载对应的组件,没有参数或者参数不全时,组件加载不出来。
如下:home 路由用的是 query 方式传参,about 路由用的是params 传参
<!-- app.vue -->
<nav>
<router-link to="/?name=lisi&id=456">Home</router-link> |
<router-link to="/about/zhangsan/123">About</router-link>
</nav>
<!-- about.vue params 方式-->
<h2>params 参数是:{{$route.params.name}}</h2>
<!-- home.vue query 方式 -->
<h2>query 参数是:{{$route.query.name}}</h2>
// router/index.js
import VueRouter from "vue-router";
import HomeView from "../views/HomeView.vue";
Vue.use(VueRouter);
const routes = [
{
path: "/",
name: "home",
component: HomeView,
},
{
path: "/about/:name/:id",
name: "about",
component: () =>
import(/* webpackChunkName: "about" */ "../views/AboutView.vue"),
},
];
11、路由组件传值方式
1)props(父传子)
2)$emit(子传父)
3)vuex(父子之间相互传值)
4)创建全局 vue 对象,数据挂载到这个对象上(父子之间传值)
12、导航守卫
1)全局前置守卫“beforeEach”;
2)全局解析守卫“beforeResolve”;
3)路由独享的守卫“beforeEnter”;
4)组件内的守卫“beforeRouteEnter”、“beforeRouteLeave”
13、路由模式有哪几种
const router = new VueRouter({
routes,
mode:'abstract'
});
1)hash 模式 (http://localhost:8082/#/about)
是在 url 后面用 #
连接,不会导致浏览器向服务器发送请求,也不会刷新页面。hash 值变化,会触发 hashchange
事件,通过这个事件可以知道 hash 值发生了哪些改变。
HashHistory
有两个方法:HashHistory.push()
将新路由添加到浏览器访问历史的栈顶,和 HashHistory.replace()
替换当前栈顶的路由。
window.onhashchange = function (event) {
console.log(event.oldURL, event.newRUL);
let hash = location.hash.slice(1);
document.body.style.color = hash;
}
2)history 模式 (http://localhost:8082/about)
该模式是利用 h5 新增的 pushstate()
和 replacestate()
将地址直接压入历史记录找,这两个方法可以改变 url 地址,不会发送请求;可以读取历史记录栈,也可以对浏览器历史记录栈进行修改。
通过 popstate
进行监听实现页面跳转到。
3)区别
- hashchange 只能改变 # 后的 url 片段,而pushstate 设置的新的 url 可以是与当前 url 同源的任意 url
- history 模式会将 url 修改的和正常请求后端的 url 一样,如果后端没有配置对应路由处理,会返回 404 错误。
14、循环中key的作用
如上图,有 a,b,c,d,e 5个元素,要在 c,d 中间插入一个 z,如果不用 key ,vue 会把 d 改为 z,d 和 e 会重新渲染;有 key 的话,原来的 5 个元素会进行复用,只是在 c 和 d 中间插入新的元素。
15、route和router的区别
可以理解为,一个是用来获取路由信息的,一个是用来操作路由的。
1)route 是路由信息对象
每一个路由都会有一个 route 对象,是一个局部的对象,里面包含路由的一些基本信息,如:name、meta、path、hash、query、params、fullPath、matched、redirectionFrom 等。
2)$.router 是 VueRouter 的实例
通过 Vue.use(VueRouter)
和 VueRouter
构造函数等到一个 router 的实例对象,这个对象中是一个全局的对象,它包含了路由的跳转方法和钩子对象回调。
this.$router.push({path:'home'});
this.$router.go(-1);
this.$router.replace('/');
16、v-if和v-for为什么不能连用
v-for 比 v-if 具有更高的优先级,vue 会先循环所有的数据再进行判断,影响性能。
解决方法:
1)外部包一层 template 标签进行 if 判断,内部 for 去循环
2)利用计算属性
17、v-show和v-if的区别
- v-show 是改变元素css 的 display,为 false 时,dom元素还在文档流中,只是
display:none
不显示在页面上。 - v-if 是适当销毁重建元素。初始化为 false 时,元素不会渲染,为 true 时,才开始编译。
v-show
是简单的css属性切换,适合用于频繁切换显示与隐藏的场景。v-if
切换开销较大,适合条件一经改变,就不再切换的场景。
18、token的作用
token 是服务端生成的一串字符串,作为客户端进行请求的一个标识。
当接口限定只能在登录状态调用的情况下,需要用到token,它是服务器根据账号的用户名和密码生成的字符串。
用户第一次登陆后,服务器生成一个 token ,并将该 token 返回给客户端,客户端将这个 token 保存在缓存中(cookie或者Local Storage),以后客户端请求数据时,在请求头上,带上这个 token,服务端通过这个 token 判断用户是否已登录,登录状态正常返回数据,否则返回一个标识,告诉客户端没有 token (或者 token 已失效),客户端接收以后,重新登录获取新的 token,并重置前端缓存的token。
简单的token组成:uid(用户唯一的身份标识,如账户/密码)、time(当前时间的时间戳)、sign(签名)。
19、keep-alive
1)是什么
keep-alive 是 Vue 的内置组件,当它包裹动态组件时,会缓存不活动的组件实例,而不是销毁。
2)作用
用来缓存组件,避免多次加载相同的组件,减少性能消耗,提升用户体验。
3)怎么用
法一:
<div>
<keep-alive>
<tar-bar></tar-bar>
</keep-alive>
</div>
法二:
<!-- 缓存 name 为 cc 的组件,若有多个,用逗号分隔 -->
<keep-alive include="cc">
<router-vire/>
</keep-alive>
<!-- 缓存 name 不为 cc 的组件,若有多个,用逗号分隔 -->
<keep-alive exclude="cc">
<router-vire/>
</keep-alive>
法三:路由配置阶段配置组件是否缓存,组件里面进行判断
//router/index.js
const routes = [
{
path: '/Home',
component: Home,
meta: {
keepalive: true
}
},
{
path: '/about',
component: About,
meta: {
keepalive: false
}
}
]
<div id="app">
<!--keep-alive 表示页面不会被销毁,即保持页面状态-->
<keep-alive>
<router-view v-if="$route.meta.keepalive"></router-view>
</keep-alive>
<router-view v-if="!$route.meta.keepalive"></router-view>
</div>
20、权限管理怎么做
21、lodash有哪些常用的api
22、什么是动态组件
动态组件是指:在一个页面点一个位置使用多个组件,并进行动态切换。常见的功能如:tab切换
vue中实现该功能有两种方法。一是使用 <component>
元素的 is 特性,二是使用 v-if。
1)compoment
<!-- currentView 是组件名,如果组件里的内容不会更改的话,还可以用 keep-alive 标签包起来, -->
<component :is="currentView"></component>
2)if
<div v-if="isactive"></div>
<div v-else></div>
24、异步组件
1)工厂函数(通过 require 引入组件)
// 全局注册
Vue.component('child1', function (resolve) {
require(['./components/child1'], resolve)
})
// 局部注册
components: {
Child1: function (resolve) {
require(['./components/child1'], resolve)
}
}
2)Promise(通过 import 引入组件)
// 全局注册
Vue.component('child2', () => import('./components/child2'))
// 局部注册
components: {
Child2: () => import('./components/child2')
}
25、vue 如何动态绑定路由信息
1)路由配置时,meta 对象里配置角色标识,跳转路由的时候判断权限,true 时继续往下执行,false 时,跳到 404
#2)接口返回路由配置,前端拿到数据进行处理(主要是组件引入的处理),处理完以后存放到缓存中,通过 addRoute 添加路由
26、OOP思想
27、两个input事件顺序
场景:有两个input框,input1上绑定了一个失焦 blur 事件,input2上绑定了一个聚焦 focus 事件,焦点在input1上,此时,点击input2,那么,两个input框上事件的执行顺序是什么?
答:先执行ipnut1的失焦事件,之后再执行ipnut2的聚焦事件。
28、jquery中的attr和prop的区别
- attr 在 jqury 1.0 版本就已经有了,prop 在 jquery 1.6 版本才新增。
- attr 设置的属性在控制台 element 里面可以在元素的节点上查看,prop 从节点上无法查看
- attr 设置的属性,属性值会自动转换为 字符串 类型,prop 不会转换,可以使用 number、arry 类型的数据。
- attr 对于checked、selected等属性返回的是字符串,prop 返回的是 布尔类型 (true、false)
- attr 设置属性方法为
$("#span1").attr("num",123)
,移除属性方法为$("#span1").removeAttr("num")
;prop设置属性的方法为$("#span2").prop("num",123)
,移除属性方法为$("#span2").removeProp("num")
30、vue的持久化存储
- 手动存本地 localStorage
- vuex-persistedstate 插件(本质也是存到 localStorage,也可修改为 sessionStorage)
31、css如何兼容所有浏览器
1、CSS Hack
CSS Hack就是针对不同的浏览器或不同版本浏览器写特定的CSS样式达到让浏览器兼容的过程。
div{
background:green;/*forfirefox*/
*background:red;/*forIE6*/(bothIE6&&IE7)
}
2、条件注释法
IE条件注释(Conditional comments)是IE浏览器私有的代码,在其它浏览器中被视为注释。
<!--[if IE]>
<link rel="shortcut icon" href="{{ MEDIA_URL }}img/favicon.png?t=1398068110"/>
<![endif]-->
32、sass有哪些方法
1、允许使用变量,所有变量以$开头。
/* 变量声明 */
$fontStack: Helvetica, sans-serif;
$primaryColor: #333;
body {
font-family: $fontStack;
color: $primaryColor;
}
//编译成css为:
body {
font-family: Helvetica, sans-serif;
color: #333;
}
2、允许在代码中进行计算
.div2 {
margin: 10px * 2;
padding:(14px / 2);
}
//编译成css为:
.div2 {
margin: 20px;
padding: 7px;
}
3、允许选择器嵌套
nav {
ul {
margin: 0;
padding: 0;
list-style: none;
}
li { display: inline-block; }
}
//编译成css为:
nav ul {
margin: 0;
padding: 0;
list-style: none;
}
nav li {
display: inline-block;
}
4、允许&的嵌套
a {
margin: 10px;
&:hover {
color: #000;
}
}
//编译成css为:
a {
margin: 10px;
}
a:hover {
color: #000;
}
5、允许一个选择器,继承另一个选择器
.div3 {
margin: 2px;
}
/* .div4继承.div3 */
.div4 {
@extend .div3;
font-size: 10px;
}
//编译成css为:
.div3, .div4 {
margin: 2px;
}
.div4 {
font-size: 10px;
}
6、可以使用混入 minx
7、可以引入文件
@import "path/filename.scss";
@import "foo.css";