此库用于记录日常工作/学习所获得的一些以前并不了解的知识点。
lizhongzhen11 / dailygain Goto Github PK
View Code? Open in Web Editor NEW日常工作/学习中遇到的小知识点
日常工作/学习中遇到的小知识点
晚上老大说switch case
效率比if else
高,刚好记得前两天也看过类似的分析,具体也想不起来了,这样不好啊。只意识到效率高,却不明其理,这样很浮躁的,很容易被人问倒的,所以我晚上特地去百度了下,看了不少文章,究其原因涉及到了汇编,还有什么switch case
用到了跳表等知识,特记录下来:
项目中需要保存单元id、计划id之类的较长数值,我只负责单元部分,单元一直提交的是string,没有问题。直到今天需要调计划模块的一个接口时,发现入参计划id要求是integer类型,当时觉得奇怪,一般这种长的id不都是string吗。但既然文档要求,那就按照要求来吧。
结果,接口返回null
,这我就很奇怪了,查看入参,按要求来的啊,再看下控制台,发现请求提交的计划id竟然不一样!!!
我控制台打印的明明是 '1097387258221404162' ,而接口入参却是 1097387258221404200 !!!太奇怪了吧!!!
提交时我对数据做了number转换,直接用的+
简写,难道是+
问题,控制台输入+'1097387258221404162'
,果然输出1097387258221404200。
感觉很奇葩,请教了同事,同事说他也遇到过,这个超出了js number类型的长度限制,没法避免,最好的是用string。。。
不过,当我改成string时,能正常提交并拿到数据,看来后台是支持string的,但是文档不严谨啊,不过也算是学到了一点。
最近一直忙于项目,好久没学习了。
1.今天在copyiview
的Select
组件代码时发现了一个没用过的属性:spellcheck
(其实纵观iview
源码,好多css属性我没用过呢,还有不少vue
的api也没用过,尴尬。。。)去MDN上看了下,是一个实验中的属性,用来告诉浏览器是否要检查拼写错误的:https://developer.mozilla.org/zh-CN/docs/Web/HTML/Global_attributes/spellcheck
2.今天才算第一次真正在项目中用到vue
的transition
组件,刚开始用不知道name
会对应css类,文档要看全!https://cn.vuejs.org/v2/guide/transitions.html#%E8%BF%87%E6%B8%A1%E7%9A%84%E7%B1%BB%E5%90%8D
3.今天朋友代表他们组校招面试985的大学生,我日,学生都挺猛的,据说diff算法,虚拟dom,react和vue的区别,各自设计原理等等有深度的问题都回答的很好,不愧是名牌大学生,不像我只知道打游戏。学无止境~
是这样的,最近做的项目,由于计划、单元、创意三大模块全部在一个vue中引入,流程类似腾讯广告投放平台,腾讯的做法是,当单元保存成功并展示创意后,还可以回去修改单元并实施掉接口保存,但是这样并不好。
一开始产品要求完全按照腾讯的来,不过由于这个项目有好几个平台,比腾讯的要复杂,不能按照腾讯的来,所以想到一个折中的方法,当走到创意这一步时将单元可编辑内容全部禁用!
拿到需求后,我一开始想的是通过创意是否展示(true/false)并通过props
传给各个子组件去控制禁用,输入框和select框还好说,但是涉及到定向设置里面的各个级联选择器以及时间段选择,我发现很难搞。
后来涛哥说要不加个浮层并且设置pointer-events
控制不给编辑,我觉得是个好思路(涛哥到底还是很牛逼的)。
一开始想直接用element-ui提供的浮层,但是发现它是fixed
并且top: 0
,全屏覆盖了,还不能滚动,产品肯定不同意,这我就有点苦恼了。
然后又是涛哥,牛逼的提出了在我整个单元模块外面套一层div
并设置z-index: -1;
,当创意展示出来后,改变该div
样式,加上pointer-events
以及z-index
设非常的高,果然解决了。
我怎么想不到呢?
1.今天才知道css有个all属性,除了unicode-bidi
和direction
都支持该属性!
2.chrome调试技巧再度get!!!F12打开控制台,然后选择第一个Elements
,再选中那个带箭头的图标,点击页面上的例如input
框,下方选中Event Listeners
(和Styles在同一行)即可知道该input
上存在的事件以及相应的js文件!!!
1.今天老项目有个需求,就是在select
下拉框中的每个li
加个鼠标悬停显示文字的效果,一开始想用事件来做,后来发现直接加个title
就能解决,省下一大笔代码。
2.还有,form
表单提交时,只要有name
属性的都会提交数据,除了disabled
。之所以记录这个,是因为一个页面在已经有了下一步按钮同时加上一个保存按钮,两个按钮都起到提交功能,但是跳转页面不一样,起初我想通过callback
来做,代码较多,后来还是后台的哥们说直接在两个button
上加不同的name
属性,他根据这个来判断,果然好了,又省下一大段代码。汗颜。。。
button
都加了name
属性,怎么点击其中一个button
貌似只传了被点击button
的value
值,另一个没被点击的居然没传,以前还真没注意到1.js遍历数组时需不需要将数组长度缓存起来?
背景如题。
冬哥昨晚把前端项目打包放到服务器上,然后通过ip访问不到。问我我也不清楚,毕竟我唯一一次把前端webpack打包后放到服务器上还是两年前。
后来我仔细回想了下,我记得那个项目是springmvc+mybatis+vue的,我在web.xml里面配置了<mvc:default-servlet-handler/>
,那个项目虽然是webpack打包的,但是最终发布依然不算是前后端分离,以前不懂,以为前后端分开开发,接口对接就是前后端分离,昨晚才发现理解有点偏差,完全前后端分离应该包含打包发布到服务器上。
冬哥一开始在服务器上配置了nginx,我起初以为就是做代理用,直到昨晚才发现,其实前端webpack打包项目后,放到服务器上,配置下nginx,然后直接访问ip+端口号就能访问前端页面了。
当然,默认是80端口。
以前也有看过nginx文章,当时了解下,昨晚发现看过的完全忘了,没有经过实战的理论知识终究只是过眼云烟啊,附上之前看过的nginx文章:
https://love2.io/@hfpp2012/doc/nginx-tutorial/README.md
1.上周日加班时继续学习vue源码,看到下面的代码,一开始真的感到震惊,居然能这样写???
(tip ? tips : errors).push(msg)
然后我去控制台模拟测试了下:
var a = []
var b = []
(true ? a : b).push(1)
a // [1]
b // []
说实话,我是真的第一次知道可以这样写。。。
2.还注意到vue源码里多次复用变量,比如i
,for
循环中赋值为number类型,循环结束赋值为函数然后直接执行,这种变量复用很好,但是代码实力不高的人慎用。。。
3.我看的是2.5.17-beta.0版本,滴滴前辈的源码也是这个版本,但是我发现 class Watcher
里面的update
代码变化了。。。其实原理是一样的。
如题,后台管理系统通过富文本上传了一篇带图片的文章,然后小程序调接口获取显示,发现图片没有渲染出来,感觉很奇怪。
一开始仔细研究标签,发现img缺少/>
,我手动给它加上,发现还是不行,说明不是这个问题。
然后看小程序官方文档,https://developers.weixin.qq.com/miniprogram/dev/component/rich-text.html ,有这么一句话:img 标签仅支持网络图片,仔细看了下,我的图片确实是网络地址啊,看下图:
后来我百度,发现也说这个网络地址问题,不过他配置的是域名,我猜测不会需要域名地址才行吧?毕竟正式上线的话,所有接口都必须是https://域名
的形式,不过开发模式下一般关闭的,然后,我就直接拿我github上的某个图片写死替换,发现还真是:
然后,我以为解决了,结果放开写死,替换成 https://域名
,依然不显示,这就尴尬了。
到底是什么问题呢?
回顾刚刚成功,我是这样的:
// conten对应rich-text的nodes
content: <img src="https://raw.githubusercontent.com/lizhongzhen11/dailyGain/master/images/rich-text-img.png">
而接口是:
content: "<p>康养小镇详情</p><figure class="image"><img src="https://www.hk952183.com:32122/file/1.jpg"></figure>"
难道不支持多标签?不可能!我继续研究官方文档,突然发现错过什么。。。
小程序富文本不是所有标签都支持的。。。而接口返回的figure标签,小程序就不认识,把它去掉,图片完美展示出来。。。
大坑啊。还要去替换标签,好烦啊!
这个主要是路径配置问题,可以看下下面链接:
https://segmentfault.com/q/1010000010158856
https://juejin.im/post/5c243179e51d450cfe736fb3
回到项目中,这个问题主要是因为webpack中生产配置文件的publicPath
被我改成了'./'
。
使用vue-cli构建项目时,会问我们是否用history模式,如果选择是,那么生产环境的publicPath
默认是/
,打包到线上不会出现这种问题,但是,由于使用了element-ui,会发现线上环境图标没了,网上都说要把publicPath改为./
,如果照着做,那么图标确实有了,但是,却会出现 Unexpected token < 报错。
解决方法有两种:
一提到用...表示,其实有点经验得都会想到下面的css
.curt {
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
但是,这种方法只能对单行文本有用,如果是多行的话,它会把每行都给用...表示,很明显不满足需求。
网上倒是有几个方法,记录下:
div {
display: -webkit-box;
overflow : hidden;
text-overflow: ellipsis;
-webkit-line-clamp: 3;
-webkit-box-orient: vertical;
}
第二种方法缺点也明显,看前缀就知道只能在webkit内核的浏览器中生效。
今天学到了至少两点
1.阅读vue源码normalizeArrayChildren
方法时看到标题那段代码,第一时间没能理解,然后在控制台实验:
var a = [1]
var b = [2, 3]
a.push.apply(a, b) // 3
a // [1, 2, 3]
concat
的作用,只是利用了apply()
方法,避免了concat
返回新数组在堆内存开辟新空间的损耗。记得在网上看到过评论,说concat
性能不高。2.关于反斜杠知识点,看博客 lizhongzhen11/lizz-blog#17
本着项目也是实践技术的想法,在项目中尝试用jsx语法写一个组件。好在vue的确提供了jsx的语法插件,还有v-model插件,可以在github上找到。
我写了一个white-space
组件,就是用来占位的,一般来说没什么难度,但是有些情况下不得不在这个组件内插入一些内容,第一想法就是slot
插槽了。可是写惯了template
,转到jsx还真不知道怎么去写呢。
也是百度了半天才找到写法,话不多说,上代码:
render (h) {
return (
<div class="white-space" style={this.setHeight}>
{this.renderSlot()}
</div>
),
}
computed: {
setHeight () {
return `height: ${this.height}px;`
}
},
methods: {
renderSlot () {
if (this.$slots.whiteSpace.length === 0) {
return
}
return this.$slots.whiteSpace.map(item => return item)
}
}
昨晚冬哥说他前端打包太麻烦了。
因为目前有四个环境:本地,我的腾讯云测试服务器,客户的测试服务器以及客户的正式环境。
每次打包都要去改项目配置host,因为项目中有三处host,分别是接口host,图片上传host以及单点登录host。这样改起来很麻烦,冬哥希望直接npm run build就能自动打包成对应环境的的包,然后发布到服务器上直接用,不需要慢慢手动改。
我第一想法是弄四个build命令,根据不同环境调不同的打包命令。
这就需要每个命令传参,让我知道这是哪个环境的。
接下来关键是如何获取这个参数?
以前没写过,不过我想这个问题应该很常见,遂百度,果然找到了:
https://ask.csdn.net/questions/709800
根据 process.argv 即可获取,打印输出是参数数组,我是这样获取的:
然后把它放进 process.env 中,这样项目中就可以拿到了,根据process.env.ENV知道对应哪个环境,然后新建个ENV.js,把所有host配置进去,根据环境参数去拿对应的host,看代码:
console.log(process.env.ENV)
// 打包的目标环境
const ENV = process.env.ENV
const ENV_HOST = {
local: { // 本地环境对应的接口配置
host: '',
singleSignUrl: '',
callbackUrl: '',
VolunteerHomeUrl: '',
uploadUrl: ''
},
tencent: { // 我们的测试环境,腾讯云
host: '',
singleSignUrl: '',
callbackUrl: '',
VolunteerHomeUrl: '',
uploadUrl: ''
},
user_test: { // 客户的测试环境
host: '',
singleSignUrl: '',
callbackUrl: '',
VolunteerHomeUrl: '',
uploadUrl: ''
},
user_prod: { // 客户的正式环境
host: '',
singleSignUrl: '',
callbackUrl: '',
VolunteerHomeUrl: '',
uploadUrl: ''
}
}
console.log(ENV_HOST[ENV])
const HOST = ENV_HOST[ENV] || ENV_HOST['tencent']
console.log(HOST)
export default HOST
我一开始是在 build 目录下的 build.js 直接对 process.env 进行赋值,然后打包测试发现undefined,后来在这里:https://www.cnblogs.com/pannysp/p/8665321.html 看到,人家是放到 config 文件夹下的 prod.env.js下面配置才行。
日,看了下webpack.prod.conf.js配置代码,居然用了:
const env = process.env.NODE_ENV === 'testing'
? require('../config/test.env')
: require('../config/prod.env')
new webpack.DefinePlugin({
'process.env': env
}),
难怪的,MMP的,直接改了env,我就说我之前写的怎么没用的,操操操!!!
之前接手的有个项目,我没有gitlab权限,用的朋友的账号密码拉的项目,然后创建自己的分支。后来同事改了密码,今天又需要加新功能,我准备直接拉,结果始终报:
Authentication failed for ...
一百度说是密码问题,然后要设置密码,我照做了,没用。
然后在这里:https://www.cnblogs.com/gzbit-zxx/p/8126849.html 找到解决方法,我采用的第一种:
git clone http://用户名:密码@地址
今天接手一个老项目,很老,09年左右的吧。同事用的MyEclipse开发的,其实之前
slot
api,直到目前接手的项目中用到,才发现其实自己不怎么会,后来百度了下才算了解:https://laboo.top/2018/11/07/vue/其实官方文档中具名插槽讲的很详细,只怪自己一目十行。
1.今天继续看vue源码分析文章,发现我本地的vue目录中少了scripts文件夹,我感到很奇怪,我的vue是2.5.17版本的,我以为是尤大做了什么*操作,百度了好久,后来再去github上看vue源码库,发现github上有scripts文件夹,再一看版本,2.5.21。。。是不是以前版本没传scriptd文件夹啊。
1.看了几篇技术文章,记录下:
最近突然遇到个问题,在watch
中使用&&
竟然不执行!!!
一开始以为是我代码问题,但是打印输出没任何问题,在自己的电脑上同一个vue文件内的watch
中使用&&
测试,发现没问题。
true && console.log(222)
和项目中遇到的情况所不同的是,我监听的是通过props
传入的值,并且该值是通过接口获取动态改变的。
附上部分代码:
watch: {
cityLevel (val) {
console.log('9999999999', val, +this.campaignType)
if (+this.campaignType === 1) {
console.log('666666666')
}
+this.campaignType === 1 && console.log('888888888')
}
}
我得研究研究。
公司IOT平台太烂了,jsp写的,而且没啥样式,前两天被扬大的某教授点评了下,老板很生气,然后我有机会重构它了。
虽然这个项目也是今年同事们写完的,但是,哎,算了,反正我觉得长这样的项目是卖不出去的。
既然重构,又有时间,当然选react+ts了,反正时间充足,慢慢搞。
然后踩坑了吧。。。
我个人不是很喜欢class
这种语法糖,然后也听说react开始基于函数式编程了,所以我所有组件全是函数!!!
但是,这样的话,我的数据传输等等就有点麻烦了。
前两天是react-router踩坑,搞了半天才知道可以用<route>
嵌套来实现类似vue的<router-view>
,以及如何用redux维护路由history,控制路由命令式跳转。
但是,今天知道了react-redux,以及看到了人家的@connect
写法,有点spring的注解意思了,觉得很酷,然后一天时间都埋在这上面了。
日。
首先说下,@connect 是装饰器语法糖,还不是规范,要考虑兼容性得。慎重!
首先是把react-redux官方文档看了一遍,但是第一眼看下去就觉得不大懂,示例不连贯吧。最主要它这样的:
<Provider store={store}>
<App />
</Provider>
我愣是不明白这个 store 怎么写?它就说是个redux api,但是你都react-redux了,有没有改它的写法呢?
我在github上看了两个项目,有用dva的,暂不考虑(先学基础的),也有用react-redux的,用react-redux的还引入了redux,并用它生成 store,当然,那个项目生成 store 的代码不算基础,还引入了其他第三方库。
我当时就想,都用react-redux了,要啥redux呢???
后来,我发现我错了,它两不是互相替换的。。。
store 还是要靠redux生成才行。。。
生成store后,我发现在我的函数式组件(页面)中,拿不到啊!!!
卧槽,搞了我真的好久,刚刚才知道,通过connect(mapStateToProps)(组件)
,在mapStateToProps
中返回store,才能在组件的 props 中拿到。。。
真坑啊。。。
系统用到了富文本ckeditor5,用来给小程序展示的。但是,图片上传不了。
我今天有时间接手来查Bug,发现调upload接口,返回 token is empty。问题很明显,需要加 token。顺带说一句,这个系统几乎所有的接口都要求带上token。
但是,令我伤心的是,ckeditor5不支持设置请求头。。。它只支持设置上传url。。。
这就尴尬了,我都没用过这个插件,只能去github上找,然后看到官网,但是还是不那么容易。遂百度,得知需要自己去自定义图片上传插件。
不过还好在github上找到代码:https://github.com/taurus888/ckeditor5-vue/blob/master/src/assets/upload.js
感谢该作者。
一开始我想直接用系统封装好的axios来改写,后来发现这个需要FormData格式,这就尴尬了,没有封装。算了,不改了,直接用。
不过需要对请求头改写下:
_initRequest() {
const xhr = this.xhr = new XMLHttpRequest();
xhr.open( 'POST', uploadConfig.uploadUrl, true );
xhr.setRequestHeader('X-Token', uploadConfig.headers['X-Token'])
xhr.responseType = 'json';
}
由于几乎从来没有用过这个对象去调接口,犯了个低级错误,我一开始居然把xhr.setRequestHeader
写到xhr.open
前面了。。。
MDN https://developer.mozilla.org/zh-CN/docs/Web/API/XMLHttpRequest/setRequestHeader 上明确说明 XMLHttpRequest.setRequestHeader() 是设置HTTP请求头部的方法。此方法必须在 open() 方法和 send() 之间调用。
还有一点需要注意:
// 准备数据并发送请求
_sendRequest( file ) {
//通过FormData构造函数创建一个空对象
const data = new FormData();
//通过append()方法在末尾追加key为files值为file的数据,就是你上传时需要传的参数,需要传更多参数就在下方继续append
// 这个key必须是你后端定义好的能接受的,一般是file,该仓库代码用的是files,需要注意
data.append( 'file', file );//上传的参数data
/**
* 重要提示:这是实现诸如身份验证和CSRF保护等安全机制的正确位置。
* 例如,可以使用XMLHttpRequest.setRequestHeader()设置包含应用程序先前生成的CSRF令牌的请求头。
*/
this.xhr.send( data );
}
图片上传成功保存提交时,发现 img 标签的src是本地二进制blob地址,没有换成远程地址,这就导致了编辑进来看不到图片,需要改:
//上传成功,从后台获取图片的url地址
resolve( {
default: response.payload
} );
今天遇到了个很不解问题,想了起码3小时愣是没想明白,是一个vue写的模拟table列表的组件,这里贴出部分代码:
<template>
<div class="panel-default">
<div class="panel-head panelFixedWidth">
<ul>
<li class="toggle" >
<label><input type="checkbox" v-model="checkAll"></label>
</li>
<li v-for="(item, index) in titleList" :key="index" :class="'wid-' + item.key">
<select v-if="item.key==='MediaType'" v-model="adMediaType" @change="changeTitle" class="box-select">
<option v-for="(opt, opt_index) of item.options" :key="opt_index" :value="opt.value" v-text="opt.title"></option>
</select>
<select v-else-if="item.key==='DayNums'" v-model="adDayNums" @change="changeTitle" class="box-select">
<option v-for="(opt, opt_index) of item.options" :key="opt_index" :value="opt.value" v-text="opt.title"></option>
</select>
<select v-else-if="item.key==='IsActive'" v-model="adIsActive" class="box-select" disabled>
<option v-for="(opt, opt_index) of item.options" :key="opt_index" :value="opt.value" v-text="opt.title"></option>
</select>
<span v-else v-text="item.title"></span>
</li>
</ul>
</div>
<div class="panel-body">
<ul class="panel-content-ul">
<li class="clearfix" v-for="(item, index) in dataList" :key="index" class="panelFixedWidth">
<span class="toggle" >
<label><input type="checkbox" :value="item.ID" v-model="checkList"></label>
</span>
<span
v-for="(item_value, item_key) in item"
:key="item_key + '-' + index"
:class="'wid-' + item_key"
:title="item_value"
v-if="item_key !== 'ID'"
v-text="item_value">
</span>
</li>
</ul>
</div>
</div>
</template>
省略了一些无关的代码,核心渲染代码就这么多。
key
来对应,但是也不对啊,vue中key
应该是唯一的,而且表中的key
后面都加上了index
!这就很奇怪了,我也一度以为和后台约定好顺序它才能一一对应的,的确,在其他页面,后台返回的例如BidMode
如果夹在三个select
之中,那么列表渲染时数据没有一一对应,改变数据顺序就正常了,可是Size
默认放在最后,而页面上Size
却第4个展示,它还是一定程度上保证一一对应的!神烦,今天记录下来,明天继续搞!!!今天解决昨天遗留的困惑了。
1.首先,谷歌浏览器它接受后台传过来的对象时,会默认按照ascii码对对象键名进行排序,这就是为什么明明后台没有按顺序随意塞数据给我,而我接收时却总是看到对象键名类似英文字母排列。
2.针对昨天的问题
实在想不通,请了外援 童萌(同事),他直接把数据在控制台打印出来,然后通过谷歌浏览器控制台右击选择 Store as global variable将其中一条数据保存为全局变量,然后对它进行
for in
遍历,然后震惊我了,遍历后的的顺序是这样的:
ID
AdID
AdName
AdType
Size
BidMode
MaterialType
MediaType
DayNums
IsActive
Size
这一列排在了第五,因为for in
后它就是第五(v-for
遍历对象时其实类似于for in
)。这样只要保证表头数据与传过来的表中数据数量一致,字段一致,顺序无所谓,因为两个v-for
保证了即使不同浏览器情况下它们遍历后的顺序也相同!!!v-for
遍历后的顺序不是我在控制台看到的遍历前的顺序!!!var obj = {...}
一个一个的写进去然后通过for in
遍历,那时候发现顺序没变,就没想到for in
上面,今天早上搜索发现当我们在控制台构造Object
时,这时候遍历出来的键顺序与构造时一致,而引发上述问题的数据是后台传过来的,并不是我自己创建的。虽然我们日常大多数会用element-ui或者iview等等ui框架,但是总有些业务场景,我们需要在子组件传递给我的参数中增加一些参数进行判断等等,那么该怎么写呢?
其实之前有百度查到过,但一段时间不写或者项目很忙大脑转不过来时就容易忘,所以记录下。
具体看:vuejs/vue#5735
举个例子:
子组件
<template>
<div>
<input @change="change"/>
</div>
</template>
<script>
export default {
name: 'child',
methods: {
change (e) {
this.$emit('input', e)
}
}
}
</script>
父组件:
<template>
<div>
<child @input="value => input(value, 新参数)"/>
</div>
</template>
<script>
import Child from './child'
export default {
name: 'parent',
components: {child}
methods: {
input (value, 新参数) {
console.log(value, 新参数)
}
}
}
</script>
最近一个月忙的一笔,天天上班,停休,哎,都没时间学习以及做笔记了。
最近这个项目比较重要,采用的是vue-cli3搭建。大部分接口都是java做好跨域的配置前端直接调用,但我负责的地方用到了另一个项目的接口数据,一开始我本地webpack配置跨域去解决,没有问题,但是打包到线上后直接报404,很是奇怪,遂百度了下,网上说服务器需要配置,跟老大商量了下,老大说这个服务器还是跟别的组借的(我们前端组一开始没有自己的服务器。。。)
后来跟另一个项目的人商量了下,他们做了修改允许跨域,目前线上能正常访问接口并获取到数据了。
最近接手了人家开发一半的项目,是个后台管理系统,我起初大致浏览了下界面,大部分都是列表——详情页,而且列表页基本上差距不大,顶多就是顶部筛选项略有不同,但是也可以通过slot-scope
配置,我写了一个模板,其他组件都extends
这个模板/组件,然后调接口获取到数据了,但是,问题来了,有的列表数据多,显示屏放不下,这种情况肯定要横向滚动条了,然后我通过chrome去查,发现已经设置了overflow-x: auto;
,但是滚动条死活不出来。
然后我以为是element-ui的bug,百度+查issue,确实发现一些横向滚动条的issue,但是跟我的情况不一样,我就懵逼了。
我思考了起码两小时吧,始终以为是bug,直到最后,我尝试给它设死高度,想看看纵向滚动条有没有,结果依然没有,但是能滚动!!!
我立马怀疑,是不是全局隐藏了滚动条,然后在全局样式里果然找到了这条:
::-webkit-scrollbar {/*隐藏动条*/
display: none;
}
我真的fuck了,大哥不带这么玩我的啊!!!
我还去线上环境看原来团队的界面呢,他们贼精,始终保持几个数据列在table中,就不会有横向滚动条问题,这肯定不行啊,这完全是消极怠工啊!
$(this.$refs.tab).find("li[data-index=" + index + "]").get(0).scrollIntoView({
behavior: 'smooth',
block: 'nearest',
inline: 'nearest'
});
scrollIntoView
这个api,果然还是实验中的属性。firefox不支持"block" 设置项的值"nearest" 或 "center",也不支持 "inline" 设置项。具体看:https://developer.mozilla.org/zh-CN/docs/Web/API/Element/scrollIntoView由于需要引入高德地图,高德地图会在window上绑定 AMap 对象。
但是默认的Window
接口上是没有这个属性的,必须对其进行拓展才行。
然后百度了下都说在 .d.ts 文件中这样声明:
declare global {
interface Window {
AMap: any;
}
}
我TM试了半天都没鸟用。
MMP的,终于在这篇文章找到了解决方案:https://blog.csdn.net/weixin_34289454/article/details/92072706
我直接在 react-app-env.d.ts 文件中加入:
interface Window {
AMap: any;
}
然后就好了。
但是,我之前在 interface Window
前面加了export
,始终不行!!!甚至影响到了别的模块。
哎,强行上ts要踩好多坑啊。。。
可是不上就永远不会。
https://github.com/Microsoft/TypeScript-React-Starter#typescript-react-starter
如果你以前通过npm install -g create-react-app
全局安装过create-react-app
,官方推荐使用npm uninstall -g create-react-app
先卸载,然后安装最新的npx
。
npx create-react-app my-app --typescript
,然后npm start
就能启动了。https://facebook.github.io/create-react-app/docs/adding-typescript
npx create-react-app my-app
创建了项目后,突然发现忘了添加typescript
,需要自己去手动配置
先照着官方文档:
npm install --save typescript @types/node @types/react @types/react-dom @types/jest
然后如果直接照着文档提示,将 src/index.js 改成 src/index.tsx 再启动的话,一定报错!!!
这时候需要去手动改配置了。
如何去配置呢?
最简单的方法就是照着npx create-react-app my-app --typescript
创建的项目配置去改:
// 研究性学习
// 生成带typescript的项目环境
npx create-react-app react-ts --typescript
// 显示被隐藏的webpack配置
npm run eject
然后比对 my-app
和 react-ts
两个文件夹,很明显的看到,少了个 tsconfig.json
。可以直接拷贝过来,关于里面的配置信息以及所有课配置项看:http://json.schemastore.org/tsconfig
这个时候 npm start
下发现无报错,能正常启动了。
但是能用了吗?
试试把 src 下所有 js 文件都改成 .tsx/.ts 后缀,然后重新 npm start
。
启动报错:Cannot find module './logo.svg'.
继续对比两个项目,会发现 react-ts
项目的 src 目录下有个 react-app-env.d.ts
文件,但是我的 my-app
项目没有。
将它拷贝过来,然后 npm start
,依然有报错,不过是其他错误了,说明引入图片报错解决了。
看看 react-app-env.d.ts
的代码,ts风格的,声明了各种 图片格式/css/scss 的 module
,结合之前报错说找不到module
,大致能猜出这个文件就是给所有 图片格式/css/scss 文件类型设定模块,以便于能够直接import
。
如果使用 npx create-react-app react-ts --typescript
生成的项目,并且没有 npm run eject
的话,会发现 react-app-env.d.ts 中只有下面一段代码:
/// <reference types="react-scripts" />
但是 npm run eject
后内容就变化了。
首先,需要真的看懂这个文件的语法。
/// <reference types="node" />
涉及到 https://www.tslang.cn/docs/handbook/declaration-files/library-structures.html 中的 依赖全局库declare namespace NodeJS
涉及到 https://www.tslang.cn/docs/handbook/namespaces.html 中的命名空间declare module
以及文件后缀 .d.ts
涉及到 https://www.tslang.cn/docs/handbook/modules.html 中的 外部模块这个主要依赖于webpack的配置了,毕竟是.ts
文件,会被相应的模块加载器解析。
这是个问题。
回答这个问题前,需要看下create-react-app
源码。但是由于是npx
安装的,我在本地竟然没找到create-react-app
,后来在阮一峰老师的文章npx 使用教程中了解到
npx create-react-app my-react-app
运行时,npx
将create-react-app
下载到一个临时目录,使用以后再删除。所以,以后再次执行上面的命令,会重新下载create-react-app
。
额外了解以上知识后,我把create-react-app
clone 到本地,然后浏览它的源码。
先看package.json文件,找到create-react-app
命令,它对应的是"node tasks/cra.js"
,需要去tasks文件夹下找到cra.js。这是该命令的启动文件。
在文件中找到这段代码:
指导我去找create-react-app文件夹下的index.js文件。该文件主要就是下面这段代码:
require('./createReactApp');
需要去createReactApp.js里面看看源码了,里面的代码还是比较多的。大致浏览下,可以看到主要依赖于 createApp
函数构建。
这里的参数 param
是什么?看下图:
其实就是我们输入的命令行参数!!!
// 分析命令行输入
npx create-react-app my-app --typescript
// --typescript参数传入,此时 createApp 中的 useTypescript 为 true,接下来自动去添加相关依赖。
createApp
方法中最后调用了 run
方法,附上代码图:
run
中一开始就调用了getInstallPackage
方法获取依赖,见下图:
可以看到依赖于 react-scripts
包。此时可以去该包下查看。
老规矩,先看 package.json 文件,结果幸福来得太突然!!!
{
"types": "./lib/react-app.d.ts",
}
这个是 模块解析 相关内容:
同时,TypeScript在 package.json里使用字段"types"来表示类似"main"的意义 - 编译器会使用它来找到要使用的"main"定义文件。
确实可以在 lib 文件夹下找到 react-app.d.ts 文件,而且与我拷贝过来的一模一样,所以,压根不是生成的!!!是原先就默认配置好的,然后根据命令行传参来决定是否显示(配置)该文件!!!
react-app.d.ts 文件是默认配置在 react-scripts文件夹下的 lib 文件夹中的,当时用命令行来构建时,会根据是否输入 --typescript
参数来决定是否显示/配置 react-app.d.ts 文件。
学无止境,保持一颗好奇心~
原来的代码:
data.message === 'token expired' || data.message === 'token parse error' && storage.set('userinfo', {})
结果发现,storage死活清除不了,我就奇怪了。然后我在控制台测试:
1 === 1 || 1 === 2 && console.log(111)
// true,然后就没了。。。
我突然想到,是不是要加个括号???
(1 === 1 || 1 === 2) && console.log(111)
// 111
我日,这真的是低级错误啊!!!
1.昨天没学习,罪过。。。
2.今天继续完善引入百度地图需求开发,其中再次用到了<transition>
组件,其实代码是抄的iview源码,iview的Select组件,iview的样式库我还是蛮喜欢的,我觉得比饿了么好看,但是它这个过渡效果我居然又抄失败了,上次把<transition>
对应的css加上就好了,但是这次居然失败了!!!
v-show
来控制显隐的,也就是display
。有点经验的都应该直到display
是没法用transition
的,但我就很奇怪,vue他怎么做到的呢???官方示例来看是伴随着opacity
属性,可是这个iview呢,我加了opacity
也没用啊!!!<transition>
源码,发现它其实也是通过classList
或者setAttribute
去添加属性的。感觉这块知识可以写博客了,先记录这么多吧。最近接手某集团公司养老平台管理系统,该集团还有其他系统,需要和集团下另一个志愿者管理系统联合做单点登录,具体怎么操作另说。
主要两个系统共用一个登录,比如都用志愿者的登录页,志愿者登录后,跳养老系统,在通过养老系统提供一个菜单打开新标签页方式打开志愿者系统首页。
这里我养老系统用了localstorage
,但是志愿者系统用的是sessionstorage
,一开始没在意,但是测试时发现,手动打开新标签页并输入志愿者系统地址时,存在sessionstorage中的token没有了,这我就很奇怪了,我一直以为sessionstorage除了存储时间和localstorage不同外,其他没啥区别的,直到这次问题才让我意识到我用的还不熟,遂百度才了解,具体看下面链接:
https://developer.mozilla.org/zh-CN/docs/Web/API/Window/sessionStorage
1.测试嫌数据多原生的横向滚动条操作不好,让我模拟一个,老实说我内心是拒绝的,但考虑到自己没模拟过,倒不如趁此机会尝试一番,也算是学习了,说实话,不百度的话很难突破,有些知识还是遇到问题并去百度实践才能获得的,今天一直在纠结横向滚动条那个滚动块的宽度问题,直到在:https://www.cnblogs.com/tugenhua0707/p/3462317.html 才获得答案,涨知识了!
1.昨天同事问我有没有快速取类似88,99这种100以内的两位数的第一位数字,我当时只想到截取,后来他想到利用 % 然后再相减,当时觉得这个办法比我的好多了,今早突然想起来好像看过 ~~
这种取反方式,试了下果然可以,明明看过,关键时刻就是掉链子,我太水了。。。
~~(98.15432 / 10) = 9
最近在撸 react+typescript,想利用一个管理系统项目熟悉熟悉这两家伙。但是在环境配置这块就踩了不少坑。
今天主要是解决webpack配置alias
别名的问题。
熟悉vue开发的话,应该都知道vue-cli搭建的项目,会给我们配置好@
别名,@
对标src
路径,用起来还是蛮习惯的,但是create-react-app
搭建的项目并没有给我配置这种别名,为了自己爽,我就尝试手动配置下,结果研究了好一段时间。
首先webpack正常配置别名:
alias: {
'@': path.resolve('src'),
}
然后在ts文件中使用:
import('@/views/login/login')
启动报错!
vscode提示:[ts] 找不到模块“@src/views/login/login”。控制台也是提示@这里有问题。
为啥呢?
遂百度。
各种配置,无解。
但是起码知道这是typescript找不到模块而导致的,遂去查阅配置项:http://json.schemastore.org/tsconfig
网上都说要在tsconfig.json中配置baseUrl
和paths
,这是对的,但是他们的配置的值我不能直接拿来用。
在我项目中baseUrl
这个属性,只能选择src
或者node_modules
,网上很多什么.
之类的都不行,否则直接报错。(详细配置见:https://www.tslang.cn/docs/handbook/module-resolution.html#base-url)
其次,paths
属性值是相对于baseUrl
路径的,既然baseUrl
选择了src
,那么paths
下面的属性值肯定是相对于src
路径来的,如果这里在配置一个src
,那么路径会变成src/src
,那肯定不对的,我需要的是 @代表src路径 ,那么应该这样配置:
"baseUrl": "src",
"paths": {
"@/*": ["*"]
}
这种配置的意思就是 @/*对标src/*路径
。
这样配置,就能满足我的需求了。
form
提交时,如果input
框设置了disabled
,那么不会提交该input
框的值。这个以前真没意识到。。。网上说用readonly
替代,但是我试了下并不符合我的预期,我加了一个<input type="hidden" name="Data[type]" :value="tupe">
(vue)。昨晚帮朋友做的项目要验收,但是本地跑起来登录不进去,报接口504。
关于该项目配置我什么都没改,之前还好好的,也就近几天突然不行了,当时因为前期开发完了,就没管,以为是服务器接口出了问题,直到昨晚,朋友让我换成测试环境的地址试试,我把target
改成测试环境地址,开始报404了,依然不行,但是测试环境的线上系统能正常登陆,这就很奇怪了,说明测试环境地址没问题啊,怎么突然就不行了???
找了一段时间,发现测试环境线上请求登陆地址里面多了个/api
,而本地webpack代理配置里面通过pathRewrite
属性将/api
重写为''了,所以请求地址不对。
这个应该是后端接口突然配置了/api
,不过可能配错了,因为昨晚发现有时候登陆过期,退出重登时有的接口不带/api
,我反映了这个情况,不过由于这个项目原先的开发团队撤出了,朋友也不管,所以这个坑就留下了。
可能为了以后维护谈钱吧,毕竟不是我们开发的项目。
其实是11.15号工作时了解到的内容,但由于当天通宵加班,今天才想起来。
vue
element-ui
...
https://dafrok.github.io/vue-baidu-map/#/
因为涉及到地址查找等服务,肯定需要保留BMap对象,好在提供了ready
方法,文档要看清楚。
我地图就是通过element-ui的popover
组件来做的,由于百度地图提供的search结果面板太丑,也不知道怎么去改了,索性不用,直接利用element-ui的组件。
一开始直接引入dropdown
组件,但是报错,看来这个组件不能直接让我用,然后去element-ui官网上找,发现select
和menu
等都有这种dropdown,但是都有自己的实现,不过我大致看了下源码,要适合我的业务还得改动,考虑到时间问题,我继续浏览,但是突然一想,这个好像还可以在嵌套一层popover
啊,而且popover
也确实提供了手动触发显隐的操作,这样就好办多了
附上代码:
<div class="mb10">
<el-input placeholder="请从地图中选择" v-model="lonAndLat">
<template slot="prepend">经纬度</template>
<el-popover
placement="bottom"
width="500"
slot="append"
trigger="click"
>
<el-button slot="reference" icon="el-icon-location"></el-button>
<div class="flex flex-one mb10 flex-center">
<span>搜索</span>
<el-input class="mapinput flex-one ml10" placeholder="请输入地址"
v-model="searchAddress" v-popover:popover/>
<el-popover
ref="popover"
popper-class="result-popover"
placement="bottom"
width="436"
trigger="manual"
v-model="searchResultVisible"
>
<el-row class="map-result"
v-for="(res, index) in searchResults"
:key="index"
@click.native="handleClickRes(res)"
>
<i class="el-icon-search"></i>
{{res.address}}
</el-row>
</el-popover>
</div>
<baidu-map ref="bmap" class="map"
center="南京" :zoom="14"
:scrollWheelZoom="true"
@ready="handleReady"
@click="handleClick"
>
<bm-navigation anchor="BMAP_ANCHOR_TOP_LEFT"></bm-navigation>
<bm-geolocation anchor="BMAP_ANCHOR_BOTTOM_RIGHT" :showAddressBar="false" :autoLocation="true"></bm-geolocation>
<bm-local-search :keyword="searchAddress" @searchcomplete="handleSearchComplete" :auto-viewport="true" :panel="false"></bm-local-search>
<bm-marker :position="currClickPosition" :dragging="true" animation="BMAP_ANIMATION_BOUNCE"></bm-marker>
</baidu-map>
</el-popover>
</el-input>
</div>
久违的用vue搭个简单后台管理页面,写登录页时发现 登录 二字不等高,立马想到了设置 font-family,但是,这次竟然没用!!!
摸索了下发现浏览器显示依然用的 微软雅黑 渲染的字体,这个字体是 windows 自带的,我家里的组装台式机貌似没有 STSong 这个字体,这就尴尬了。。。
附上 如何优雅的选择字体,顺带贴出 windows默认支持的字体
具体看下图展示:
日常开发中,有发现过网页上汉字不对齐,当时就觉得很奇怪,但是,以前没管那么多,撸就完事了,哈哈。
今天又遇到了,不过现在有时间,得研究下。
遂百度,答案也很简单,是字体问题。。。
可以看这里:https://bbs.csdn.net/topics/391091508
由于我用了antd库,antd内部也对 body 设置了字体等属性,而我本地设置的属性优先级没它高,最直接的方法,把它设置的font-family
复制粘贴到我本地,然后加上 STSong 字体并 !important即可。
看看图例:
2019-11-09补充:
今天水贴时发现了这个:
https://developer.mozilla.org/zh-CN/docs/Web/CSS/font-family
我还真不知道字体知识呢。。。
因业务原因,需要一种组件,既能做到单选同时也能带着复选,选择单选时所有复选框应取消选中,选择复选时单选也要取消选中。
由于项目用到的了element-ui,发现其提供radio-group
和checkbox-group
,同事便将checkbox-group
放在radio-group
中包裹,后来因业务需求,我对该组件做了点更改,然后发现一个以前都没碰到过的bug。具体看图:
如上图,41-49这个el-checkbox
其实是禁用的,但是当我点上去发现包裹该el-checkbox
的el-radio
整个出现了淡蓝色边框,打开控制台始终找不到这个样式来自哪里。
以前我真没碰到过这种情况。无奈,只能求救。同事一看,就知道这是什么原因了,他说这个应该是有tabindex
属性了,然后浏览器自己实现的这种样式,一般用outline: none
就可以解决了。同事果然身经百战!在控制台删除那些tabindex
属性蓝色边框果然消失了。
但是当我们继续看时,发现element-ui早就写上了outline: none
属性,这样就没法子了,后来换了折中办法,用point-events: none
来阻止该禁用按钮的点击事件,果然不会出现淡蓝色边框了,但是,点击该禁用按钮居然把其他被选中的el-checkbox
给取消选中了!!!通过官方提供的change
方法去改变v-model
值的,但是貌似点击此处没有走change
方法,倒是改变了v-model
,着实奇怪,待我明日再研究下。
2019-02-04
最近忙的一笔,几乎天天上班。
那个问题后来偶然间发现了,不是outline: none;
没用,而是element-ui的样式,比较奇怪的是我在控制台上没找到,反倒是发现同事负责的模块里有这个样式,我把它取消掉果然没问题了。
可能是同事负责的地方样式影响到我了。
form
默认是get
提交,我曾经看过,但是真的忘了,还是这两天的一个bug提醒了我。1.今天早上终于把iview的Dropdown
组件动态效果研究出来了,原来他利用了animition
动画以及scaleY和transform-origin。
2.百度地图也让我踩了个大坑,想了两小时呢!起因后台哥们问我要gps的经纬度,我一愣,百度返回的不是吗?
当然不是!!!看:http://lbsyun.baidu.com/index.php?title=coordinate ,尼玛隐藏的太深了,最重要的是小贴士:**互联网地图在国内必须至少使用GCJ02进行首次加密,不允许直接使用WGS84坐标下的地理数据,同时任何坐标系均不可转换为WGS84坐标。**这TM是法律规定的!!!
这几天做两个系统间单点登录,前面谈到sessionstorage的坑,这里再开一篇说下,即使我发现了坑,但改起来还是很烦,因为该系统所有用到sessionstorage的地方,都是直接
sessionStorage.getItem()
它没有统一维护一个sessionStorage对象,以前觉得没什么,但是现在要我改突然发现这样真的很坑,太多了,很不方便。
相反,另一个系统,对localStorage进行了封装,
export const storage = {
set: (key, value) => {
return window.localStorage.setItem(key, JSON.stringify(value))
},
get: (key) => {
return JSON.parse(window.localStorage.getItem(key))
}
}
这样改起来会方便很多。以后还是能统一封装的封装起来吧。
最近一直在忙于公司一个比较重要的广告系统开发,虽然页面看似不多,但是业务却着实复杂。起初看到tencent、toutiao、suning三个平台页面大致一致,只有一些字段不同罢了,当时想的是共用一个vue去做,一开始进展不错,直到开始联调发现不同产品线对应的业务逻辑完全不同,差异非常大,表面上页面很像,但是数据结构等等差异较大,维护起来比较吃力。
然后老大看了我部分代码,立马要求我各个产品线分开写,把完全相同的代码放到mixin里面去,类似但是里面要处理不同的业务逻辑的不要混在一起写,避免业务耦合。
我照着要求去做了,完全相同的代码没多少,抽成一个公共的Mixin,大致类似的方法,但是里面业务逻辑不同的,放到与该产品线对应的mixin里面,这样果然轻松不少,之前写的一大堆判断产品线的代码也全都省了,而且将每个vue基本控制在200行以内,有的300行以内,不像之前动辄500多行,自己看起来都害怕。
当然,最重要的是加注释!!!
总的来说,遇到这种页面看似不多且大致类似的业务时,不能短视,要思考以后的维护以及加新需求等等情况,尽量抽出来不要将业务耦合在一起。以前在小公司做的项目没太多复杂度,也没怎么思考过业务耦合这个问题,这次算是有了个初步接触了。
1.input
框在chrome里有个关于autocomplete
问题,它会有个默认填充功能,这样输入框背景色会变成屎黄色,很难看,解决办法也较简单,autocomplete=off
即可。
2.老项目中既用到了vue也用到了jq。开发时发现,如果css写在<style scoped></style>
内,使用jq的addClass
方法无法改变样式,需要将css写在非scoped
style标签中才行。
3.axios
请求下载报表功能,网上大同小异,但还是踩了坑:
axios.get()
方法,但是死活不行,百度发现人家这样写axios({method: get, url: 拼接的url, responseType: 'blob'})
,但是由于我不想用这么low的拼接方法,然后用了官方提供的axios.get(url, {params: 数据})
,但是乱码,百度说要加上responseType:'blob'
,可我不知道在哪里加,最后试了下,下面写法就好了。this.$http.get('downloadReport', {params: this.handleData, responseType:'blob'}).then((res) => {
if (!res) {
return
}
let fileName = res.headers['content-disposition'].split('=')[1]
let url = window.URL.createObjectURL(res.data)
let link = document.createElement('a')
link.style.display = 'none'
link.href = url
link.setAttribute('download', `${fileName}`)
document.body.appendChild(link)
link.click()
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.