1

Java面试题-前端Vue_博观而约取,厚积而薄发的技术博客_51CTO博客

 1 year ago
source link: https://blog.51cto.com/xiongmaoit/5971169
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

Table of Contents

Vue的生命周期

  • 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 中就已经完成了。

Vue实现数据双向绑定

vue.js 则是采用数据劫持结合发布者-订阅者模式的方式,通过Object.defineProperty()来劫持各个属性的settergetter,在数据变动时发布消息给订阅者,触发相应的监听回调

总结

双向绑定既不仅model可以影响view的数据,view也可以影响model的数据

例子:

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width,initial-scale=1.0">
    <title>wue01</title>
    <script src="vue.min.js"></script>
  </head>
  <body>
    <div id="app">
      <div>{{ message }}</div>
      <input v-model="message">
      {{ message }}
    </div>
  </body>
  <script>
    new Vue({
      el: '#app',
      data: {
        message: 'Hello Vue.js!'
      }
    })
  </script>
</html>

Vue组件间的参数传递

  1. 父组件与子组件传值

    父组件传给子组件:子组件通过props方法接受数据;
    子组件传给父组件:$emit方法传递参数

    <app-test v-bind:pops="lists,obj" v-on:showmsg="showhh($event)"></app-test>
    
    <template>
        <div>
            {{msg}}
          <ul>
            <li v-for="po in pops">
              主键:{{po.id}}-姓名:{{po.name}}-名称:{{po.username}}-手机号码:{{po.phone}}-邮件:{{po.email}}
            </li>
          </ul>
          {{this.obj.name}}-{{this.obj.age}}
          <button @click="updatemsg">改变父级页面</button>
        </div>
    </template>
    
    <style>
        body {
            background-color: limegreen;
        }
    </style>
    
    <script>
        export default {
            /**简约写法*/
            //props:["pops"],
             //props:["obj"],
            /**标准写法*/
            props:{
              pops:{
                type:Array,
                required:true
              },
              obj:{
                type:Object,
                required:true
              }
            },
            data() {
                return {msg: '这个是Home模板页'}
            },mounted(){
              console.log(this.obj);
           },methods:{
              updatemsg(){
                this.$emit("showmsg","改变了父级msg内容");
              }
          }
        }
    </script>
    
  2. 非父子组件间的数据传递,兄弟组件传值**

    eventBus,就是创建一个事件中心,相当于中转站,可以用它来传递事件和接收事件。项目比较小时,用这个比较合适。

vue路由的钩子函数

首页可以控制导航跳转,beforeEach,afterEach等,一般用于页面title的修改。一些需要登录才能调整页面的重定向功能。

  • beforeEach主要有3个参数to,from,next;

  • to:route即将进入的目标路由对象;

  • from:route当前导航正要离开的路由;

  • next:function一定要调用该方法resolve这个钩子。执行效果依赖next方法的调用参数。可以控制网页的跳转;

vuex是什么?

只用来读取的状态集中放在store中; 改变状态的方式是提交mutations,这是个同步的事物; 异步逻辑应该封装在action中。
在main.js引入store,注入。新建了一个目录store,…… export 。

state

Vuex 使用单一状态树,即每个应用将仅仅包含一个store 实例,但单一状态树和模块化并不冲突。存放的数据状态,不可以直接修改里面的数据。

import Vue from 'vue'
import Vuex from 'vuex'
import * as getters from  './getters'   /** 导入响应的模块,*相当于引入了这个组件下所有导出的事例*/
import * as actions from  './action'
import * as mutations from './mutations'

Vue.use(Vuex);

/**首先声明一个需要全局维护的状态 state  默认值*/
const state = {
  lists:[],
  name:'username',
  password:'userpassword'
};

// 注册上面引入的各大模块
const store = new Vuex.Store({
  state,    // 共同维护的一个状态,state里面可以是很多个全局状态
  getters,  // 获取数据并渲染
  actions,  // 数据的异步操作
  mutations  // 处理数据的唯一途径,state的改变或赋值只能在这里
});

export default store  // 导出store并在 main.js中引用注册
import store from './store'

mutations

mutations定义的方法动态修改Vuex 的 store 中的状态或数据。

// 提交 mutactions是更改Vuex状态的唯一合法方法
// 把方法传递过来的参数,赋值给state中的lists
export const getlist = (state,lists) => {
  state.lists = lists
};

export const updateUserInfo = (state,name) =>{
  state.name = name;
};

getters

类似vue的计算属性,主要用来过滤一些数据。

export const resultlist = state => state.lists;

/** 存储 和 取值方式*/
/*
this.$store.dispatch("setname",'nick');
console.log(myvue.$store.state.name);
*/

action

actions可以理解为通过将mutations里面处里数据的方法变成可异步的处理数据的方法,简单的说就是异步操作数据。view 层通过 store.dispath 来分发 action。

// 给action注册事件处理函数。当这个函数被触发时候,将状态提交到mutactions中处理
export const setlist = ({commit},lists) => commit('getlist',lists);
export const setname = ({commit},name) => commit('updateUserInfo',name);

modules

项目特别复杂的时候,可以让每一个模块拥有自己的state、mutation、action、getters,使得结构非常清晰,方便管理。

const moduleA = {
  state: { ... },
  mutations: { ... },
  actions: { ... },
  getters: { ... }
 }
const moduleB = {
  state: { ... },
  mutations: { ... },
  actions: { ... }
 }

const store = new Vuex.Store({
  modules: {
    a: moduleA,
    b: moduleB
})

vue-cli如何新增自定义指令?

  1. 创建局部指令

    var app = new Vue({
        el: '#app',
        data: {    
        },
        // 创建指令(可以多个)
        directives: {
            // 指令名称
            dir1: {
                inserted(el) {
                    // 指令中第一个参数是当前使用指令的DOM
                    console.log(el);
                    console.log(arguments);
                    // 对DOM进行操作
                    el.style.width = '200px';
                    el.style.height = '200px';
                    el.style.background = '#000';
                }
            }
        }
    })
    
  2. Vue.directive('dir2', {
        inserted(el) {
            console.log(el);
        }
    })
    
  3. 指令的使用

    <div id="app">
        <div v-dir1></div>
        <div v-dir2></div>
    </div>
    

vue如何自定义一个过滤器?

  1. html代码

    <div id="app">
         <input type="text" v-model="msg" />
         {{msg| capitalize }}
    </div>
    
  2. var vm=new Vue({
        el:"#app",
        data:{
            msg:''
        },
        filters: {
          capitalize: function (value) {
            if (!value) return ''
            value = value.toString()
            return value.charAt(0).toUpperCase() + value.slice(1)
          }
        }
    })
    
  3. 全局定义过滤器

    Vue.filter('capitalize', function (value) {
      if (!value) return ''
      value = value.toString()
      return value.charAt(0).toUpperCase() + value.slice(1)
    })
    

对keep-alive 的了解?

keep-alive是 Vue 内置的一个组件,可以使被包含的组件保留状态,或避免重新渲染。
在vue 2.1.0 版本之后,keep-alive新加入了两个属性: include(包含的组件缓存) 与 exclude(排除的组件不缓存,优先级大于include) 。

使用方法

<keep-alive include='include_components' exclude='exclude_components'>
  <component>
    <!-- 该组件是否缓存取决于include和exclude属性 -->
  </component>
</keep-alive>

参数解释

  • include - 字符串或正则表达式,只有名称匹配的组件会被缓存;
  • exclude - 字符串或正则表达式,任何名称匹配的组件都不会被缓存;
  • include 和 exclude 的属性允许组件有条件地缓存。二者都可以用“,”分隔字符串、正则表达式、数组。当使用正则或者是数组时,要记得使用v-bind 。

使用示例

<!-- 逗号分隔字符串,只有组件a与b被缓存。 -->
<keep-alive include="a,b">
  <component></component>
</keep-alive>

<!-- 正则表达式 (需要使用 v-bind,符合匹配规则的都会被缓存) -->
<keep-alive :include="/a|b/">
  <component></component>
</keep-alive>

<!-- Array (需要使用 v-bind,被包含的都会被缓存) -->
<keep-alive :include="['a', 'b']">
  <component></component>
</keep-alive>
  1. css只在当前组件起作用

    在style标签中写入scoped即可 例如:<style scoped></style>

  2. v-if 和 v-show 区别

    v-if按照条件是否渲染,v-show是display的block或none;

  3. $route$router的区别

    $route是“路由信息对象”,包括path,params,hash,query,fullPath,matched,name等路由信息参数。而$router是“路由实例”对象包括了路由的跳转方法,钩子函数等。

  4. vue.js的两个核心是什么?

    数据驱动、组件系统

  5. vue几种常用的指令

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

  6. vue常用的修饰符?

    .prevent: 提交事件不再重载页面;

    .stop: 阻止单击事件冒泡;

    .self: 当事件发生在该元素本身而不是子元素的时候会触发;

    .capture: 事件侦听,事件发生的时候会调用

  7. v-on 可以绑定多个方法吗?

  8. vue中 key 值的作用?

    当 Vue.js 用 v-for 正在更新已渲染过的元素列表时,它默认用“就地复用”策略。如果数据项的顺序被改变,Vue 将不会移动 DOM 元素来匹配数据项的顺序, 而是简单复用此处每个元素,并且确保它在特定索引下显示已被渲染过的每个元素。key的作用主要是为了高效的更新虚拟DOM。

  9. 什么是vue的计算属性?

    在模板中放入太多的逻辑会让模板过重且难以维护,在需要对数据进行复杂处理,且可能多次使用的情况下,尽量采取计算属性的方式。

    ①使得数据处理结构清晰;

    ②依赖于数据,数据更新,处理结果自动更新;

    ③计算属性内部this指向vm实例;

    ④在template调用时,直接写计算属性名即可;

    ⑤常用的是getter方法,获取数据,也可以使用set方法改变数据;

    ⑥相较于methods,不管依赖的数据变不变,methods都会重新计算,但是依赖数据不变的时候computed从缓存中获取,不会重新计算

  10. vue等单页面应用及其优缺点

    优点:Vue 的目标是通过尽可能简单的 API 实现响应的数据绑定和组合的视图组件,核心是一个响应的数据绑定系统。MVVM、数据驱动、组件化、轻量、简洁、高效、快速、模块友好。

    缺点:不支持低版本的浏览器,最低只支持到IE9;不利于SEO的优化(如果要支持SEO,建议通过服务端来进行渲染组件);第一次加载首页耗时相对长一些;不可以使用浏览器的导航按钮需要自行实现前进、后退。

  11. 怎么定义 vue-router 的动态路由? 怎么获取传过来的值

    在 router 目录下的 index.js 文件中,对 path 属性加上 /:id,使用 router 对象的 params.id 获取。

    routes.js:

    export default [
      {
        /**绑定活的路径*/
        name:'showSingleBlog',
        path:'/showSingleBlog/:id',
        component:showSingleBlog
      },{
        name:'updateSingleBlog',
        path:'/updateSingleBlog/:id',
        component:updateSingleBlog
      }
    ]
    

    html:

    <router-link v-bind:to="'/showSingleBlog/'+blog.id"><h2 id="h0" v-rain title="查看详情">{{blog.title | toUpper}}</h2>
    


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK