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等
- 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>
- 子组件向父组件传值
子组件:
<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模式。
- 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.nextTick有什么作用?
处理数据动态变化后,dom还未及时更新的问题。nexttick就可以获取到数据更新后最新的dom变化
网友评论