史上最强Vue,面试、项目全靠它
-
- vue框架篇
- vue中的指令和它的用法
-
- 为什么vue组件中data必须是一个函数?
- vue中v-if和v-show有什么区别?
- computed和watch的区别
- vue-loader是什么?使用它的用途有哪些?
- $nextTick是什么?
- v-for key的作用
- Vue的双向数据绑定?
- 组件传值
- prop 验证,和默认值
- 请说下封装 vue 组件的过程
- Vue.js的template编译
- scss是什么?在vue.cli中的安装使用步骤是?有哪几大特性?
- vue如何监听对象或者数组某个属性的变化
- 常用的事件修饰符
- vue如何获取dom
- v-on可以监听多个方法吗?
- assets和static的区别
- slot插槽
- 全局过滤器和局部过滤器的使用
- vue初始化页面闪动问题
- vue改变数据DOM不更新的解决办法
- vue插件篇
- 常用webpack配置
vue框架篇
文章目录
-
- vue框架篇
- vue中的指令和它的用法
-
- 为什么vue组件中data必须是一个函数?
- vue中v-if和v-show有什么区别?
- computed和watch的区别
- vue-loader是什么?使用它的用途有哪些?
- $nextTick是什么?
- v-for key的作用
- Vue的双向数据绑定?
- 组件传值
- prop 验证,和默认值
- 请说下封装 vue 组件的过程
- Vue.js的template编译
- scss是什么?在vue.cli中的安装使用步骤是?有哪几大特性?
- vue如何监听对象或者数组某个属性的变化
- 常用的事件修饰符
- vue如何获取dom
- v-on可以监听多个方法吗?
- assets和static的区别
- slot插槽
- 全局过滤器和局部过滤器的使用
- vue初始化页面闪动问题
- vue改变数据DOM不更新的解决办法
- vue插件篇
- 常用webpack配置
vue的优点
轻量级框架:只关注视图层,是一个构建数据的视图集合,大小只有几十kb;
简单易学:国人开发,中文文档,不存在语言障碍 ,易于理解和学习;
双向数据绑定:保留了angular的特点,在数据操作方面更为简单;
组件化:保留了react的优点,实现了html的封装和重用,在构建单页面应用方面有着独特的优势;
视图,数据,结构分离:使数据的更改更为简单,不需要进行逻辑代码的修改,只需要操作数据就能完成相关操作;
虚拟DOM:dom操作是非常耗费性能的,不再使用原生的dom操作节点,极大解放dom操作,但具体操作的还是dom不过是换了另一种方式;
运行速度更快:相比较与react而言,同样是操作虚拟dom,就性能而言,vue存在很大的优势。
数据驱动的理解
当vue中的数据发生改变的时候,用户的界面也会相应的变化,开发者不需要手动去修改DOM元素。这样可以认为是vue.js帮我们处理了数据和DOM对象之间的映射,我们有更多的精力去处理业务逻辑。这样比频繁的操作DOM元素,效率要高很多。
MVVM的理解
vue中的数据驱动是通过MVVM框架实现的,M指的是data数据部分,V指的是view页面视图部分,VM指的是连接数据和页面视图的中间件。
- MVVM说明
数据和页面视图是不能直接通信的,这时候需要中间件来实现双方的数据通信。
当数据发生变化的时候,中间件监听到了以后通知页面视图进行渲染,如果是有事件触发的时候,中间件监听到了以后,会对data中的数据做出更改
MVVM最终实现了业务(data)和视图的分离 - MVVM三要素
1.响应式 vue如何监听数据的变化
2.vue模板如何编写和解析,如何把具体的数据替换到模板中,{ {}}双花括号的形式。
3.vue如何把模板转换为HTML(虚拟DOM的显示和DOM的转换)
组件化的理解
1.组件定义
组件是可复用的的vue实例,可以增强代码的复用性,提高可维护性
2.组件的使用场景
1.通用组件 实现基本的功能,比如输入框组件,下拉菜单组件等等(element-ui中的组件)
2.业务组件 用于完成一定的业务和功能,比如搜索框组件、轮播图组件、tab选项卡组件等。
3.页面组件 组织应用各部分页面内容,用于页面组件的切换,比如商品列表页面组件,购物车页面等。
3.如何使用组件
第一种:components注册
第二种:有状态组件(data) 无状态组件(函数组件)
第三种:组件传值、父传子用props接收,子传父用emit
第四种:组件用于内容的分发,比如插槽的使用
4.vue组件产生的过程
组件配置-Vuecomponent-render-虚拟dom-真实的DOM结构
数据闪烁
如果是{ {msg}}会出现数据闪烁的现象,用v-text="msg"可以解决这个问题
<div id="app">
<div>{
{
msg }}</div>
<div v-text="msg"></div>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
<script>
const app = new Vue({
el: "#app",
data() {
return {
msg: "aa"
};
}
});
</script>
请详细说下你对vue生命周期的理解?
总共分为8个阶段创建前/后,载入前/后,更新前/后,销毁前/后。
创建前/后: 在beforeCreate阶段,vue实例的挂载元素el和数据对象data都为undefined,还未初始化。在created阶段,vue实例的数据对象data有了,el为undefined,还未初始化。
载入前/后:在beforeMount阶段,vue实例的$el和data都初始化了,但还是挂载之前为虚拟的dom节点,data.message还未替换。在mounted阶段,vue实例挂载完成,data.message成功渲染。
更新前/后:当data变化时,会触发beforeUpdate和updated方法
销毁前/后:在执行destroy方法后,对data的改变不会再触发周期函数,说明此时vue实例已经解除了事件监听以及和dom的绑定,但是dom结构依然存在
vue中父子组件的生命周期
渲染的过程
-父beforCreate>父created>父beforMount>子beforCreate>子create>子beforMount>子Mounted>父mounted
子更新创建过程
-父beforUpdate>子beforUpdate>子updated>父updated
父组件更新过程
-父beforUpdate>父updated
销毁过程
-父beforDestory>子beforDestory>子destoryed>父destoryed
vue中的指令和它的用法
v-for 用于遍历数组、对象、数字的值,使用的语法是 name in 数组(对象,数字)
如果遍历的是数组,则可以获取到数组的元素和下标(索引),使用方法为 (item,index) in 数组
如果遍历的是对象,则可以获取到对象的属性名和属性值,使用方法为(属性,值)in 对象
注意:使用v-for指令时,最好给一个key属性,用于优化vue对DOM的渲染
v-model 双向数据绑定指令 一般用于表单元素
v-on 用于添加事件 用@符代替
v-bind 用于绑定一个或多个属性 用:代替
v-html 数据被定义在数据属性中,指明了具体的html内容。对应JavaScript中的innerHTML
属性
v-text 数据被定义在数据属性中,指明了具体的值。将具体的值展示在视图层,对应JavaScript中的innerText属性
v-once 作用是只会渲染对应元素一次,数据更行不会引起视图的更新,目的是为了优化页面的性能
v-if 用于根据条件表法是来带有条件的渲染。如果条件为假,那么页面中将不回渲染当前元素
v-else 在v-if条件不满足时才起作用,不能单独使用,必须配合v-if一起使用
v-show 用于显示或者隐藏元素,它是以style样式的方式来实现的
为什么vue组件中data必须是一个函数?
对象为引用类型,当复用组件时,由于数据对象都指向同一个data对象,当在一个组件中修改data时,其他重用的组件中的data会同时被修改;而使用返回对象的函数,由于每次返回的都是一个新对象(Object的实例),引用地址不同,则不会出现这个问题。
vue中v-if和v-show有什么区别?
v-if和v-show看起来似乎差不多,当条件不成立时,其所对应的标签元素都不可见,但是这两个选项是有区别的:
1、v-if在条件切换时,会对标签进行适当的创建和销毁,而v-show则仅在初始化时加载一次,因此v-if的开销相对来说会比v-show大。
2、v-if是惰性的,只有当条件为真时才会真正渲染标签;如果初始条件不为真,则v-if不会去渲染标签。v-show则无论初始条件是否成立,都会渲染标签,它仅仅做的只是简单的CSS切换。
computed和watch的区别
计算属性computed:
- 支持缓存,只有依赖数据发生改变,才会重新进行计算
- 不支持异步,当computed内有异步操作时无效,无法监听数据的变化
- computed 属性值会默认走缓存,计算属性是基于它们的响应式依赖进行缓存的,也就是基于data中声明过或者父组件传递的props中的数据通过计算得到的值
- 如果一个属性是由其他属性计算而来的,这个属性依赖其他属性,是一个多对一或者一对一,一般用computed
- 如果computed属性属性值是函数,那么默认会走get方法;函数的返回值就是属性的属性值;在computed中的,属性都有一个get和一个set方法,当数据变化时,调用set方法。
侦听属性watch:
- 不支持缓存,数据变,直接会触发相应的操作;
- watch支持异步;
- 监听的函数接收两个参数,第一个参数是最新的值;第二个参数是输入之前的值;
- 当一个属性发生变化时,需要执行对应的操作;一对多;
- 监听数据必须是data中声明过或者父组件传递过来的props中的数据,当数据变化时,触发其他操作,函数有两个参数:
immediate:组件加载立即触发回调函数执行
watch: {
firstName: {
handler(newName, oldName) {
this.fullName = newName + ' ' + this.lastName;
},
// 代表在wacth里声明了firstName这个方法之后立即执行handler方法
immediate: true
}
}
deep: deep的意思就是深入观察,监听器会一层层的往下遍历,给对象的所有属性都加上这个监听器,但是这样性能开销就会非常大了,任何修改obj里面任何一个属性都会触发这个监听器里的 handler
watch: {
obj: {
handler(newName, oldName) {
console.log('obj.a changed');
},
immediate: true,
deep: true
}
}
优化:我们可以使用字符串的形式监听
watch: {
'obj.a': {
handler(newName, oldName) {
console.log('obj.a changed');
},
immediate: true,
// deep: true
}
}
这样Vue.js才会一层一层解析下去,直到遇到属性a,然后才给a设置监听函数。
vue-loader是什么?使用它的用途有哪些?
vue文件的一个加载器,跟template/js/style转换成js模块。
$nextTick是什么?
vue实现响应式并不是数据发生变化后dom立即变化,而是按照一定的策略来进行dom更新。
nextTick 是在下次 DOM 更新循环结束之后执行延迟回调,在修改数据之后使用nextTick,则可以在回调中获取更新后的 DOM
v-for key的作用
当Vue用 v-for 正在更新已渲染过的元素列表是,它默认用“就地复用”策略。如果数据项的顺序被改变,Vue将不是移动DOM元素来匹配数据项的改变,而是简单复用此处每个元素,并且确保它在特定索引下显示已被渲染过的每个元素。
为了给Vue一个提示,以便它能跟踪每个节点的身份,从而重用和重新排序现有元素,你需要为每项提供一个唯一 key 属性。key属性的类型只能为 string或者number类型。
key 的特殊属性主要用在Vue的虚拟DOM算法,在新旧nodes对比时辨识VNodes。如果不使用 key,Vue会使用一种最大限度减少动态元素并且尽可能的尝试修复/再利用相同类型元素的算法。使用key,它会基于key的变化重新排列元素顺序,并且会移除 key 不存在的元素。
Vue的双向数据绑定?
在表单元素中通过v-model指令把用户输入的值和data(模型)中的数据进行绑定,页面输入的内容时发生变化,data(模型)中的数据会发生变化,如果是data中的数据发生变化,页面(视图)也会相应做出相应的变化。
组件传值
父传子
通过props传递
父组件: <child value = '传递的数据' />
子组件: props['value'],接收数据,接受之后使用和data中定义数据使用方式一样
子传父
在父组件中给子组件绑定一个自定义的事件,子组件通过$emit()触发该事件并传值。
父组件: <child @receive = 'receive' />
子组件: this.$emit('receive','传递的数据')
兄弟组件传值
- 通过中央通信 let bus = new Vue()
A:methods :{ 函数{bus.$emit(‘自定义事件名’,数据)} 发送
B:created (){bus.$on(‘A发送过来的自定义事件名’,函数)} 进行数据接收
- 通过vuex
prop 验证,和默认值
我们在父组件给子组件传值的时候,可以指定该props的默认值及类型,当传递数据类型不正确的时候,vue会发出警告
props: {
visible: {
default: true,
type: Boolean,
required: true
},
},
请说下封装 vue 组件的过程
首先,组件可以提升整个项目的开发效率。能够把页面抽象成多个相对独立的模块,解决了我们传统项目开发:效率低、难维护、复用性等问题。
然后,使用Vue.extend方法创建一个组件,然后使用Vue.component方法注册组件。子组件需要数据,可以在props中接受定义。而子组件修改好数据后,想把数据传递给父组件。可以采用emit方法。
Vue.js的template编译
简而言之,就是先转化成AST树,再得到的render函数返回VNode(Vue的虚拟DOM节点),详细步骤如下:
首先,通过compile编译器把template编译成AST语法树(abstract syntax tree 即 源代码的抽象语法结构的树状表现形式),compile是createCompiler的返回值,createCompiler是用以创建编译器的。另外compile还负责合并option。
然后,AST会经过generate(将AST语法树转化成render funtion字符串的过程)得到render函数,render的返回值是VNode,VNode是Vue的虚拟DOM节点,里面有(标签名、子节点、文本等等)
scss是什么?在vue.cli中的安装使用步骤是?有哪几大特性?
css的预编译,使用步骤如下:
第一步:用npm 下三个loader(sass-loader、css-loader、node-sass)
第二步:在build目录找到webpack.base.config.js,在那个extends属性中加一个拓展.scss
第三步:还是在同一个文件,配置一个module属性
第四步:然后在组件的style标签加上lang属性 ,例如:lang=”scss”
特性主要有:
- 可以用变量,例如($变量名称=值)
- 可以用混合器,例如()
- 可以嵌套
vue如何监听对象或者数组某个属性的变化
当在项目中直接设置数组的某一项的值,或者直接设置对象的某个属性值,这个时候,你会发现页面并没有更新。这是因为Object.defineProperty()限制,监听不到变化。
解决方式:
- this.$set(你要改变的数组/对象,你要改变的位置/key,你要改成什么value)
this.$set(this.arr, 0, "OBKoro1"); // 改变数组
this.$set(this.obj, "c", "OBKoro1"