1.MVVM

MVVM 是 Model-View-ViewModel 的缩写。
Model代表数据模型,也可以在Model中定义数据修改和操作的业务逻辑。
View 代表UI 组件,它负责将数据模型转化成UI 展现出来。
ViewModel 监听模型数据的改变和控制视图行为、处理用户交互,简单理解就是一个同步View 和 Model的对象,连接Model和View。


2.生命周期

beforeCreate(创建前) 在数据观测和初始化事件还未开始
created(创建后) 完成数据观测,属性和方法的运算,初始化事件,$el属性还没有显示出来
beforeMount(载入前) 在挂载开始之前被调用,相关的render函数首次被调用。实例已完成以下的配置:编译模板,把data里面的数据和模板生成html。注意此时还没有挂载html到页面上。
mounted(载入后) 在el 被新创建的 vm.$el 替换,并挂载到实例上去之后调用。实例已完成以下的配置:用上面编译好的html内容替换el属性指向的DOM对象。完成模板中的html渲染到html页面中。此过程中进行ajax交互。
beforeUpdate(更新前) 在数据更新之前调用,发生在虚拟DOM重新渲染和打补丁之前。可以在该钩子中进一步地更改状态,不会触发附加的重渲染过程。
updated(更新后) 在由于数据更改导致的虚拟DOM重新渲染和打补丁之后调用。调用时,组件DOM已经更新,所以可以执行依赖于DOM的操作。然而在大多数情况下,应该避免在此期间更改状态,因为这可能会导致更新无限循环。该钩子在服务器端渲染期间不被调用。
beforeDestroy(销毁前) 在实例销毁之前调用。实例仍然完全可用。
destroyed(销毁后) 在实例销毁之后调用。调用后,所有的事件监听器会被移除,所有的子实例也会被销毁。该钩子在服务器端渲染期间不被调用。

1.什么是vue生命周期?
答: Vue 实例从创建到销毁的过程,就是生命周期。从开始创建、初始化数据、编译模板、挂载Dom→渲染、更新→渲染、销毁等一系列过程,称之为 Vue 的生命周期。

2.vue生命周期的作用是什么?
答:它的生命周期中有多个事件钩子,让我们在控制整个Vue实例的过程时更容易形成好的逻辑。

3.vue生命周期总共有几个阶段?
答:它可以总共分为8个阶段:创建前/后, 载入前/后,更新前/后,销毁前/销毁后。

4.第一次页面加载会触发哪几个钩子?
答:会触发 下面这几个beforeCreate, created, beforeMount, mounted 。

5.DOM 渲染在 哪个周期中就已经完成?
答:DOM 渲染在 mounted 中就已经完成了。


3.Vue实现数据双向绑定的原理:Object.defineProperty()

<div id="app">
    <input type="text" id="text">
    <p id="show"></p>
</div>
<script type="text/javascript">
    var obj = {}
    Object.defineProperty(obj, 'text', {
        get: function () {
            return obj
        },
        set: function (val) {
            document.getElementById('text').value = val
            document.getElementById('show').innerHTML = val
        }
    })
    document.addEventListener('keyup', function (e) {
        obj.text = e.target.value
    })
</script>

4.组件间参数传递

1.父组件与子组件传值
父组件传给子组件:子组件通过props方法接受数据;
子组件传给父组件:$emit方法传递参数
2.非父子组件间的数据传递,兄弟组件传值 :VUEX


5.vue常用指令

v-if v-show v-else v-for v-on v-bind


6.vue中key值的作用

需要使用key来给每个节点做一个唯一标识,Diff算法就可以正确的识别此节点,找到正确的位置区插入新的节点。其实不只是vue,react中在执行列表渲染时也会要求给每个组件添加上key这个属性。


7.Vue组件中的data为什么必须是函数

一个组件的 data 选项必须是一个函数,因此每个实例可以维护一份被返回对象的独立的拷贝.


8.Vue如何监听键盘事件中的按键

<input @keyup.enter="function">
别名实际键值
.deletedelete(删除)/BackSpace(退格)
.tabTab
.enterEnter(回车)
.escEsc(退出)
.spaceSpace(空格键)
.leftLeft(左箭头)
.upUp(上箭头)
.rightRight(右箭头)
.downDown(下箭头)
.ctrlCtrl
.altAlt
.shiftShift
.meta(window系统下是window键,mac下是command键)

vue还有组合写法

组合写法按键
@keyup.alt.67="function"Alt + C
@click.ctrl="function"Ctrl + Click

8.Vue中的过滤器有什么用?

Vue.js 允许你自定义过滤器,可被用于一些常见的文本格式化。过滤器可以用在两个地方:双花括号插值和 v-bind 表达式 (后者从 2.1.0+ 开始支持)。过滤器应该被添加在 JavaScript 表达式的尾部,由“管道”符号指示:

一个代码示例:

<!-- 在双花括号中 -->
<span class="timeline-time">{{value|handleDay}}</span>

<!-- 在 `v-bind` 中 -->
<div v-bind:id="value| handleDay"></div>
filters: {
    handleDay(value) {
        return value.split(" ")[0].split("-")[2] + " 日";
    }
},

一个简单的例子
添加过滤器之后,可直接将2020-03-24 22:39:31格式化为24 日


9.vue-router导航钩子

1.全局前置守卫

const router = new VueRouter({ ... })

router.beforeEach((to, from, next) => {
  // ...
})

2.全局后置守卫

router.afterEach((to, from) => {
  // ...
})

3.路由独享的守卫

const router = new VueRouter({
  routes: [
    {
      path: '/foo',
      component: Foo,
      beforeEnter: (to, from, next) => {
        // ...
      }
    }
  ]
})

4.组件内的守卫

const Foo = {
  template: `...`,
  beforeRouteEnter (to, from, next) {
    // 在渲染该组件的对应路由被 confirm 前调用
    // 不!能!获取组件实例 `this`
    // 因为当守卫执行前,组件实例还没被创建
  },
  beforeRouteUpdate (to, from, next) {
    // 在当前路由改变,但是该组件被复用时调用
    // 举例来说,对于一个带有动态参数的路径 /foo/:id,在 /foo/1 和 /foo/2 之间跳转的时候,
    // 由于会渲染同样的 Foo 组件,因此组件实例会被复用。而这个钩子就会在这个情况下被调用。
    // 可以访问组件实例 `this`
  },
  beforeRouteLeave (to, from, next) {
    // 导航离开该组件的对应路由时调用
    // 可以访问组件实例 `this`
  }
}

10.vue-router参数传递方法详述及区别

1.path显示传递

//发送数据
jump(id) {
    this.$router.push({
        path: `/article/${id}`
    });
},
//路由
{
    path: '/article/:id',
    name: 'article',
    component: (resolve) => require(['./views/Article.vue'], resolve)
},
//接收
this.$route.params.id
//url
http://ciblog.zhangyifei.top/article/10

2.name隐式传递页面刷新数据会丢失

//发送数据
jump(id) {
    this.$router.push({
        name: 'article',
        params: {
          id: id
        }
    });
},
//路由
{
    path: '/article',
    name: 'article',
    component: (resolve) => require(['./views/Article.vue'], resolve)
},
//接收数据
this.$route.params.id
//url
http://ciblog.zhangyifei.top/article

3.path显示传递

//发送数据
jump(id) {
    this.$router.push({
        path: '/article',
        query: {
          id: id
        }
    });
},
//路由
{
    path: '/article',
    name: 'article',
    component: (resolve) => require(['./views/Article.vue'], resolve)
},
//接收数据
this.$route.query.id
//url
http://ciblog.zhangyifei.top/article?id=10

4.link-to

//发送数据
<router-link :to="{path:'/article',query: {id: id}}">跳转</router-link>
//路由
{
    path: '/article',
    name: 'article',
    component: (resolve) => require(['./views/Article.vue'], resolve)
},
//接收数据
this.$route.query.id
//url
http://ciblog.zhangyifei.top/article?id=10

12.路由懒加载

当打包构建应用时,JavaScript 包会变得非常大,影响页面加载。如果我们能把不同路由对应的组件分割成不同的代码块,然后当路由被访问的时候才加载对应组件,这样就更加高效了。
结合 Vue 的异步组件和 Webpack 的代码分割功能,轻松实现路由组件的懒加载。

const routes = [{
        path: '/',
        name: 'home',
        component: (resolve) => require(['./views/Home.vue'], resolve),
    }
];

或者

const routes = [{
        path: '/',
        name: 'home',
        component: ()=>import("./views/Home.vue")
    }
];

12.什么是vuex以及应用

个人理解
vuex就是专门为vue设计的状态管理库
应用:涉及到非父子跨组件传值。多个页面之间公用同一数据。多页面之间可以修改同一数据。