打开“八股”的正确方式探索01
事情起源于5月20日一个平平无奇的下午,笔者作为一个菜鸟新手前端勇敢地参加了腾讯前端实习生的一个部门一面。
虽然秒挂,但是腾讯小哥给了自己很多真诚的建议(真的非常真诚!),其中包括八股如何结合项目理解的打开方式,于是笔者决定雄赳赳气昂昂地从头开始认识八股,并记录下自己学习的过程和一些心得。
时间记录:2024.5.22
放一下“八股”学习链接:严正声明 (yuque.com)
从打开项目和目标页面开始……
Q1:localhost 和 ip 地址和 http://0.0.0.0:7100/ 打开的区别?
米小芽同学在使用npm打开项目时遇到了一个神奇的情况,项目直接点击http://0.0.0.0:7100/ 时项目打开失败了!?
但是将其改为http://localhost:7100/却可以打开,有时甚至需要在cmd界面通过ipconfig命令查询自己的ip地址(即无线局域网适配器WLAN目录下的本地链接IPv6地址中一串192开头的数字,有时是IPv4地址),那么,他们有什么区别呢?
1. 重新认识IP地址
(1)ip地址
当我们访问一个网站例如平时对域名如百度的www.baidu.com的访问,本质就是对域名所绑定的IP地址的访问。而IP地址就是我们在网络世界中的地址坐标,即网络中的地址,我们用二进制数字将其表示。
IP地址的世界分为公有IP地址和私有IP地址,他们最大的区别在于共有IP地址由Inter NIC(因特网信息中心)负责,全球唯一;私有IP地址是非注册地址,不能与Internet连接,且不同局域网内ip地址可重复,最终使用路由器中的公网ip连接外网。
(2)IPv4地址/IPv6地址
那么,什么是IPv4地址/IPv6地址嘞?
IP指的是网际协议,是 tcp/ip 协议体系两个最主要协议之一。互联网通过很多中间设备连接起来,他们实际的物理地址是难以协调统一的,但使用相同的网际协议ip忽略不同网络的异构性,便可以形成虚拟的互联网络。
IPv4是32位,即给每台连接互联网的机器分配一个唯一的标识,那么显而易见的是,IPv4总共可以分配2的32次方个地址,IPv6就是IPv4的地址不够分了,需要更多的位数(2的64次)。
(3)172.0.0.1 和 192.168.0.0
在私有ip地址中范围如下:
- A类IP地址中:10.0.0.0--10.255.255.255(ZF或大型企业)
- B类IP地址中:172.16.0.0--172.31.255.255(中等规模公司)
- C类IP地址中:192.168.0.0--192.168.255.255(小公司或个人)
- 还有D类(组播),E类(保留)
因此,172开头的网址是B类网址,192开头的是C类网址。
放结论:他们都是私有地址 不能在外网使用 只不过根据局域网的规模选择不同类别的地址
但也有区别:凡是以127开头的IP地址都是回环地址,其所在回环接口一般被理解为虚拟网卡而不是真实的路由接口;且172开头这种一般不被当作本机IP。
2. 神奇的http://0.0.0.0:7100/
0.0.0.0是不能被ping通的。他被称为“unspecified”,即未指定(即无效的,无意义的)地址。
在服务器中,0.0.0.0并不是一个真实的的IP地址,它表示本机中所有的IPV4地址。服务器不指定在哪个网卡上监听时,也使用0.0.0.0,这个时候监听本机中所有IP的端口。
3. 非常好用的localhost
使用localhost时比起直接使用IP地址多一个DNS解析过程,系统会通过DNS(域名系统)解析来将其转换为相应的IP地址。一般情况下,这个过程很快,因为大多数操作系统都会在本地的hosts文件中对localhost进行映射,使其指向127.0.0.1或类似的环回地址。
值得一提的是,使用localhost可能会引入微小的延迟,因为需要经过DNS解析的过程。127.0.0.1则可以省略这一步骤,稍微提升效率。
但是,localhost在IPv6中通常解析为::1(在IPv4时被指向127.0.0.1),这是IPv6下的环回地址。直接使用IP地址无法利用IPv6的优势,因此在IPv6优先的网络环境中,推荐使用localhost。
Q2:Vue-router——神奇的路由操作如何实现?
通过修改访问的ip地址,米小芽同学顺利地打开了项目!但是,由于公司该业务项目是内嵌APP操作,每一个Vue组件之间都是独立的,米小芽同学不得不开始学习如何善用 vue-router 进行灵活地页面跳转,那么,关于Vue-router有哪些知识点呢?
1. 创建路由并实现懒加载
const List = () => import('@/components/list.vue')
const router = new VueRouter({
routes: [
{ path: '/list', component: List }
]
})
相比起简洁的八股,公司真实的项目路由是很长很长的一大坨!
const routes = [
{
path: '/releaseServe',
component: () => import('./subpages/releaseServe/index.vue'),
name: 'releaseServe',
meta: {
title: '发布服务'
}
},
]
可以发现,路由懒加载的关键便在于使用箭头函数+import动态加载的语句,当然,也可以使用箭头函数+require动态加载
component: resolve => require(['@/components/list'], resolve)
还有一个不太看得明白的方案:使用webpack的require.ensure技术,也可以实现按需加载。 这种情况下,多个路由指定相同的chunkName,会合并打包成一个js文件。
// r就是resolve
const List = r => require.ensure([], () => r(require('@/components/list')), 'list');
// 路由也是正常的写法 这种是官方推荐的写的 按模块划分懒加载
const router = new Router({
routes: [
{
path: '/list',
component: List,
name: 'list'
}
]
}))
遗留问题:
秉承着不懂就要问的优良品质,米小芽还想知道
① 方案三中使用webpack的require.ensure技术原理
② require动态加载和import动态加载的区别
但察觉到里面要素过多,先跳过。
2. 神奇的#从哪里来——hash和history模式
米小芽发现项目的网址是http://localhost:7100/#/Home,通过查阅资料,她发现小小的#号大有来头!原来这与Vue-Router 默认的hash模式有关系。
对于单页面而言,路由需要实现 浏览器刷新时根据url变化动态切换页面 的功能,此时,利用JS事件监听URL变化就分为了两种模式,即hash和histo模式。
(1)hash模式(也叫前端路由)
① 原理:通过监听浏览器url上的hash值,切换浏览器对应的界面。
监听事件的方法是使用浏览器事件 onhashchange 事件监听 url(window.location.hash ) 变化,只要hsah变化,都会触发onhashchange事件。
window.onhashchange = function(event){
console.log(event.oldURL, event.newURL);
let hash = location.hash.slice(1);
}
使用监听事件的好处:在页面的hash值发生变化时,无需向后端发起请求,window就可以监听事件的改变,并按规则加载相应的代码。
除此之外,hash值变化对应的URL都会被浏览器记录下来,这样浏览器就能实现页面的前进和后退。虽然是没有请求后端服务器,但是页面的hash值和对应的URL关联起来了。
② 特点和相关知识点
- hash值指的是地址中 # 号以及后面的字符,也称作锚点或散列值;
- hash值不会发到服务器,改变hash值浏览器不会重新加载(原因:hash值会出现在URL里面,但是不会出现在HTTP请求中,对后端完全没有影响);
- location.hash值的变化会直接反映到浏览器地址栏。
(2)history 模式
① 原理:利用H5的 history中新增的两个API ,pushState() 和 replaceState() 和一个事件onpopstate监听URL变化。(使用了传统的路由分发模式,用户输入->服务器接受请求->服务器解析请求并处理)
② 特点和相关知识点
- 没有#号,比如说我的学习链接 www.yuque.com/cuggz/inter… ,但是需要后台配置,并且因为自由修改path是直接请求服务器,所以很容易刷新后服务器没有相应的资源/相应,刷出404。
- 对应了一些属性和方法参考↓
(3)比较history和hash模式
PS:除此之外,还有一个用于非浏览器的 abstract 模式。
样式修改从入门到入土……
Q1:到底应该选择那个响应式布局方案?!
米小芽同学顺利创建好路由并新建了一个页面,现在要开始画出这个页面了!
经过米小芽的一番操作,她顺利地放好了背景图,前景图和图文框,其中遇到了背景覆盖(用z-index解决)、背景图未跟随页面拉伸(关闭overflow属性和height相关属性)、元素混乱(使用flex布局拨乱反正!)等问题……米小芽感到了痛苦,虽然已经知道了不同自适应单位的定义,但是,到底应该选择哪个响应式布局方案?!
1. 为什么不可以无脑冲px
CSS像素 = 物理像素/分辨率
当我们设置布局视口为理想视口(理想视口或者说分辨率就是给定设备物理像素的情况下,最佳的“布局视口”。)时,CSS像素计算公式如上。
因此,当设备不同时,会导致物理像素的不同,无法实现各端自适应。
2. 方案一:媒体查询法
使用 @media 查询,可以针对不同的媒体类型定义不同的样式。
@media screen and (max-width: 960px){
body{
background-color:#FF6699
}
}
@media screen or (max-width: 768px){
body{
background-color:#00FF66;
}
}
通过媒体查询,可以通过给不同分辨率的设备编写不同的样式来实现响应式的布局,比如我们为不同分辨率的屏幕,设置不同的背景图片。比如给小屏幕手机设置@2x图,为大屏幕手机设置@3x图,通过媒体查询就能很方便的实现。
但是媒体查询的缺点也很明显,如果在浏览器大小改变时,需要改变的样式太多,那么多套样式代码会很繁琐。
3. 方案二:使用百分比
百分比的对应关系 ↓
缺点:① 计算困难,比如说米小芽同学偷工减料使用肉眼观察法计算比例为40%,被明察秋毫的前端小姐姐计算后发现其实应该是42%…囧
② 父元素不唯一,导致改动大小时很有可能 “牵一发而动全身”。(反面案例:米小芽在遇到这个问题后为了不改动太多不得不将百分比和rem单位混合了起来用…)
4. 方案三:rem解决方案
rem单位无论嵌套层级如何,都只相对于浏览器的根元素(HTML元素)的font-size,由浏览器转化像素并显示。(有一个小弟em,只相对当前对象内文本的字体尺寸,若未设置则相对浏览器默认字体尺寸)
缺陷:在响应式布局中,必须通过js来动态控制根元素font-size的大小, 且必须将改变font-size的代码放在css样式前。
5. 方案四:vw/vh 实现
vw等单位的含义 ↓
该单位有点类似于百分比,不过比百分比更好用!1vh = 视图高度的百分之一
总结
经过又一次学习,米小芽并没有找到能够 “绝对好用” 的响应式布局,也许这是一个需要经验和实践的活?
今天主要学习/复习了关于路由、地址、响应式布局的部分内容。目前感觉,结合项目一步步找问题确实比直接背更有意思?(但是进度好慢啊好慢啊好慢啊好慢啊好慢……我是急急急急急急急急急急急急国王qwq)
得,一步一步来吧。(欢迎食用 and 批评指正!罒▽罒)