目录:
- vue高级异步组件
- react异步组件
“今晚我真的想砍死我自己。。。。。。。。。。。。。。。。。
今晚我真的想砍死我自己。。。。。。。。。。。。。。。。。
今晚我真的想砍死我自己。。。。。。。。。。。。。。。。。”
********注意*下面纯属废话,吐槽,请忽略[***************************************************
从vue1到现在vue2,已经使用了vue有一年半的时间了。
之前vue1的时候写了一个微信论坛项目,可能是vue1的时候框架还不够完善或者只是自己没有了解到位,那时候项目用到的动态组件只是局限于路由。
常常遇到一个问题是,一个页面里面又多个tab,而每个tab里面分别对应不同的功能。有些tab比较常用,有些tab可能某些用户一年一不会点击一次。
“每个tab单独写到一个文件然后import进来调用。这样可以减少tab之间的逻辑互相影响,同时让代码更加清晰和容易管理。”
我记得第一次写spa的时候,我还为此沾沾自喜过很长的一段时间。
SPA的遍历的确可以能解决很多传统开发模式无法解决的问题,但是也会带来某些问题,思考的范围也不再局限于浏览器兼容,文件压缩,页面特效。
在后来的一年半的时间里面,公司的工作模式随之VUE框架的推广开始前后分离,VUE也开始在不定期的活动项目上开始大行其道。由于活动项目相对来说,只有弹出交互,对产生的文件大小要求并不是很强。
最近突然感觉自己好久没有翻看过vue的文档了,心里有点不安的感觉,也许是时候复习下和总结下了吧
套用一个群友的吐槽话“忙,整天就知道忙,你是不是瞎了呀.”无厘头,但是却包含很多的无奈。
********上面纯属废话,吐槽,请忽略]***************************************************
来说说今天的问题:
Vue.js 允许将组件定义为一个工厂函数,动态地解析组件的定义。Vue.js 只在组件需要渲染时触发工厂函数,并且把结果缓存起来,用于后面的再次渲染,从而达到减少请求的目的(下面实例代码来自vue官网)
vue异步组件:
Vue.component('async-webpack-example',function (resolve) { // 这个特殊的 require 语法告诉 webpack // 自动将编译后的代码分割成不同的块, // 这些块将通过 Ajax 请求自动下载。 require(['./my-async-component'],resolve) })
Webpack 2 + ES2015 的语法返回一个promise:
Vue.component( 'async-webpack-example',() => import('./my-async-component') )
直接局部注册:
new Vue({ // ... components: { 'my-component': () => import('./my-async-component') } })
这种普通方式的异步组件,我是知道怎么使用的,我查看的一篇博文也很清晰的对它做了再次说明
但是
高级异步组件的调用我就有点看不懂了
它这里强调了component返回的应该是promise,这个开始让我很纠结,或许我一开始就不应该把注意点放在这里,而是应该把原来的组件直接调用即可,这样就不会出现后来的故事。
导致我把重点放在这里的原因在于:我是经常使用import xx form “yy.vue” 这种形式来导入文件的,而且我很明确的知道这种形式返回的是我一个函数,而不是promise
最后证实import(“./mycomp.vue”)返回的的确是一个promise对象它和“import xx form “yy.vue”是不同的
情景重现:
看到了这里应当时一个promise的时候,我第一反应是不是自己应该把mycomp.vue封装成一个jsx的组件,然后export default new Promise
如果返回的是一个promise的话,那
component: import('./MyComp.vue'),
就应该改成函数如下:
添加sync 和await
const asyncCompa = sync() => ({ // 需要加载的组件。应当是一个 Promise component:await import("@/components/asynccomponents1"),loading: loading,// 出错时渲染的组件 error: loading,delay: 3000,timeout: 10000 });
事实上我的确这样做了。然后就开始了一个晚上作死的行动~~~~自虐
结果:Failed to mount component:template or render function not defined
它意味着渲染函数有问题,我查看了父组件(语法没问题),子组件(因为export default new promise了,所有肯定不对)
我把子组件恢复了。
但是仍然不行
这时候我应该sync和await去掉的,如果这样的话我很快就能解决这个问题。但是没有。。。我没有意识到这个自作聪明的作死行为。
我百思不得其解,开始寻求谷歌的帮助。但是没有找到合适的解决方案。
我找到了这样的一个“由于问题过于水”而被关闭的问题https://segmentfault.com/q/1010000009936870/a-1020000009938303,我开始为他感到扼腕,开始不甘和咒骂。。。。巴拉巴拉...............
然后去群里帖代码,问大神。。。。。。。。。
但是可能对方也是一知半解,或者没有实际用过这个功能,,,,
于是乎,,一群人开始被我虐。。。。。。。。。
甚至有位大神直接给我发vue源码截图
虽然他并没有解决我的问题,但是能在手机上为我去阅读源码,这个的确让我十分的感动。我难以想象对方是什么样的水平同时非常震撼我们的差距到底有多大。
遇到问题,我出来jquery插件会看源码外,从来没有去看过框架的源码,从来都没有。。。。。。。。。。这个让我头疼,我头疼我是不是某个地方或者很多地方没有做到位。。。
虽然我的确在努力。。。但是同时经常被群友“小乔”喷“忙,忙,忙,就知道忙,你是不是瞎呀”.
就这样混混沌沌的在群友的陪伴下一个个代码的对和截图。。。。。。
突然有个人问,你哪里为什么要sync,去掉看看
果然,,,,,,,,可以。。。。。我坑了我自己。。。。
而且是走不出的坑直接把自己埋了。。。。。。。。。
水了这么久,帖下最终结果代码
父组件:
<template> <div> <a href="javascript:;" :class='[tab==0?"active":""]' @click="handle(0)">tab1</a> <a href="javascript:;" :class='[tab==1?"active":""]' @click="handle(1)">tab2</a> <div> <p>tab:{{tab}}</p> <async-compa v-if="tab==0"></async-compa> </div> </div> </template> <script> import Vue from "vue"; import loading from "@/components/loading" const y=import("@/components/asynccomponents1"); console.log("loading",loading) console.log("y",y) const asyncCompa = () => sync({ // 需要加载的组件。应当是一个 Promise component:await import("@/components/asynccomponents1"),//这个延时并不能让loading显示更长时间 timeout: 10000 }); export default { name: "asyncCom",data() { return { tab: 1 }; },methods: { handle(index) { console.log(index); this.tab = index; } },moused: function() {},components: { asyncCompa } }; </script> <style lang="less" scoped> .active { color: red; } </style>
子组件:
<template> <div>111111</div> </template> <script> export default { name: "async-components1",data: function() { return { tab: "1" }; } }; </script>
当点击tab为0的时候,浏览器会从服务器加载异步子组件。如果tab不为0的时候,是不会加载的,
可以尝试打开页面后,把网络关掉然后再点击另外一个tab,会发现原来应该出现子组件的地方有一个不断在load的动画
这样可以直接减少大量的不需要用到的组件提高页面的执行效率
已经到晚上1点了,晚安。
迟一点再研究react的异步组件
2018/03/22 00:08更新
react异步组件:
react本身没有集成异步组件,["webpack import()"]不在说明范围内,因为这不属于react范畴,需要使用第三方库“react-loadable”它提供的功能和vue的高级异步组件一样,有timeout,delay,loading,error等可配置参数,下面直接贴代码:
主页面:
import React from 'react'; import Loadable from 'react-loadable'; import "./tab.less" import Loading from '../../components/loading' const LoadableComponent1 = Loadable({ loader: () => import ('./content1'),loading: Loading,delay: 2000 }); const LoadableComponent2 = Loadable({ loader: () => import ('./content2'),delay: 2000 }); class tab extends React.Component { constructor(props) { super(props); this.state = { index: 0 }; this.handleClick.bind(this); } componentDidMount() { //console.log("this.state",this.state) } componentWillMount() {} tabCompont() { return ( <div> <span onClick={() => this.handleClick(0)} className={this.state.index == 0 ? 'active' : ''}>111111</span> <span onClick={() => this.handleClick(1)} className={this.state.index == 1 ? 'active' : ''}>2222222</span> </div> ); } handleClick(index) { console.log("index",index) this.setState({index: index}) } tabContentCompont() { return this.state.index == 0? <LoadableComponent1/>: <LoadableComponent2/>; } render() { return ( <div> <h1>'Hello,world!'</h1> <div> {this.tabCompont()} </div> <div> {this.tabContentCompont()} </div> </div> ); } } export default tab;
子页面和loading页面是普通的react页面,不展开说明。
值得强调的是,它的文档有说明需要对babel进行配置,我试了后没有效果,同事还报错了,没搞明白,最后用了现有项目的已经搭建好的配置,竟然不需要对babel进行配置
react-loadable比vue异步组件更方便的是,它可以加载多个资源
{ "plugins": ["react-loadable/babel"] }
它还有一个姐妹库react-loadable-visibility意思是可见的位置的组件才会加载,看起来非常的方便和厉害
这篇博文注定属于水货了,而且还是稀稀拉拉的滴水的那种。
就当做写日记吧