Vue2深入必知的几点
站长
· 阅读数 24
Vue2深入学习
异步组件
- Vue.component()注册组件时,接收两个参数
- 第一个是组件名,如果是在字符串模板或组件中使用,建议大驼峰。如果是在DOM中直接使用,建议全小写短横线连接
- 第二个是组件定义。可以是一个对象或一个函数
- 观察源码实现可知,传入的组件定义被缓存在options.components中。
- 当定义为对象时,会继承this.options._base对象的值
- 当为函数时,是原样保存,同时该组件被识别为异步组件
- 观察文档描述可知,该函数默认接收resolve和reject两个参数,我们可以在函数中根据自己的方式返回组件的定义
特别注意
- Vue.component提供了异步渲染组件的功能,当收到的组件定义参数是函数时,会在需要渲染时去调用该函数。
- webpack提供了动态导入模块的功能,当使用import()时,会将该语句编译为webpack.require.e()函数。
- 在编译时,webpack遇到import()编译为webpack.require.e()函数,
- 在运行时,Vue将异步组件函数调用获取到webpack.require.e的调用结果,同时会给e传入参数resolve,reject。而webpack.require.e内部是动态创建script标签,将分割为单独chunk的模块的url作为src,动态插入页面,监听脚本加载事件,当加载完毕则执行参数resolve将获取到的结果传入。
- 因此我们在使用import时必须放在函数中,这样异步组件才能获取到import的结果。
Prop和Emit
Prop
特别注意
Emit
插槽
动态组件
const AsyncComponent = () => ({
// 需要加载的组件 (应该是一个 `Promise` 对象)
component: import('./MyComponent.vue'),
// 异步组件加载时使用的组件
loading: LoadingComponent,
// 加载失败时使用的组件
error: ErrorComponent,
// 展示加载时组件的延时时间。默认值是 200 (毫秒)
delay: 200,
// 如果提供了超时时间且组件加载也超时了,
// 则使用加载失败时使用的组件。默认值是:`Infinity`
timeout: 3000
})
边界情况
- 后代组件通过$root获取根实例数据
- 后代组件通过$parent获取父实例数据
- 组件通过$refs获取根实例数据(ref不是响应式数据,只有子组件渲染完毕才会生效,因此在模板和计算属性中不要使用,否则获取不到数据)
- 依赖注入通过provide和inject来获取祖先传下来的数据,相比于root,这种方式父组件只暴露少量数据,相比于root,这种方式父组件只暴露少量数据,相比于root,这种方式父组件只暴露少量数据,相比于parent,可以跨越任意多的层级去获取数据
事件侦听器的一些注意事项
- $emit是用来触发自定义事件的,我们一般是在子组件中通过v-on来自动监听自定义事件
- 有时候需要手动去监听组件的某些事件,而不是在组件标签上通过v-on自动监听,此时就会用到on,on,on,once,$off这三个方法
- 比如,我们在组件内引入第三方组件时,想要在父组件挂载后去实例化三方组件,在父组件卸载前销毁三方组件
- 第一种方式:在父组件的mounted钩子函数内实例化组件,并保存该组件的引用,在beforeDestroy钩子函数中销毁该组件
- 第二种方式:在父组件的mounted钩子函数内实例化组件,调用$once去手动监听hook:beforeDestroy事件,在回调中销毁该组件,相比第一种方式有两个好处,不用保存三方组件的引用,挂载和卸载的逻辑在一块,容易阅读
典型边界问题
- 父子组件互相引用,模板解析时发现互相引用,找不到入口,就会报组件未定义。当然如果父组件是全局注册的则Vue可以自动解开这个循环,如果都是局部注册,则需要我们去异步引入子组件
- 在组件标签中加入inline-template属性,则组件标签之间的内容不会被解析为slot,而是取代组件内的template
- 在template的根标签中加入v-once则只进行一次渲染并缓存,之后使用缓存来解析,一般不用,相比于提升的那点时间,对人造成的困惑更难以接受
- 对于数组和对象的变更检测,有时候可能不满足我们的需求,但是99%的情况都能满足,最好是检查是否使用正确。如果确定使用正确也无法满足需要手动强制更新时可调用$forceUpdate来强制更新
- 注意强制更新只会影响当前组件实例和其直接的子组件实例,更深层次的组件不会被影响,因为递归渲染子组件是Vue主动检测父组件发生变化后才会执行的操作,我们手动更新其父组件并未发生变化