基础篇
1、什么是盒子模型?
页面就是由一个个盒模型堆砌起来的,每个HTML元素都可以叫做盒模型,盒模型由外而内包括:边距(margin)、边框(border)、填充(padding)、内容(content)。它在页面中所占的实际宽度是margin + border + paddint + content 的宽度相加。
2、行内元素、块级元素有哪些,有何区别,如何转换?
分别有:块级元素div p h1 h2 h3 h4 form ul 行内元素: a b br i span input select
区别
行内元素会在一条直线上排列,都是同一行的。块级元素各占据一行,垂直方向排列。
块级元素可包含行内、块级元素。行内元素不能包含块级元素,只能包含文本或其它行内元素。
行内元素与块级元素属性的不同,主要是盒模型属性上:行内元素设置width无效,height无效(可以设置line-height),margin上下无效,padding上下无效
转换:display:block;设为块级元素。display:inline;设为行内元素
3、前端页面有哪三层构成,分别是什么?作用是什么?
结构层 Html 、表示层 CSS、 行为层 js
4、如下有一段html,请用原生js或jq满足如下要求【dom】
<div class="mydiv">
<lable>用户名:</lable>
<input type="text" data-name="uname" value="hello"/>
</div>
a:将lable中的内容设置为 当前值+当前时间戳
b:将input的值 设置为 当前值+当前时间戳
c:将input中的自定义属性data-name设置为 当前值+当前时间戳
高级篇
5、描述一下js都有哪些作用域。如下代码的结果是什么,并且分析原因【作用域】
var arr = [];
for(var i=0;i<10;i++){
arr[i]=function(){
return i;
}
}
var res=arr[3]()
console.log(res);
显然这段代码输出10,并没有向我们期望的返回3,原因也很简单(js的变量提升)函数在调用时候访问的是一个全局作用域的i,此时for循环已经执行完毕,全局变量i=10;
如果想输出3,两种办法,1中是用es6的let。另一种是利用函作用域通过立即执行函数来对其闭包。具体代码如下
6、js有几种数据类型,分别都有哪些。按照内存结构如何区分,存储结构有何区别
5种简单数据类型:Undefined, Null, Boolean, Number, String.
1种复杂数据类型:Object(Array,Date,Function).
上面的5种简单数据类型又称为基本数据类型,复杂数据类型又称为引用数据类型。基本数据类型保存在栈内存,引用数据类型实际上是一个指针,这个指针也保存在栈中,但是这个指针指向的对象则保存在堆内存中。
var arr = [];
for(var i=0;i<10;i++){
arr[i]=(function(i){
return function(){
return i;
}
})(i)
}
var res=arr[3]()
console.log(res);
// 这样一来数组的每个函数就处于一个立即执行函数的函数作用域中,该立即执行函数传入i,其实for循环执行了如下代码:
// array[0]=(function(i){
// return function(){
// return i;
// }
// })(0);
// array[1]=(function(i){
// return function(){
// return i;
// }
// })(1);
// 这样一来,数字组中每个函数对应一个单独的函数作用域(立即执行函数的)这里共创建了10个函数作用域,这些函数作用域里的i值就是执行时候传入的0……9,当执行
// array[3]();时候函数访问的i值是其对应的立即执行函数作用域里的 i,而不是全局的i值,这样我们就得到了预期的效果。
// 说得到这里我们简单来说一下闭包,闭包可以理解为一个闭包就是一个没有释放资源的栈区,栈区内的变量处于激活状态。上面的例子中for循环在执行时系统分配内存,js执行线程创建执行栈区,执行
7、目前为止,js都有哪些实现继承的办法。【面向对象】
原型链继承:将父类的实例作为子类的原型
借用构造函数继承:apply与call
es6:关键字extend
8、如何避免回调地狱(如何优雅的处理回调),并给出如下代码优雅解决方案【es6+】
service.js代码如下
let myService={
/**
*功能:获取教师id,即tid
*参数:tno--教师编号
*/
getTcId:function (param) {
let result=$.post('http://localhost:8080/getTcId',param);
return result;
},
/**
*功能:获取老师详细信息
*参数:tid--教师id
*/
getTcInfo:function (param) {
let result=$.post('http://localhost:8080/getTcInfo',param);
return result;
}
}
index.html如下
<button>获取张老师信息</button>
<div class="tinfo"></div>
<script src="service.js"></script>
<script>
$('button').click(function () {
let param={tno:20160808};
getTcId(param).then(function (rep) {
let tid=rep.tid;
let param={tid:tid}
getTcInfo(param).then(function (rep) {
$('tinfo').html(`老师的详细信息为:${rep}`)
})
})
})
</script>
更改index.html中的script部分,使其代码优雅处理回调
参考答案:
$('button').click(async function () {
let tid=(await getStudent({tno:20160808})).tid;
let tinfo=await getStudent({tid:tid})
$('tinfo').html(`老师的详细信息为:${rep}`)
})
组件篇
9、什么是mvvm,它和mvc有何区别?【设计思想】
什么是mvvm
MVVM是Model-View-ViewModel的缩写,是一种设计思想。Model 层代表数据模型;View 代表UI 组件,它负责将数据模型转化成UI 展现出来,ViewModel 是一个同步View 和 Model对象。
在MVVM架构下,View 和 Model 之间并没有直接的联系,而是通过ViewModel进行交互,Model 和 ViewModel 之间的交互是双向的, 因此View 数据的变化会同步到Model中,而Model 数据的变化也会立即反应到View 上。
ViewModel 通过双向数据绑定把 View 层和 Model 层连接了起来,而View 和 Model 之间的同步工作完全是自动的,无需人为干涉,因此开发者只需关注业务逻辑,不需要手动操作DOM, 不需要关注数据状态的同步问题,复杂的数据状态维护完全由 MVVM 来统一管理。
和传统mvc的区别
mvc和mvvm其实区别并不大。都是一种设计思想。主要就是mvc中Controller演变成mvvm中的viewModel。mvvm主要解决了mvc中大量的DOM 操作使页面渲染性能降低,加载速度变慢,影响用户体验。
10、Vue组件之间如何通信,父子组件通信(父-->子,子-->父),兄弟组件通信
父组件通过标签上面定义传值,子组件通过props方法接受数据【vue通信】
//父组件中
<child message="hello!"></child>
//子组件中
<template>
<div>
{{message}}
</div>
</template>
export default {
name: "baseLayer",
props:['message']
}
/*需要注意的是,子组件不能修改父组件的props
因为一个父组件下可能有多个子组件,如果某个子组件修改了父组件传递的props,
很可能导致其他子组件也就跟着变化,最终导致整个应用的状态难以管理和维护
所以不允许子组件修改props*/
子->父: 子组件自定义事件,子组件通过$emit方法传递参数,父组件可以在使用子组件的地方用 v-on 来监听子组件触发的事件
//父组件中
<template>
<div class="father">
<child v-on:result="clickChild"></child>
</div>
</template>
<script>
import child from '@/compoment/child'
export default {
name:'father',
components:{child},
methods:{
clickChild(type){
alert(type)
}
}
}
</script>
//子组件中
<template>
<div>
<button v-on:click="clickBtn(true)">确定</button>
</div>
</template>
export default {
name: "child",
methods:{
clickBtn(b){
//监听result变化, 并发出通知
//(在angularjs中叫做广播,angularjs提供了emit,
//broadcast和$on服务用于向父中传递消息)
this.$emit('result', b);
}
}
兄弟或者复杂组件间的通信,推荐使用vuex,参考笔记
http://www.cnblogs.com/flyings/p/9022583.html
10、vue-router如何定义一个带参数的路由,并且写出跳转至此路由,此路由对应的组件如何接受对应的参数【vue路由】
export default new Router({
routes: [
{
path: '/',
name: 'home',
component: home
},
{
path: '/blogDetail/:bid',
name: 'BlogDetail',
component: blogDetailCmp
}]
//跳转至此组件,并携带参数
编程式:this.$router.push({ name: 'BlogDetail', params: { bid: 20160808}})
声明式:<router-link :to="{ name: 'user', params: { bid: 20160808 }}">详情</router-link>
//此组件如何接受参数
this.$route.params.bid
11、vue生命周期函数(钩子)都有哪些?DOM 渲染在 哪个周期中就已经完成。请列举出3个Vue中常用的生命周期钩子函数
【vue钩子】
可以总共分为8个阶段:创建前/后, 载入前/后,更新前/后,销毁前/销毁后
在mounted阶段
created: 实例已经创建完成之后调用,在这一步,实例已经完成数据观测, 属性和方法的运算, watch/event事件回调. 然而, 挂载阶段还没有开始, $el属性目前还不可见
mounted: el被新创建的 vm.$el 替换,并挂载到实例上去之后调用该钩子。如果 root 实例挂载了一个文档内元素,当 mounted 被调用时 vm.$el 也在文档内。
activated: keep-alive组件激活时调用
12、v-show和v-if指令的共同点和不同点 【vue指令】
v-show指令是通过修改元素的display的CSS属性让其显示或者隐藏
v-if指令是直接销毁和重建DOM达到让元素显示和隐藏的效果
13、如何让css只在当前组件中起作用【vue组件】
将当前组件的<style>修改为<style scoped>
14、如何定义一个vue组件,别人只需要安装你的插件,无需再页面引入import 模板也无需插入该组件,便可以直接调用。比如toast弹窗插件。某个组件用的时候,直接 this.$toast('验证中通过',1000) ,既可以弹出。【vue组件进阶】
./plugin/modal/index.js
import mytoast from './toast';
export default {
install:function(Vue){
//生成一个Vue的子类,同时这个子类也就是组件.并生成一个该子类的实例
const Toast = Vue.extend(mytoast);
let toast = new Toast();
// 将这个实例挂载在我创建的div上, 并将此div加入全局挂载点内部
toast.$mount(document.createElement('div'))
document.body.appendChild(toast.$el)
//挂在到全局
Vue.prototype.$toast=function (msg,time) {
toast.msg=msg;
toast.open();
if(time){
setTimeout(function () {
toast.close();
},time)
}
}
main.js启动直接注入到全局实例中就行
import modal from './plugin/modal/index'
Vue.use(modal)//启用自己的插件
15、<keep-alive></keep-alive>的作用是什么,如果使用了keep-alive,页面中哪些钩子会被触发【vue原生内置组件】
<keep-alive></keep-alive> 包裹动态组件时,会缓存不活动的组件实例,主要用于保留组件状态或避免重新渲染。比如滚动的位置,表单的值
当组件在 <keep-alive> 内被切换,它的 activated 和 deactivated 这两个生命周期钩子函数将会被对应执行。
16、vue中如何定义一个全局的插件,在任何组件中都可以使用。比如定义个工具类,工具类里有获取当前时间的插件。 我想在任意组件中都可以 this.utils.getTime()来调用。请大致写出【vue插件】
17、vue常用的指令都有哪些【vue指令】
v-if:判断是否隐藏;v-for:数据循环;v-bind:绑定一个属性; v-model:实现双向绑定 ; v-on事件; v-html渲染dom; v-once只绑定一次就不在改变...
18、vue如何自定指令
分为全局和局部
// 注册一个全局自定义指令 `v-focus`
Vue.directive('focus', {
// 当被绑定的元素插入到 DOM 中时……
inserted: function (el) {
// 聚焦元素
el.focus()
}
})
directives: {
focus: {
// 指令的定义
inserted: function (el) {
el.focus()
}
}
}
使用
<input v-focus>
19、VNode是什么?虚拟 DOM是什么?
Vue在 页面上渲染的节点,及其子节点称为“虚拟节点 (Virtual Node)”,简写为“VNode”。“虚拟 DOM”是由 Vue 组件树建立起来的整个 VNode 树的称呼。
20、谈谈你对单页Web应用(single page web application,SPA)的理解