面试官常问——vue篇

1.vue生命周期
2.vue 双向绑定原理
3.vue router原理
4.vue router动态路由javascript

1.vue 生命周期钩子

clipboard.png

注意:全部的生命周期钩子自动绑定this上下文到实例中,所以你能够访问数据,对属性和方法进行运算。这意味着你不能使用箭头函数来定义一个生命周期方法(例如:created:() => this.fetchTodos() )。这是由于箭头函数绑定了父级上下文,所以this与你期待的vue实例不一样,this.fetchTodos的行为未定义。html

beforeCreate
在实例初始化以后,数据观测(data observer)和 event/watcher事件配置以前被调用。
created
在实例建立完成后被当即调用.在这一步,实例已完成如下的配置:数据观测(data observer),属性和方法的运算,watch/event 事件回调。然而,挂载阶段还没开始,$el属性目前不可见。
beforeMount
在挂载开始以前被调用:相关的 render 函数首次被调用。该钩子在服务器端渲染期间不被调用。该钩子在服务器渲染期间不被调用。
mounted
el被新建立的 vm.$el 替换,病挂载到实例上去以后调用该钩子。若是root实例挂载了一个文档内元素,当 mounted
被调用时 vm.$el 也在文档内。 注意: mounted 不会承诺全部子组件也都一块儿被挂载。若是你但愿等到整个视图都渲染完毕,能够用
vm.$nextTick 替换调 mounted:(该钩子在服务器端渲染期间不被调用)
mounted:function() {
        this.$nextTick(function () {
        //code that will run only after the 
        //entire view has been rendered
   }) }
beforeUpdate
数据更新时调用,发生在虚拟 DOM 打补丁以前。这里适合在更新以前访问现有的DOM,好比
手动移除已经添加的事件监听器。
该钩子在服务器端渲染期间不被调用,由于只有初次渲染会在服务端进行。
updated
因为数据更改致使的虚拟 DOM 从新渲染和打补丁,在这以后会调用该钩子。

当这个钩子被调用时,组件DOM已经更新,因此你如今能够执行依赖于DOM的操做。然而在大多数状况下,你应该避免在此期间更改状态。若是要相应状态改变,一般最好使用计算属性或watcher取而代之。前端

注意 updated 不会承诺全部的子组件都一块儿被重绘。若是你但愿等到整个视图都重绘完毕,能够用vm.$nextTick 替换调
mounted:(该钩子在服务器端渲染期间不被调用)vue

mounted:function() {
    this.$nextTick(function () {
    //code that will run only after the 
    //entire view has been rendered
}) }
activated
keep-alive 组件激活时调用。该钩子在服务器端渲染期间不被调用。
构建组件 keep-alive
动态组件 keep-alive
deactivated
keep-alive组件停用时调用。 该钩子在服务器端渲染期间不被调用
构建组件 keep-alive
动态组件 keep-alive
beforeDestory
实例销毁以前调用。在这一步,实例仍然彻底可用。
该钩子在服务器端渲染期间不被调用。
destoryed
vue实例销毁后调用。调用后,vue实例指示的全部东西都会解绑定,全部的事件监听器会被移除,全部的子实例也会被销毁。
该钩子在服务器端渲染期间不被调用。

2.vue 双向绑定原理

Object.defineProperty是ES5新增的一个API,其做用是给对象的属性增长更多的控制
Object.defineProperty(obj,prop,descriptor)
参数:java

obj: 须要定义属性的对象(目标对象)
 prop:须要定义或修改的属性名(对象上的属性或方法)
 对于setter和getter,个人理解是它们是一对钩子hook函数,当你对一个对象的某个属性赋值时,则会自动调用相应的setter函数;
 而当获取属性时,则调用getter函数。这也是实现双向数据绑定的关键。

clipboard.png

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>vue 双向绑定</title>
</head>
<body>
    <div id="app">
        <input type="text" id="txt">
        <p id="show-txt"></p>
    </div>
</body>
<script type="text/javascript">
    var obj = {};
    Object.defineProperty(obj, 'txt', {
        get: function () {

        },
        set: function (newValue) {
            document.getElementById('txt').value = newValue
            document.getElementById('show-txt').innerHTML = newValue
        }
    })

    document.addEventListener('keyup',function (e) {
        obj.txt = e.target.value
    })
</script>
</html>

3.vue router原理

路由这个概念最早是后端出现的。在之前用模板引擎开发页面时,常常会看到这样git

http://www.xxx.com/login

大体流程能够当作这样:github

1.浏览器发出请求
2.服务器监听到80端口(或443)有请求过来,并解析url路径
3.根据服务器路由配置,返回相应的信息(能够是html字串,也能够是json数据,图片等)
4.浏览器根据数据包`Content-Type`来决定如何解析数据

简单来讲路由就是用来跟后端服务器进行交互的一种方式,经过不一样的路径,来请求不一样的资源,请求不一样的页面是路由的其中一种功能。ajax

前端路由
1.hash模式
随着ajax的流行,异步数据请求交互运行在不刷新浏览器的状况下进行。而异步交互体验的更高级版本就是SPA——单页应用。单页应用不只仅在页面交互是无刷新的,连页面跳转都是无刷新的,为了实现单页应用,因此就有了前端路由。
相似于服务器路由,前端路由实现起来其实也很简单,就是匹配不一样的url路径,进行解析,而后动态的渲染出区域html内容。可是这样存在一个问题,就是URL每次变化的时候,都会形成页面的刷新。那解决问题的思路即是在改变URL的状况下,保证页面的不刷新。在2014年以前,你们是经过hash来实现路由,URL hash 就是相似于:vue-router

http://www.xxx.com/login

这种#。后面hash值的变化,并不会致使浏览器向服务器发出请求,浏览器不发出请求,也就不会刷新页面。另外每次hash值的变化,还会触发
hashchange这个事件,经过这个事件咱们就能够知道hash值发生了哪些变化。而后咱们即可以监听hashchang来实现更新页面部份内容的操做:json

function matchAndUpdate () {
    // todo 匹配 hash 作 DOM 更新
}
window.addEventListener('hashchange',matchAndUpdate)

2.history 模式
14年后,由于HTML5标准发布。多了两个API,pushStatereplaceState,经过这两个API 能够改变url地址且不会发送请求。同时还有 popState 事件。经过这些就能用另外一种方式来实现前端路由了,但原理都是跟 hash 实现相同的。用了 HTML5 的实现,单页路由的 url 就不会多出一个#,变得更加美观。但由于没有 # 号,因此当用户刷新页面之类的操做时,浏览器仍是会给服务器发送请求。为了不出现这种状况,因此这个实现须要服务器的支持,须要把全部路由都重定向到根页面。

function matchAndUpdate () {
    // todo 匹配 hash 作 DOM 更新
}
window.addEventListener('popstate',matchAndUpdate)

vue router实现
咱们在使用vue-router的时候,主要有如下几步:

<div id="app">
    <!-- 路由匹配到的组件将渲染在这里 -->
    <router-view></router-view>
</div>


// 1. 安装 插件
Vue.use(VueRouter);

// 2. 建立router对象
const router = new VueRouter({
    routes // 路由列表 eg: [{ path: '/foo', component: Foo }]
});

// 3. 挂载router
const app = new Vue({
    router
}).$mount('#app');

vue-router 实现 -- install
理解Object.defineProperty的做用

相关文章
相关标签/搜索