vue组件化的好处及vue常见面试题

1,组件化开发思想:

* 提高开发效率
* 方便重复使用
* 简化调试步骤
* 提升项目的可维护性
* 便于多人协同开发

2, vue优点

vue是一个构建数据驱动的web界面的渐进式MVVM框架,性能好、简单易用、前后端分离、单页面应用用户体验好
3,谈谈你对MVVM开发模式的理解

MVVM分为Model、View、viewModel三者
* Model:代表数据模型,数据和业务逻辑都在Model层定义
* View: 代表视图模型,负责数据的展示
* viewModel: 负责监听Model中的数据的改变并控制视图的更新,处理用户交互操作
4, v-if和v-show区别

v-show仅仅控制元素的显示方式,将display属性在block和none直接来回切换;v-if会控制这个DOM节点的存在与否,如果需要经常切换某个元素的显示/隐藏的时候,这时候使用v-show更节省性能上的开销
5, vue常见的指令

v-html、v-if、v-show、v-for、v-model、v-once、v-on
6, v-loader是什么

vue文件的一个加载器,将template/js/style转换成js模块
用途: js可以写es6、style样式可以scss、less、template可以加jade等

  1. vue中key的作用

key来给每个节点做一个唯一标识,作用是为了高效的更新虚拟DOM
8,computed和watch区别及使用场景
computed适用于动态计算data里的属性值,必须加return,不能对data里的属性进行赋值,当无变化时会先从缓存里读取。
使用场景:当一个值受多个属性影响的时候

computed: {
    btnText(){
      return this.totalCount !== 0 ? `${this.totalCount}s`: "获取验证码"
    }
  }

watch
watch是监听data里的值的变化,当data中的属性发生改变的时候,watch中的函数就会执行,有两个参数,前者是newVal,后者是oldVal。当监听引用类型数据的变化,需要进行深度监听(用handler + deep的方式进行深度监听。immediate:true 页面首次加载的时候做一次监听。
使用场景:当一条数据的更改影响到多条数据的时候

watch: {
    //a,b,c,d为data里的数据名
    a(val, oldVal) {
        console.log( val, oldVal)
    },
    // 方法名
    b: 'someMethod',
    c: {
      handler(val, oldVal) {},
      deep: true // 该回调会在任何被侦听的对象的 property 改变时被调用,不论其被嵌套多深
    },
    d: {
      handler: 'someMethod',
      immediate: true    // 该回调将会在侦听开始之后被立即调用
    },
}
computed当一个属性受多个属性影响的时候使用computed 最典型的例子: 购物车商品结算的时候
watch当一条数据影响多条数据的时候使用watch,典型的例子: 搜索数据

9,MVVM响应式原理
实现数据绑定的做法大致如下几种:
发布者 - 订阅者模式
数据劫持
数据劫持: vue是采用数据劫持结合发布者-订阅者模式的方式,通过object.defineProperty()来劫持各个属性的setter, getter,在数据变动时发布消息给订阅者,触发相应的监听回调


image.png

1,实现一个指令解析器Compile
待补全 ....
10, Vue的三种常用传值方式父传子、子传父、非父子组件传值
1、父组件向子组件进行传值
父组件

<template>
  <div>
    父组件:
    <input type="text" v-model="name">
    <br>
    <br>
    <!-- 引入子组件 -->
    <child :inputName="name"></child>
  </div>
</template>
<script>
  import child from './child'
  export default {
    components: {
      child
    },
    data () {
      return {
        name: ''
      }
    }
  }
</script>

子组件:

<template>
  <div>
    子组件:
    <span>{{inputName}}</span>
  </div>
</template>
<script>
  export default {
    // 接受父组件的值
    props: {
      inputName: String,
      required: true
    }
  }
</script>
  1. 子组件向父组件传值
    子组件:
<template>
  <div>
    子组件:
    <span>{{childValue}}</span>
    <!-- 定义一个子组件传值的方法 -->
    <input type="button" value="点击触发" @click="childClick">
  </div>
</template>
<script>
  export default {
    data () {
      return {
        childValue: '我是子组件的数据'
      }
    },
    methods: {
      childClick () {
        // childByValue是在父组件on监听的方法
        // 第二个参数this.childValue是需要传的值
        this.$emit('childByValue', this.childValue)
      }
    }
  }
</script>

父组件:

<template>
  <div>
    父组件:
    <span>{{name}}</span>
    <br>
    <br>
    <!-- 引入子组件 定义一个on的方法监听子组件的状态-->
    <child v-on:childByValue="childByValue"></child>
  </div>
</template>
<script>
  import child from './child'
  export default {
    components: {
      child
    },
    data () {
      return {
        name: ''
      }
    },
    methods: {
      childByValue: function (childValue) {
        // childValue就是子组件传过来的值
        this.name = childValue
      }
    }
  }
</script>

3,非父子组件进行传值

非父子组件之间传值,需要定义个公共的公共实例文件bus.js,作为中间仓库来传值,不然路由组件之间达不到传值的效果

eventBus 就是创建一个事件中心,相当于中转站,可以用它来传递事件和接受事件

公共bus.js:

//bus.js
import Vue from 'vue'
export default new Vue()

组件A:

<template>
  <div>
    A组件:
    <span>{{elementValue}}</span>
    <input type="button" value="点击触发" @click="elementByValue">
  </div>
</template>
<script>
  // 引入公共的bug,来做为中间传达的工具
  import Bus from './bus.js'
  export default {
    data () {
      return {
        elementValue: 4
      }
    },
    methods: {
      elementByValue: function () {
        Bus.$emit('val', this.elementValue)
      }
    }
  }
</script>

组件B:

<template>
  <div>
    B组件:
    <input type="button" value="点击触发" @click="getData">
    <span>{{name}}</span>
  </div>
</template>
<script>
  import Bus from './bus.js'
  export default {
    data () {
      return {
        name: 0
      }
    },
    mounted: function () {
      var vm = this
      // 用$on事件来接收参数
      Bus.$on('val', (data) => {
        console.log(data)
        vm.name = data
      })
    },
    methods: {
      getData: function () {
        this.name++
      }
    }
  }
</script>

11, vue中vue-router hash和history模式区别
为了构建SPA,vue引入了前端路由系统vue-router。
vue-route有两种模式:history模式和hash模式。

  1. hash模式(vue-router默认hash模式)
    hash模式背后的原理是onhashchange事件。
window.onhashchange=function(){
 let hash=location.hash.slice(1);
 document.body.style.color=hash;
}

localtion是js里管理地址栏的内置对象,是window对象的一部分,可通过window.localtion访问,在w3cshool里的详细介绍)
由于hash发生变化的url都会被浏览器记录下来,使得浏览器的前进后退都可以使用了,尽管浏览器没有亲求服务器,但是页面状态和url关联起来。后来人们称其为前端路由,成为单页应用标配。

比如http://www.abc.com/#/index,hash值为#/index。hash模式的特点在于hash出现在url中,但是不会被包括在HTTP请求中,对后端没有影响,不会重新加载页面。
2.history模式
history模式利用了HTML5 History Interface中新增的pushState()和replaceState()方法。MDN相关介绍(需要特定浏览器支持)。这两个方法应用于浏览器的历史记录栈,提供了对历史记录进行修改的功能。只是当他们进行修改时,虽然修改了url,但浏览器不会立即向后端发送请求。
当使用history模式时,url就像正常的url,例如http://abc.com/user/id相比hash模式更加好看。特别注意,history模式需要后台配置支持。如果后台没有正确配置,访问时会返回404。
通过history api,我们丢弃了丑陋的#,但是有一个缺点,当刷新时,如果服务器中没有相应的相应或者资源,会分分钟刷出一个404来(刷新需要请求服务器)。所以history模式不怕前进,不怕后退,就怕刷新。
3.hash模式和history模式区别

  • pushState()设置新的url可以是和当前url同源的任意url;hash只可修改#后面的部分,只能设置当前url同文档的url。
  • pushState()设置的新url可与当前url一致,这样也会把记录添加到栈中;hash必须设置与当前url不同的url的,才会触发动作将记录添加到栈中。
  • pushState()通过stateObject参数可以添加任意类型的数据到记录中;hash只可添加短字符串。
  • pushState()可额外设置title属性供后续使用。
    不过,hash模式也有比history模式优势的地方:
  • hash模式下,仅hash符号之前的url会被包含在请求中,后端如果没有做到对路由的全覆盖,也不会返回404错误。
  • history模式下,前端的url必须和实际向后端发起请求的url一致,如http://abc.com/user/id,后端如果没有对user/id的路由处理,将返回404错误。
    12, vue路由的钩子函数
    首页可以控制导航跳转,beforeEach,afterEach等,一般用于页面title的修改。一些需要登录才能调整页面的重定向功能。
    beforeEach主要有3个参数to,from,next:
    to: route即将进入的目标路由对象
    from: route当前导航正要离开的路由
    next:function一定要调用该方法resolve这个钩子。执行效果依赖next方法的调用参数。可以控制网页的跳转。
    13,vue.js的两个核心是什么?
    数据驱动、组件系统
    14,vue-router是怎么传递参数的
    (1)通过在router.js文件中配置path的地方动态传递参数 eg: path: ‘/detail/:id’
    (2).在router-link标签中传递参数

<router-link :to={
params: {
x: 1
}
} />
获取:this.$route.params.id
15, v-if和v-for一起使用的弊端以及解决办法
v-for的优先级比v-if高,导致每循环一次就会去v-if一次,而v-if是通过创建和销毁dom元素来控制元素的显示与隐藏,所以就会不停的去创建和销毁元素,造成页面卡顿,性能下降。
解决办法:
1.在v-for的外层包裹一个标签来使用v-if
2将需要的判断在computed里处理,然后在放到v-for里
16, vue中父组件如何获取子组件的属性和方法
在子组件上定义ref属性来获取子组件的属性和方法

// 这里是父组件
<templete>
    <child ref="child"/>
</templete>
<script>
method: {
    getChild () {
        this.$refs.child.属性名(方法名)
    }
}
</script>

16, watch和computed的区别
watch:监听数据变化,并执行一个回调函数
computed:对已有的数据进行加工,具有缓存功能,只有数据发生改时,才会重新计算
17, vue中父组件能监听到子组件的生命周期吗
能,通过@hook:进行监听代码如下:

// 这里是父组件
<template>
    <child
    @hook:mounted="getChildMounted"
    />
</template>
<script>
method: {
    getChildMounted () {
        // 这里可以获取到子组件mounted的信息
    }
}
</script>

17, vue中的事件修饰符主要有哪些?分别是什么作用?
.stop: 阻止事件冒泡
.native: 绑定原生事件
.once: 事件只执行一次
.self:将事件绑定在自身身上,相当于阻止事件冒泡
.prevent: 阻止默认事件
.caption: 用于事件捕获
18, watch如何实现深度监听

watch: {
    obj: {
        handler: function(val) {
        },
        deep: true // 深度监听
    }
}

19, vue中如何解决页面不重新渲染问题?
(1)修改对象属性后,页面未重新渲染:

this.$set(对象名称, '属性名', '属性值')

(2)使用this.forceUpdate()方法可重新渲染页面 20, 什么是路由懒加载 通过异步的方式来加载对应的路由组件,提高页面的加载速度 21,nextTick有什么作用?
处理数据动态变化后,dom还未及时更新的问题。nexttick就可以获取到数据更新后最新的dom变化

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,524评论 5 460
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,869评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,813评论 0 320
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,210评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,085评论 4 355
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,117评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,533评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,219评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,487评论 1 290
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,582评论 2 309
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,362评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,218评论 3 312
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,589评论 3 299
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,899评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,176评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,503评论 2 341
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,707评论 2 335