1、vue中父子组件传值,父组件异步请求,子组件不能实时更新怎么解决?(vue中数据不能实时更新怎么解决?)
首先了解父子组件生命周期执行顺序 ==>
加载渲染数据过程
父组件 beforeCreate -->
父组件 created -->
父组件 beforeMount -->
子组件 beforeCreate -->
子组件 created -->
子组件 beforeMount -->
子组件 mounted -->
父组件 mounted -->
原因:因为生命周期只会执行一次,数据是要等到异步请求以后才能拿到,那么子组件的mounted钩子执行的时候,还没有拿到父组件传递过来的数据,但是又必须要打印出来结果,那这样的话,就只能去打印props中的默认值空字符串了,所以打印的结果是一个空字符串。
解决办法:
1.使用v-if控制组件渲染的时机
初始还没拿到后端接口的异步数据的时候,不让组件渲染,等拿到的时候再去渲染组件。使用v-if="变量"去控制,初始让这个变量为false,这样的话,子组件就不会去渲染,等拿到数据的时候,再让这个变量变成true。
2.使用watch监听数据的变化
3.使用VueX
2、vue 首屏加载怎么优化?
- 把不常改变的库放到 index.html 中,通过 cdn 引入,然后找到 build/webpack.base.conf.js 文件,在 module.exports = { } 中添加以下代码
externals: {
'vue': 'Vue',
'vue-router': 'VueRouter',
'element-ui': 'ELEMENT',
}
2.vue 路由的懒加载(import或者require懒加载。)
3.不生成 map 文件,找到 config/index.js,修改为 productionSourceMap: false
4.vue 组件尽量不要全局引入
5.使用更轻量级的工具库
6.开启gzip压缩
3、Vue 中 for循环为什么加 key?
为了性能优化, 因为vue是虚拟DOM,更新DOM时用diff算法对节点进行一一比对,比如有很多li元素,要在某个位置插入一个li元素,但没有给li上加key,那么在进行运算的时候,就会将所有li元素重新渲染一遍,但是如果有key,那么它就会按照key一一比对li元素,只需要创建新的li元素,插入即可,不需要对其他元素进行修改和重新渲染。
key也不能是li元素的index,因为假设我们给数组前插入一个新元素,它的下标是0,那么和原来的第一个元素重复了,整个数组的key都发生了改变,这样就跟没有key的情况一样了
4、Vue 中 nextTick的作用是:该方法中的代码会在当前渲染完成后执行,就解决了异步渲染获取不到更新后DOM的问题了。 n e x t T i c k 的 原 理 : nextTick的原理:nextTick的原理:nextTick本质是返回一个Promise 。
应用场景:在created()里面想要获取操作Dom,把操作DOM的方法放在$nextTick中
5、vue生命周期
beforeCreate:创建前。此时,组件实例刚刚创建,还未进行数据观测和事件配置,拿不到任何数据。
created:创建完成。vue 实例已经完成了数据观测,属性和方法的计算(比如props、methods、data、computed和watch此时已经拿得到),未挂载到DOM,不能访问到el属性,el属性,ref属性内容为空数组常用于简单的ajax请求,页面的初始化。
beforeMount:挂载前。挂在开始之前被调用,相关的render函数首次被调用(虚拟DOM)。编译模板,把data里面的数据和模板生成html,完成了el和data 初始化,注意此时还没有挂在html到页面上。
mounted:挂载完成。也就是模板中的HTML渲染到HTML页面中,此时可以通过DOM API获取到DOM节点,$ref属性可以访问常用于获取VNode信息和操作,ajax请求,mounted只会执行一次。
beforeUpdate:在数据更新之前被调用,发生在虚拟DOM重新渲染和打补丁之前,不会触发附加地重渲染过程。
updated:更新后。在由于数据更改导致地虚拟DOM重新渲染和打补丁之后调用,
beforeDestroy;销毁前。在实例销毁之前调用,实例仍然完全可用。(一般在这一步做一些重置的操作,比如清除掉组件中的定时器 和 监听的dom事件)
destroyed:销毁后。在实例销毁之后调用,调用后,vue实列指示的所有东西都会解绑,所有的事件监听器会被移除。
其他:
activated:在keep-alive组件激活时调用
deactivated:在keep-alive组件停用时调用
6、New 操作符具体干了什么?
1.创建一个空对象: 并且 this 变量引入该对象,同时还继承了函数的原型
2.设置原型链 空对象指向构造函数的原型对象
3.执行函数体 修改构造函数 this 指针指向空对象,并执行函数体
4.判断返回值 返回对象就用该对象,没有的话就创建一个对象
7、module、export、import 有什么作用?
module、export、import 是 ES6 用来统一前端模块化方案的设计思路和实现方案。
export、import 的出现统一了前端模块化的实现方案,整合规范了浏览器/服务端的模块化方
法,用来取代传统的 AMD/CMD、requireJS、seaJS、commondJS 等等一系列前端模块不同的
实现方案,使前端模块化更加统一规范,JS 也能更加能实现大型的应用程序开发。
import 引入的模块是静态加载(编译阶段加载)而不是动态加载(运行时加载)。
import 引入 export 导出的接口值是动态绑定关系,即通过该接口,可以取到模块内部实时的值
8、vue的双向绑定原理?
Vue.js 是采用数据劫持结合发布者-订阅者模式的方式,通过 Object.defineProperty()来劫持各个属性的 setter,getter,在数据变动时发布消息给订阅者,触发相应的监听回调。
1、需要 observe 的数据对象进行递归遍历,包括子属性对象的属性,都加上 setter 和 getter,
这样的话,给这个对象的某个值赋值,就会触发 setter,那么就能监听到了数据变化
2、compile 解析模板指令,将模板中的变量替换成数据,然后初始化渲染页面视图,并将每个指令对应的节点绑定更新函数,添加监听数据的订阅者,一旦数据有变动,收到通知,更新视图
9、描述下 vue 从初始化页面--修改数据--刷新页面 UI 的过程?
当 Vue 进入初始化阶段时,一方面 Vue 会遍历 data 中的属性,并用 Object.defineProperty 将它转化成 getter/setter 的形式,实现数据劫持(暂不谈 Vue3.0 的 Proxy);另一方面,Vue 的指令编译器 Compiler 对元素节点的各个指令进行解析,初始化视图,并订阅 Watcher 来更新试图,此时 Watcher 会将自己添加到消息订阅器 Dep 中,此时初始化完毕。
当数据发生变化时,触发 Observer 中 setter 方法,立即调用 Dep.notify(),Dep 这个数组开始遍历所有的订阅者,并调用其 update 方法,Vue 内部再通过 diff 算法,patch 相应的更新完成对订阅者视图的改变。
10、vue-router 有哪些钩子函数?
关于 vue-router 中的钩子函数主要分为 3 类
1、全局钩子函数要包含 beforeEach
1,1)beforeEach 函数有三个参数,分别是
1,2)to:router 即将进入的路由对象
1,3)from:当前导航即将离开的路由
1,4)next:function,进行管道中的一个钩子,如果执行完了,则导航的状态就是 confirmed
(确认的)否则为 false,终止导航
2、单独路由独享组件
2,1)beforeEnter
3、组件内钩子
3,1)beforeRouterEnter
3,2)beforeRouterUpdate
3,3)beforeRouterLeave