dmyang

dmyang 查看完整档案

广州编辑  |  填写毕业院校  |  填写所在公司/组织 github.com/chemdemo 编辑
编辑

一只养喵的程序员。

个人动态

dmyang 赞了文章 · 2019-12-17

98道经典Vue面试题总结(长期更新)

写在前面


参考答案在看云平台发布,如果大家想阅读参考答案,可直接购买。

一次购买,文档所有部分(vue、http、js等)均可以观看,无时间限制,文档长期更新!

有什么意见与建议欢迎您及时联系作者或留言回复!
参考资料:前端知识库

阅读文档

Vue开发交流微信群:(二维码定期更新,长期有效!或添加群主微信hanxuming888进群)

图片描述

本文档基于vue-cli技术栈总结了

  • vue-cli工程
  • vue.js核心知识
  • vue-router路由
  • vuex状态管理器
  • axios等http请求
  • 移动端适配
  • Tab切换等常用功能
  • vue与原生app混合交互
  • vue生产环境部署
  • vue各项技术源码解析
  • MVVM设计模式
  • vue-cli工程深入拓展

等12个关于vue-cli开发的方面。

不仅可以帮你一次性详细阅读所有关于vue的面试题、更可以帮你拓展关于vue开发的视野。

关于vue的试题,看这一篇文档就够了!


vue-cli工程


1、构建的 vue-cli 工程都到了哪些技术,它们的作用分别是什么?

2、vue-cli 工程常用的 npm 命令有哪些?

3、请说出vue-cli工程中每个文件夹和文件的用处

4、config文件夹 下 index.js 的对于工程 开发环境 和 生产环境 的配置

5、请你详细介绍一些 package.json 里面的配置

参考答案:https://www.kancloud.cn/hanxu...


vue核心知识点


1、对于Vue是一套渐进式框架的理解

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

3、请问 v-ifv-show 有什么区别

4、vue常用的修饰符

5、v-on可以监听多个方法吗?

6、vue中 key 值的作用

7、vue-cli工程升级vue版本

8、vue事件中如何使用event对象?

9、$nextTick的使用

10、Vue 组件中 data 为什么必须是函数

11、v-for 与 v-if 的优先级

12、vue中子组件调用父组件的方法

13、vue中 keep-alive 组件的作用

14、vue中如何编写可复用的组件?

15、什么是vue生命周期生命周期钩子函数?

16、vue生命周期钩子函数有哪些?

17、vue如何监听键盘事件中的按键?

18、vue更新数组时触发视图更新的方法

19、vue中对象更改检测的注意事项

20、解决非工程化项目初始化页面闪动问题

21、v-for产生的列表,实现active的切换

22、v-model语法糖的组件中的使用

23、十个常用的自定义过滤器

24、vue等单页面应用及其优缺点

25、什么是vue的计算属性?

26、vue-cli提供的几种脚手架模板

27、vue父组件如何向子组件中传递数据?

28、vue-cli开发环境使用全局常量

29、vue-cli生产环境使用全局常量

30、vue弹窗后如何禁止滚动条滚动?

31、计算属性的缓存和方法调用的区别

32、vue-cli中自定义指令的使用

参考答案:https://www.kancloud.cn/hanxu...


vue-router


1、vue-router如何响应 路由参数 的变化?

2、完整的 vue-router 导航解析流程

3、vue-router有哪几种导航钩子( 导航守卫 )?

4、vue-router的几种实例方法以及参数传递

5、vue-router的动态路由匹配以及使用

6、vue-router如何定义嵌套路由?

7、<router-link></router-link>组件及其属性

8、vue-router实现路由懒加载( 动态加载路由 )

9、vue-router路由的两种模式

10、history路由模式与后台的配合

参考答案:https://www.kancloud.cn/hanxu...


vuex


1、什么是vuex?

2、使用vuex的核心概念

3、vuex在vue-cli中的应用

4、组件中使用 vuex 的值和修改值的地方?

5、在vuex中使用异步修改

6、pc端页面刷新时实现vuex缓存

参考答案:https://www.kancloud.cn/hanxu...


http请求


1、Promise对象是什么?

2、axios、fetch与ajax有什么区别?

3、什么是JS的同源策略和跨域问题?

4、如何解决跨域问题?

5、vue-cli中如何使用JSON数据模拟

6、vue-cli中http请求的统一管理。

7、axios有什么特点?

参考答案:https://www.kancloud.cn/hanxu...


UI样式


1、.vue组件的scoped属性的作用

2、如何让CSS只在当前组件中起作用?

3、vue-cli中常用的UI组件库

4、如何适配移动端?【 经典 】

5、移动端常用媒体查询的使用

6、垂直居中对齐

7、vue-cli中如何使用背景图片?

8、使用表单禁用时移动端样式问题

9、多种类型文本超出隐藏问题

参考答案:https://www.kancloud.cn/hanxu...


常用功能


1、vue中如何实现tab切换功能?

2、vue中如何利用 keep-alive 标签实现某个组件缓存功能?

3、vue中实现切换页面时为左滑出效果

4、vue中父子组件如何相互调用方法?

5、vue中央事件总线的使用

参考答案:https://www.kancloud.cn/hanxu...


混合开发


1、vue如何调用 原生app 提供的方法?

2、原生app 调用 vue 提供的方法,并将值传递到 .vue 组件中

参考答案:https://www.kancloud.cn/hanxu...


生产环境


1、vue打包命令是什么?

2、vue打包后会生成哪些文件?

3、如何配置 vue 打包生成文件的路径?

4、vue如何优化首屏加载速度?

参考答案:https://www.kancloud.cn/hanxu...


MVVM设计模式


1、MVC、MVP与MVVM模式

2、MVC、MVP与MVVM的区别

3、常见的实现MVVM几种方式

4、Object.defineProperty()方法

5、实现一个自己的MVVM(原理剖析)

6、 ES6中类和定义

7、JS中的文档碎片

8、解构赋值

9、Array.from与Array.reduce

10、递归的使用

11、Obj.keys()与Obj.defineProperty

12、发布-订阅模式

13、实现MVVM的思路分析

参考答案:https://www.kancloud.cn/hanxu...


源码剖析


1、vue内部与运行机制:

  • Vue.js 全局运行机制
  • 响应式系统的基本原理
  • 什么是 Virtual DOM?
  • 如何编译template 模板?
  • diff算法
  • 批量异步更新策略及 nextTick 原理?
  • proxy代理?

2、vuex工作原理详解

  • Vue.mixin
  • Vue.use

参考答案:https://www.kancloud.cn/hanxu...


深入拓展


1、vue开发命令 npm run dev 输入后的执行过程

2、vue的服务器端渲染

3、从零写一个npm安装包

4、vue-cli中常用到的加载器

5、webpack的特点

参考答案:https://www.kancloud.cn/hanxu...


查看原文

赞 653 收藏 502 评论 203

dmyang 赞了文章 · 2019-12-17

2019前端面试题汇总(主要为Vue)

毕业之后就在一直合肥小公司工作,没有老司机、没有技术氛围,在技术的道路上我只能独自摸索。老板也只会画饼充饥,前途一片迷茫看不到任何希望。于是乎,我果断辞职,在新年开工之际来到杭州,这里的互联网公司应该是合肥的几十倍吧。。。。
刚来3天,面试了几家公司,有些规模比较小,有些是创业公司,也有些已经发展的不错了;今天把最近的面试题目做个汇总,也给自己复个盘,由于我的技术栈主要为Vue,所以大部分题目都是Vue开发相关的。

1. 谈谈你对MVVM开发模式的理解

MVVM分为Model、View、ViewModel三者。
Model 代表数据模型,数据和业务逻辑都在Model层中定义;
View 代表UI视图,负责数据的展示;
ViewModel 负责监听 Model 中数据的改变并且控制视图的更新,处理用户交互操作;
ModelView 并无直接关联,而是通过 ViewModel 来进行联系的,ModelViewModel 之间有着双向数据绑定的联系。因此当 Model 中的数据改变时会触发 View 层的刷新,View 中由于用户交互操作而改变的数据也会在 Model 中同步。
这种模式实现了 ModelView 的数据自动同步,因此开发者只需要专注对数据的维护操作即可,而不需要自己操作 dom

2. Vue 有哪些指令?

v-html、v-show、v-if、v-for等等

3. v-if 和 v-show 有什么区别?

v-show 仅仅控制元素的显示方式,将 display 属性在 block 和 none 来回切换;而v-if会控制这个 DOM 节点的存在与否。当我们需要经常切换某个元素的显示/隐藏时,使用v-show会更加节省性能上的开销;当只需要一次显示或隐藏时,使用v-if更加合理。

4. 简述Vue的响应式原理

当一个Vue实例创建时,vue会遍历data选项的属性,用 Object.defineProperty 将它们转为 getter/setter并且在内部追踪相关依赖,在属性被访问和修改时通知变化。
每个组件实例都有相应的 watcher 程序实例,它会在组件渲染的过程中把属性记录为依赖,之后当依赖项的 setter 被调用时,会通知 watcher 重新计算,从而致使它关联的组件得以更新。

5. Vue中如何在组件内部实现一个双向数据绑定?

假设有一个输入框组件,用户输入时,同步父组件页面中的数据
具体思路:父组件通过 props 传值给子组件,子组件通过 $emit 来通知父组件修改相应的props值,具体实现如下:

import Vue from 'vue'

const component = {
  props: ['value'],
  template: `
    <div>
      <input type="text" @input="handleInput" :value="value">
    </div>
  `,
  data () {
    return {
    }
  },
  methods: {
    handleInput (e) {
      this.$emit('input', e.target.value)
    }
  }
}

new Vue({
  components: {
    CompOne: component
  },
  el: '#root',
  template: `
    <div>
      <comp-one :value1="value" @input="value = arguments[0]"></comp-one>
    </div>
  `,
  data () {
    return {
      value: '123'
    }
  }
})

可以看到,当输入数据时,父子组件中的数据是同步改变的:
Image 1.png

Image 2.png

我们在父组件中做了两件事,一是给子组件传入props,二是监听input事件并同步自己的value属性。那么这两步操作能否再精简一下呢?答案是可以的,你只需要修改父组件:

template: `
    <div>
      <!--<comp-one :value1="value" @input="value = arguments[0]"></comp-one>-->
      <comp-one v-model="value"></comp-one>
    </div>
  `

v-model 实际上会帮我们完成上面的两步操作。

6. Vue中如何监控某个属性值的变化?

比如现在需要监控data中,obj.a 的变化。Vue中监控对象属性的变化你可以这样:

watch: {
      obj: {
      handler (newValue, oldValue) {
        console.log('obj changed')
      },
      deep: true
    }
  }

deep属性表示深层遍历,但是这么写会监控obj的所有属性变化,并不是我们想要的效果,所以做点修改:

watch: {
   'obj.a': {
      handler (newName, oldName) {
        console.log('obj.a changed')
      }
   }
  }

还有一种方法,可以通过computed 来实现,只需要:

computed: {
    a1 () {
      return this.obj.a
    }
}

利用计算属性的特性来实现,当依赖改变时,便会重新计算一个新值。

7. Vue中给data中的对象属性添加一个新的属性时会发生什么,如何解决?

示例:

<template>
  <div>
    <ul>
      <li v-for="value in obj" :key="value">
        {{value}}
      </li>
    </ul>
    <button @click="addObjB">添加obj.b</button>
  </div>
</template>
<script>
export default {
  data () {
    return {
      obj: {
        a: 'obj.a'
      }
    }
  },
  methods: {
    addObjB () {
      this.obj.b = 'obj.b'
      console.log(this.obj)
    }
  }
}
</script>
<style></style>

点击button会发现,obj.b 已经成功添加,但是视图并未刷新:
Image 3.png

Image 4.png

原因在于在Vue实例创建时,obj.b并未声明,因此就没有被Vue转换为响应式的属性,自然就不会触发视图的更新,这时就需要使用Vue的全局api $set():

addObjB () {
      // this.obj.b = 'obj.b'
      this.$set(this.obj, 'b', 'obj.b')
      console.log(this.obj)
    }

$set()方法相当于手动的去把obj.b处理成一个响应式的属性,此时视图也会跟着改变了:
Image 5.png

8. delete和Vue.delete删除数组的区别

delete只是被删除的元素变成了 empty/undefined 其他的元素的键值还是不变。
Vue.delete直接删除了数组 改变了数组的键值。

    var a=[1,2,3,4]
    var b=[1,2,3,4]
    delete a[1]
    console.log(a)
    this.$delete(b,1)
    console.log(b)

Image 6.png

Image 7.png

9.如何优化SPA应用的首屏加载速度慢的问题?

  • 将公用的JS库通过script标签外部引入,减小app.bundel的大小,让浏览器并行下载资源文件,提高下载速度;
  • 在配置 路由时,页面和组件使用懒加载的方式引入,进一步缩小 app.bundel 的体积,在调用某个组件时再加载对应的js文件;
  • 加一个首屏 loading 图,提升用户体验;

10. 前端如何优化网站性能?

  1. 减少 HTTP 请求数量

在浏览器与服务器进行通信时,主要是通过 HTTP 进行通信。浏览器与服务器需要经过三次握手,每次握手需要花费大量时间。而且不同浏览器对资源文件并发请求数量有限(不同浏览器允许并发数),一旦 HTTP 请求数量达到一定数量,资源请求就存在等待状态,这是很致命的,因此减少 HTTP 的请求数量可以很大程度上对网站性能进行优化。

    • CSS Sprites:国内俗称 CSS 精灵,这是将多张图片合并成一张图片达到减少 HTTP 请求的一种解决方案,可以通过 CSS background 属性来访问图片内容。这种方案同时还可以减少图片总字节数。
    • 合并 CSS 和 JS 文件:现在前端有很多工程化打包工具,如:grunt、gulp、webpack等。为了减少 HTTP 请求数量,可以通过这些工具再发布前将多个 CSS 或者 多个 JS 合并成一个文件。
    • 采用 lazyLoad:俗称懒加载,可以控制网页上的内容在一开始无需加载,不需要发请求,等到用户操作真正需要的时候立即加载出内容。这样就控制了网页资源一次性请求数量。
    1. 控制资源文件加载优先级

    浏览器在加载 HTML 内容时,是将 HTML 内容从上至下依次解析,解析到 link 或者 script 标签就会加载 href 或者 src 对应链接内容,为了第一时间展示页面给用户,就需要将 CSS 提前加载,不要受 JS 加载影响。
    一般情况下都是 CSS 在头部,JS 在底部。

    1. 利用浏览器缓存
      浏览器缓存是将网络资源存储在本地,等待下次请求该资源时,如果资源已经存在就不需要到服务器重新请求该资源,直接在本地读取该资源。
    2. 减少重排(Reflow)
      基本原理:重排是 DOM 的变化影响到了元素的几何属性(宽和高),浏览器会重新计算元素的几何属性,会使渲染树中受到影响的部分失效,浏览器会验证 DOM 树上的所有其它结点的 visibility 属性,这也是 Reflow 低效的原因。如果 Reflow 的过于频繁,CPU 使用率就会急剧上升。

    减少 Reflow,如果需要在 DOM 操作时添加样式,尽量使用 增加 class 属性,而不是通过 style 操作样式。

    1. 减少 DOM 操作
    2. 图标使用 IconFont 替换

    11. 网页从输入网址到渲染完成经历了哪些过程?

    大致可以分为如下7步:

    1. 输入网址;
    2. 发送到DNS服务器,并获取域名对应的web服务器对应的ip地址;
    3. 与web服务器建立TCP连接;
    4. 浏览器向web服务器发送http请求;
    5. web服务器响应请求,并返回指定url的数据(或错误信息,或重定向的新的url地址);
    6. 浏览器下载web服务器返回的数据及解析html源文件;
    7. 生成DOM树,解析css和js,渲染页面,直至显示完成;

    12. jQuery获取的dom对象和原生的dom对象有何区别?

    js原生获取的dom是一个对象,jQuery对象就是一个数组对象,其实就是选择出来的元素的数组集合,所以说他们两者是不同的对象类型不等价。

    • 原生DOM对象转jQuery对象:
    var box = document.getElementById('box');
    var $box = $(box);
    • jQuery对象转原生DOM对象:
    var $box = $('#box');
    var box = $box[0];

    13. jQuery如何扩展自定义方法

    (jQuery.fn.myMethod=function () {
           alert('myMethod');
    })
    // 或者:
    (function ($) {
            $.fn.extend({
                 myMethod : function () {
                      alert('myMethod');
                 }
            })
    })(jQuery)

    使用:

    $("#div").myMethod();

    目前来看公司面试的问题还是比较基础的,但是对于某些只追求会用并不研究其原理的同学来说可能就没那么容易了。所以大家不仅要追求学习的广度,更要追求深度。
    OK,希望自己能早日拿到心仪的offer.

    参考:
    浅谈网站性能之前端性能优化

    查看原文

    赞 533 收藏 393 评论 47

    dmyang 关注了问题 · 2016-09-23

    关于webpack css中url的问题

    我在某个css中写了一个背景图片,用到了url()引用相对路径的图片资源。
    打包的时候我把图片转到别的文件夹下
    clipboard.png
    但是打包后的css中的url不会自动变化,所以运行的时候会提示找不到图片。
    请问这个问题如何解决?

    关注 9 回答 4

    dmyang 回答了问题 · 2016-09-23

    关于webpack css中url的问题

    css loader似乎确实不会处理这种情况,可以通过publicPath来解决,打包后的路径用绝对路径。

    关注 9 回答 4

    dmyang 发布了文章 · 2016-09-03

    【译】React 组件的生命周期

    原文:https://medium.com/react-ecosystem/react-components-lifecycle-ce09239010df#.j7h6w8ccc

    译者序:React组件生命周期有很多文章介绍了,这篇作者列出了很多开发中可能不会注意的细节,比如哪些阶段执行setState是否会导致render等,对React组件性能优化有一定的帮助,故译之,不当之处敬请指正!

    github issue: https://github.com/chemdemo/c...

    一段探索React自建内部构造的旅程

    在先前的文章里我们涵盖了React基本原理如何构建更加复杂的交互组件。此篇文章我们将会继续探索React组件的特性,特别是生命周期。

    稍微思考一下React组件所做的事,首先想到的是一点是:React描述了如何去渲染(DOM)。我们已经知道React使用render()方法来达到这个目的。然而仅有render()方法可能不一定都能满足我们的需求。如果在组件rendered之前或之后我们需要做些额外的事情该怎么做呢?我们需要做些什么以避免重复渲染(re-render)呢?

    看起来我们需要对组件(运行)的各个阶段进行控制,组件运行所有涉及的各个阶段叫做组件的生命周期,并且每一个React组件都会经历这些阶段。React提供了一些方法并在组件处于相应的阶段时通知我们。这些方法叫做React组件的生命周期方法且会根据特定并可预测的顺序被调用。

    基本上所有的React组件的生命周期方法都可以被分割成四个阶段:初始化挂载阶段(mounting)更新阶段卸载阶段(unmounting)。让我们来近距离分别研究下各个阶段。

    初始化阶段

    初始化阶段就是我们分别通过getDefaultProps()getInitialState()方法定义this.props默认值和this.state初始值的阶段。

    getDefaultProps()方法被调用一次并缓存起来——在多个类实例之间共享。在组件的任何实例被创建之前,我们(的代码逻辑)不能依赖这里的this.props。这个方法返回一个对象并且属性如果没有通过父组件传入的话相应的属性会挂载到this.props对象上。

    getInitialState()方法也只会被调用一次,(调用时机)刚好是mounting阶段开始之前。返回值将会被当成this.state的初始值,且必须是一个对象。

    现在我们来证明上面的猜想,实现一个显示的值可以被增加和减少的组件,基本上就是一个拥有“+”和“-”按钮的计数器。

    var Counter = React.createClass({
        getDefaultProps: function() {
            console.log('getDefaultProps');
            return {
                title: 'Basic counter!!!'
            }
        },
    
        getInitialState: function() {
            console.log('getInitialState');
            return {
                count: 0
            }
        },
    
        render: function() {
            console.log('render');
            return (
                <div>
                    <h1>{this.props.title}</h1>
                    <div>{this.state.count}</div>
                    <input type='button' value='+' onClick={this.handleIncrement} />
                    <input type='button' value='-' onClick={this.handleDecrement} />
                </div>
            );
        },
    
        handleIncrement: function() {
            var newCount = this.state.count + 1;
            this.setState({count: newCount});
        },
    
        handleDecrement: function() {
            var newCount = this.state.count - 1;
            this.setState({count: newCount});
        },
    
        propTypes: {
            title: React.PropTypes.string
        }
    });
    
    ReactDOM.render(
        React.createElement(Counter),
        document.getElementById('app-container')
    );

    我们通过getDefaultProps()方法配置一个“title”属性,如果没有传入则提供一个默认值。然后通过getInitialState()为组件设置一个初始state值“{count: 0}”。如果运行这段代码你将会看到控制台输出如下结果:

    现在我们想要让Counter组件可以设置this.state.count初始值和增加/减少的步长值,但依然提供一个默认值:

    var Component = React.createClass({
        getDefaultProps: function() {
            console.log('getDefaultProps');
            return {
                title: "Basic counter!!!",
                step: 1
            }
        },
    
        getInitialState: function() {
            console.log('getInitialState');
            return {
                count: (this.props.initialCount || 0)
            };
        },
    
        render: function() {
            console.log('render');
            var step = this.props.step;
    
            return (
                <div>
                    <h1>{this.props.title}</h1>
                    <div>{this.state.count}</div>
                    <input type='button' value='+' onClick={this.updateCounter.bind(this, step)} />
                    <input type='button' value='-' onClick={this.updateCounter.bind(this, -step)} />
                </div>
            );
        },
    
        updateCounter: function(value) {
            var newCount = this.state.count + value;
            this.setState({count: newCount});
        },
    
        propTypes: {
            title: React.PropTypes.string,
            initialCount: React.PropTypes.number,
            step: React.PropTypes.number
        }
    });
    
    ReactDOM.render(
        React.createElement(Component, {initialCount: 5, step: 2}),
        document.getElementById('app-container')
    );

    这里通过Function.prototype.bind使用偏函数应用(Partial Application)来达到复用代码的目的。

    现在我们拥有了一个可定制化的组件。

    增长(Mounting)阶段

    Mounting阶段发生在组件即将被插入到DOM之前。这个阶段有两个方法可以用:componentWillMount()componentDidMount()

    componentWillMount()方法是这个阶段最先调用的,它只在刚好初始渲染(initial rendering)发生之前被调用一次,也就是React在DOM插入组件之前。需要注意的是在此处调用this.setState()方法将不会触发重复渲染(re-render)。如果添加下面的代码到计数器组件我们将会看到此方法在getInitialState()之后且render()之前被调用。

    getInitialState: function() {...},
    componentWillMount: function() {
        console.log('componentWillMount');
    },

    componentDidMount()是这个阶段第二个被调用的方法,刚好发生在React插入组件到DOM之后,且也只被调用一次。现在可以更新DOM元素了,这意味着这个方法是初始化其他需要访问DOM或操作数据的第三方库的最佳时机。

    假设我们想要通过API拉取数据来初始化组件。我们应该直接在计数器组件的componentDidMount()方法拉取数据,但是这让组件看起来有太多逻辑了,更可取的方案是使用容器组件来做:

    var Container = React.createClass({
        getInitialState: function() {
            return {
                data: null,
                fetching: false,
                error: null
            };
        },
    
        render: function() {
            if (this.props.fetching) {
                return <div>Loading...</div>;
            }
    
            if (this.props.error) {
                return (
                    <div className='error'>
                        {this.state.error.message}
                    </div>
                );
            }
    
            return <Counter {...data} />
        },
    
        componentDidMount: function() {
            this.setState({fetching: true});
    
            Axios.get(this.props.url).then(function(res) {
                this.setState({data: res.data, fetching: false});
            }).catch(function(res) {
                this.setState({error: res.data, fetching: false});
            });
        }
    });

    Axios是一个基于priomise的跨浏览器和Node.js的HTTP客户端。

     更新阶段

    当组件的属性或者状态更新时也需要一些方法来供我们执行代码,这些方法也是组件更新阶段的一部分且按照以下的顺序被调用:

    1、当从父组件接收到新的属性时:

    props updated

    2、当通过this.setState()改变状态时:

    state updated

    此阶段React组件已经被插入DOM了,因此这些方法将不会在首次render时被调用。

    最先被调用的方法是componentWillReceiveProps(),当组件接收到新属性时被调用。我们可以利用此方法为React组件提供一个在render之前修改state的机会。在此方法内调用this.setState()将不会导致重复render,然后可以通过this.props访问旧的属性。例如计数器组件,如果我们想要在任何时候父组件传入“initialCount”时更新状态,可以这样做:

    ...
    componentWillReceiveProps: function(newProps) {
        this.setState({count: newProps.initialCount});
    },
    ...

    shouldComponentUpdate()方法允许我们自行决定下一个state更新时是否触发重复render。此方法返回一个布尔值,且默认是true。但是我们也可以返回false,这样下面的(生命周期)方法将不会被调用:

    • componentWillUpdate()

    • render()

    • componentDidUpdate()

    当有性能瓶颈时也可以使用shouldComponentUpdate()方法(来优化)。尤其是数百个组件一起时重新render的代价将会十分昂贵。为了证明这个猜想我们来看一个例子:

    var TextComponent = React.createClass({
        shouldComponentUpdate: function(nextProps, nextState) {
            if (this.props.text === nextProps.text) return false;
            return true;
        },
    
        render: function() {
            return <textarea value={this.props.text} />;
        }
    });

    此例中无论何时父组件传入一个“text”属性到TextComponent并且text属性等于当前的“text”属性时,组件将会不会重复render。

    当接收到新的属性或者state时在render之前会立刻调用componentWillUpdate()方法。可以利用此时机来为更新做一些准备工作,虽然这个阶段不能调用this.setState()方法:

    ...
    componentWillUpdate: function(nextProps, nextState) {
        console.log('componentWillUpdate', nextProps, nextState);
    },
    ...

    componentDidUpdate()方法在React更新DOM之后立刻被调用。可以在此方法里操作被更新过的DOM或者执行一些后置动作(action)。此方法有两个参数:

    1. prevProps:旧的属性

    2. prevState:旧的state

    这个方法的一个常见使用场景是当我们使用需要操作更新后的DOM才能工作的第三方库——如jQuery插件的时候。在componentDidMount()方法内初始化第三方库,但是在属性或state更新触发DOM更新之后也需要同步更新第三方库来保持接口一致,这些必须在componentDidUpdate()方法内来完成。为了验证这一点,让我们看看如何开发一个Select2库包裹(wrapper)React组件:

    var Select2 = React.createClass({
        componentDidMount: function() {
            $(this._ref).select2({data: this.props.items});
        },
    
        render: function() {
            return (
                <select
                    ref={
                        function(input) {
                            this._ref = input;
                        }.bind(this)
                    }>
                </select>
            );
        },
    
        componentDidUpdate: function() {
            $(this._ref).select2('destroy');
            $(this._ref).select2({data: this.props.items});
        }
    });

    卸载阶段(unmounting)

    此阶段React只提供了一个方法:

    • componentWillUnmount()

    它将在组件从DOM卸载之前被调用。可以在内部执行任何可能需要的清理工作,如无效的计数器或者清理一些在componentDidMount()/componentDidUpdate()内创建的DOM。比如在Select2组件里边我们可以这样子:

    ...
    componetWillUnmount: function(){
       $(this._ref).select2('destroy');
    },
    ...

    概述

    React为我们提供了一种在创建组件时申明一些将会在组件生命周期的特定时机被自动调用的方法的可能。现在我们很清晰的理解了每一个组件生命周期方法所扮演的角色以及他们被调用的顺序。这使我们有机会在组件创建和销毁时执行一些操作。也允许我们在当属性和状态变化时做出相应的反应从而更容易的整合第三方库和追踪性能问题。

    希望您觉得此文对您有用,如果是这样,请推荐之!!!

    查看原文

    赞 8 收藏 39 评论 1

    dmyang 回答了问题 · 2016-08-17

    解决使用webpack搭建的react应用 为什么读取json文件的时候 不加json!就读取不了 加了json!又会出现如图的错误

    报错已经告诉你了 json格式不对?

    关注 4 回答 4

    dmyang 赞了问题 · 2016-07-18

    求指导 jQuery 文字跑马灯效果

    需要做一个文字跑马灯效果,而且需要不间断,循环。也就是一段文字。那个非主流标签<marquee>暂时不考虑,兼容性问题。想采用图片轮播效果,把子节点clone一个,造成无缝隙轮播,但是文字不像图片,定时切换,我需要滚动。脑袋进程阻塞,没有思路。求大家知道一二。

    关注 3 回答 3

    dmyang 赞了问题 · 2016-07-18

    求指导 jQuery 文字跑马灯效果

    需要做一个文字跑马灯效果,而且需要不间断,循环。也就是一段文字。那个非主流标签<marquee>暂时不考虑,兼容性问题。想采用图片轮播效果,把子节点clone一个,造成无缝隙轮播,但是文字不像图片,定时切换,我需要滚动。脑袋进程阻塞,没有思路。求大家知道一二。

    关注 3 回答 3

    认证与成就

    • 获得 265 次点赞
    • 获得 3 枚徽章 获得 0 枚金徽章, 获得 0 枚银徽章, 获得 3 枚铜徽章

    擅长技能
    编辑

    (゚∀゚ )
    暂时没有

    开源项目 & 著作
    编辑

    (゚∀゚ )
    暂时没有

    注册于 2013-11-27
    个人主页被 2.4k 人浏览