4.26前端笔记

小盒子在一个大盒子中实现垂直和水平居中(六种方法)

小盒子在一个大盒子中实现垂直和水平居中(六种方法)_wuliuqi62的博客-CSDN博客_小盒子在大盒子里水平垂直居中

Web前端常用布局方式

布局方式
一、静态布局
静态布局是最为原始的布局方式,没有什么技术性可言,往往是计算机行业刚刚入门的小白使用的布局方式。制作的网页上的元素尺寸一律以px为单位。

.bor{
	width: 360px;
	height: 255px;
	border: 1px solid black;
	margin-bottom: 30px;
}
.bor p{
	color: #000000;
	font-size: 16px;
}
.border-pic{
	width: 360px;
	height: 255px;
	margin-left: 10px;
	margin-top: 10px;
	overflow: hidden;
}
.border-pic img{
	width: 360px;
	height: 255px;
}


布局特点: 页面上的布局是按最初写代码时候的布局方式进行布局的,常规的pc网站是进行设置了宽度值进行布局的,不会随着pc端的屏幕的大小而变化。
优点: 这种布局方式不管是对资深的前端开发工程师还是刚入门的小白来说都是最简单的,最让人容易以接受、学习的,没有我们所说的兼容性的问题。这种布局方式大多用在门户网站和企业的官网上,这些官网的设备的尺寸是固定的,这种布局方式往往是最简单的方法。
缺点: 不会随着pc端的屏幕大小而变化。

二、弹性布局(flexbox)
弹性布局可以简便、完整、响应的实现各种页面上的布局。与静态不同的是,使用em或rem单位(lem=16px,1rem=10px)进行相对布局,相对使用百分比更加方便、灵活,相应同时支持浏览器的字体大小调整和缩放的等正常显示。
优点:
1.适应性强,在做多种不同的屏幕分辨率不同的界面是非常使用。
2.随意按照宽度、比例划分元素的宽高。
3.可以轻松的改变元素的显示顺序。
4.网页布局实现快捷,维护起来更加容易。
如果做移动端时,如果客户对细微的之处的要求不高,使用弹性布局进行制作是最好的选择,一份css+一份js调节font-size搞定。
缺点: 浏览器兼容性较差,只能兼容到IE9及以上。

三、自适应布局(bootstrap)
自适应布局分别为不同屏幕不同分辨率定义布局,即是创建多个静态页面,每个静态页面对应一个屏幕分辨率的一个范围内。在改变不同的屏幕分辨率可以切换到不同的静态布局上,但是布局中的元素位置会发生改变,但是在每个静态布局中,页面中的元素不会随着窗口大小的调整发生变化。使用 @media 媒体查询给不同尺寸和介质的设备切换不同的样式。在优秀的响应范围设计下可以给适配范围内的设备最好的体验,在同一个设备下实际还是固定的布局。
优点:
1.对网站的复杂程度兼容性更大;
2.对开发工程师来说制作的成本代价更低;
3.代码执行效果更高效;
4.测试时更加容易,运营相对更加精准。
缺点: 在现如今的移动端设计百花齐放的时期之下,同一个网站往往需要为不同的设备制作不同的页面,不但会增加开发成本,还会因为客户的需求改变时,可能会改动多套代码、流程相比较来说较繁琐。

四、流式布局(fluid)
流式布局的布局方式是页面的元素的宽度按照屏幕的分辨率进行适配的调整,但是整体布局不变,也称之为栅栏系统。使用%百分比定义宽度,高度大都是用px来固定住,可以根据可视区域 (viewport) 和父元素的实时尺寸进行调整,尽可能的适应各种分辨率。往往配合 max-width/min-width 等属性控制尺寸流动范围以免过大或者过小影响阅读。
缺点: 屏幕大小变化时,页面元素也随之变化但是布局不变。这就会因为如果屏幕太大或太小都会布局时元素无法正常显示。

五、响应式布局
响应式布局是css3增加的新布局方式,该布局方式2010年提出来的一个概念,说白了就是一个网站能够兼容多个终端——而不是为每个终端做一个特定的版本。这个概念是为解决移动互联网浏览而诞生的。响应式布局可以为不同终端的用户提供更加舒适的界面和更好的用户体验,而且随着目前大屏幕移动设备的普及,用“大势所趋”来形容也不为过。响应式几乎成为优秀页面布局的标准。
设计方法: 媒体查询+流式布局。通常使用@media媒体查询,和网格系统配合相对布局单位进行布局,实际上说白了就是综合响应式等技术通过css给单一网页不同设备分辨率返回不式时的技术。
优点: 适应pc端和移动端,如果有足够的耐心,页面效果会很完美。
缺点:
1.只能适应主流的宽高;
2.如果匹配足够多的设备屏幕的大小,对于工程师来说工作量不小,设计更需要多个版本,工作量增大。

六、浮动布局
浮动布局进行调用浮动属性改变页面中元素的位置,浮动布局应该是目前各大网站用的最多的一种布局方式了,但是也特别复杂。浮动元素是脱离文档流的,但不脱离文本流。浮动元素有左浮动(float : left)和右浮动(float : right)两种

.lian{
	width: 90%;
	padding-left: 5%;
}
.lian img{
	float: right;
	margin-top: -180px;
}
.phone ul li{
	list-style: none;
    margin-top: 50px;
    margin-left: 70px;
    color: #808080;
}
.phone ul li img{
	position: absolute;
	margin-left: -80px;
	float: left;
	margin-top: -5px;
}
.view{
	margin-top: 50px;
	margin-left: -5px;
	float: left;
}
.view input{
	width: 120px;
	height: 40px;
	border-radius: 6px;
	border: 1px solid #3CB371;
	background-color: #3CB371;
	font-size: 16px;
	color: white;


优点: 兼容性比较好
缺点: 浮动带来的影响比较多,页面宽度不够的时候会影响布局。

七、定位布局
定位布局时利用position属性控制页面元素设置一些不规则布局。
定位元素的各个属性:
1.static 静态定位: HTML元素的默认值,即没有定位,元素出现在正常的流中。

div.static {
    position: static;
    border: 3px solid #73AD21;
}


2.fixed 固定定位: 元素的位置相对于浏览器窗口是固定位置。即使窗口是滚动的它也不会移动。Fixed定位使元素的位置与文档流无关,因此不占据空间。Fixed定位的元素和其他元素重叠。

p.pos_fixed{
    position:fixed;
    top:30px;
    right:5px;
}


3.relative 相对定位: 相对定位元素的定位是以自身为参照物。对象不可层叠、不脱离文档流,移动相对定位元素,但它原本所占的空间不会改变。通过 top,bottom,left,right 定位。

p.pos_fixed{
    position:fixed;
    top:30px;
    right:5px;
}


4.absolute 绝对定位 absolute 定位使元素的位置与文档流无关,因此不占据空间。元素和其他元素重叠。通过 top,bottom,left,right 定位。选取其最近一个最有定位设置的父级对象进行绝对定位,如果对象的父级没有设置定位属性,absolute元素将以body坐标原点进行定位。

h2{
    position:absolute;
    left:100px;
    top:150px;
}


5.sticky 粘性定位 基于用户的滚动位置来定位。粘性定位的元素是依赖于用户的滚动,在 position:relative 与 position:fixed 定位之间切换。它的行为就像 position:relative; 而当页面滚动超出目标区域时,它的表现就像 position:fixed,它会固定在目标位置。元素定位表现为在跨越特定阈值前为相对定位,之后为固定定位。这个特定阈值指的是 top, right, bottom 或 left 之一,换言之,指定 top, right, bottom 或 left 四个阈值其中之一,才可使粘性定位生效。否则其行为与相对定位相同。

div.sticky {
    position: -webkit-sticky; /* Safari */
    position: sticky;
    top: 0;
    background-color: green;
    border: 2px solid #4CAF50;
}


6.z-index 因为页面中元素的定位与文档流无关,所以定位的元素可以覆盖在文档流上面。所以z-index属性指定了一个元素的堆叠顺序(哪个元素应该放在前面/后面)。z-index的值必须取正整数,数值越大显示的优先级就越高。 如果两个定位元素重叠,而且还没有指定z - index,name最后定位在HTML代码中的元素将被显示在最前面。

ES6相比ES5有哪些优点?

  • 新增变量声明关键字let, const, 多了块级作用域概念
  • 变量的解构赋值, 扩展运算符
  • 字符串, 数组, 对象, 正则, 数值, 函数等都进行了扩展, 增强操作简便性
  • 新增一个数据类型Symbol, 可以解决名称冲突问题
  • 新增Set和Map数据结构
  • 增加了Proxy和Reflect, 对语言本身进行了规范和扩展
  • 标准化了异步解决方案Promise, 统一了语法, 原生提供了Promise对象
  • 提供了迭代器和生成器及可迭代协议, 可以用来实现数据结构的迭代. 生成器与异步操作结合, 使得可以使用同步代码的书写方式实现异步功能
  • 语言标准层面上, 实现了模块功能, 使得它成为了浏览器端和服务端通用的模块解决方案.

前端存储主要有哪些方式,有什么区别(sessionStorage,localStorage,cookie)

1.localStorage

1.存储时间是永久存储。
2.大小在5M左右。
3.ie低版本或者一些使用无痕浏览器都是不支持的
4.存储的是字符串,内容过多时,会消耗内存空间,让页面变卡
5.本地存储,不会和服务器有交互
代码:

// 使用方法存储数据
localStorage.setItem("name", "Srtian")
// 使用属性存储数据
localStorage.say = "Hello world"
// 使用方法读取数据
const name = localStorage.getItem("name")
// 使用属性读取数据
const say = localStorage.say
// 删除数据
localStorage.removeItem("name")

2.sessionStorage

大致跟localStorage一样
区别:不是永久存储,一旦浏览器的窗口关闭,也随之清除
//  使用方法存储数据
sessionStorage.setItem("ifClick", "true");

//  使用属性存储数据
sessionStorage.ifClick = "true";

3.cookie

优点:
1.存储时间可以根据存储得规则无限期得存储。
2.Cookie的兼容性非常的好。
缺点:
1.大小被限制:一般每个域只能存储20个左右,每个cookie大小在4k左右,
2.cookie要往返与客户端和服务端,会浪费不必要的资源
代码:

function setCookie(cname, cvalue, exdays) {
            var d = new Date();
            d.setTime(d.getTime() + (exdays * 24 * 60 * 60 * 1000));
            var expires = "expires=" + d.toUTCString();
         document.cookie = cname + "=" + cvalue + "; " + expires+"; path=/"   
         //这个很重要代表在那个层级下可以访问cookie
            console.log(d)
        }
//获取cookie
    function getCookie(cname) {
        var name = cname + "=";
        var ca = document.cookie.split(';');
        for(var i = 0; i < ca.length; i++) {
            var c = ca[i];
            while(c.charAt(0) == ' ') c = c.substring(1);
            if(c.indexOf(name) != -1) return c.substring(name.length, c.length);
        }
        return "";
    }
  //删除 cookie
    function clearCookie(name) {
        setCookie(name, "", -1);
    }

什么是深浅拷贝?如何实现深浅拷贝

浅拷贝就是通过赋值的方式进行拷贝,那为什么说这是浅拷贝呢?就是因为赋值的方式只会把对象的表层赋值给一个新的对象,如果里面有属性值为数组或者对象的属性,那么就只会拷贝到该属性在栈空间的指针地址,新对象的这些属性数据就会跟旧对象公用一份,也就是说两个地址指向同一份数据,一个改变就会都改变。

let person = {
  uname: '张三',
  age: 22,
  sex: '男',
  arr: ['小明', '大大', '小小'],
  obj: {
    index: 1,
    name: '三和'
  },
  say: function () {
    console.log('hello javascript')
  }
}
let son = { ...person }
person.arr.push('小王')
console.log(son)
console.log(person)

 控制台打印结果

一个对象的属性是引用类型,那么改变该属性值里面的内容,另外的拷贝对象也会改变,因此这种拷贝是浅拷贝 

深拷贝则不会出现上述问题,引用数据类型,地址跟数据都会拷贝出来。

深拷贝

1.通过递归函数来实现深拷贝

let person = {
  uname: '张三',
  age: 22,
  sex: '男',
  arr: ['小明', '大大', '小小'],
  obj: {
    index: 1,
    name: '三和'
  },
  say: function () {
    console.log('hello javascript')
  }
}
let son = {}

function myCopy(newObj, obj) {
  for(let key in obj) {
    if (obj[key] instanceof Array) {
      newObj[key] = []
      myCopy(newObj[key], obj[key])
    } else if (obj[key] instanceof Object) {
      newObj[key] = {}
      myCopy(newObj[key], obj[key])
    } else {
      newObj[key] = obj[key]
    }
  }
}

// 调用递归函数
myCopy(son, person)

person.arr.push('小王')
console.log(son)
console.log(person)

控制台打印结果

 2.通过 json 反序列化实现深拷贝

let person = {
  uname: '张三',
  age: 22,
  sex: '男',
  arr: ['小明', '大大', '小小'],
  obj: {
    index: 1,
    name: '三和'
  },
  say: function () {
    console.log('hello javascript')
  }
}

function myCopy(obj) {
  let _obj = JSON.stringify(obj)
  let newObj = JSON.parse(_obj)
  return newObj
}

let son = myCopy(person)

person.arr.push('小王')
console.log(son)
console.log(person)

控制台打印结果

 

3.通过 jQuery 封装的方法($.extend())实现深拷贝

必须先引入 jQuery
第一个参数必须是 true

 

let person = {
  uname: '张三',
  age: 22,
  sex: '男',
  arr: ['小明', '大大', '小小'],
  obj: {
    index: 1,
    name: '三和'
  },
  say: function () {
    console.log('hello javascript')
  }
}

let son = {}

$.extend(true, son, person) // 通过 $.extend() 方法实现深拷贝
// 第一个参数必须是 true

person.arr.push('小王')
console.log(son)
console.log(person)

控制台打印结果

 从三种深拷贝的方法打印结果中可以发现一个问题,那就是在三个 person 对象中,都定义了一个 say 方法,前两种拷贝方法,都无法拷贝对象里面的方法,第三种方法却可以,所以使用的时候应该考虑到这个因素

遍历数组的常用方法

遍历数组的常用方法:

一、利用for循环遍历

可以不用重复获取数组长度,提高效率,数组特别大时效果比较明显

for (var i = 0; i < arr.length; i++) {
 	//code
}


二、利用foreach遍历(没有返回值,对原数组没有影响)

arr.forEach((item,index,array)=>{
    //code
})
//arr数组有几项,箭头函数就会执行几次,code就会执行几次
//item是遍历数组的当前项, index是当前项的索引, array是原数组;


三、利用map遍历(有返回值,对原数组没有影响)

把原数组的每一项都修改了,返回一个新数组,不会改变原数组
 

arr.map(function(item,index,array){
     //code 
  return item*2; 
})

var arr = [1,2,3,4,5]; 
var arrSecond= ary.map(function (item,index,array) { 
    return item*2; 
}) 
或者var arrSecond= ary.map((item) => item*2) 
console.log(arrSecond);  //[2,4,6,8,10]

改变this指向的三个方法的用法及区别

call,apply和bind

作用:改变this的指向

function Person(age) {
    this.age = age;
}

var obj = {};
// Person();
Person.call(obj, 18);
// 这两种执行是一样的,准确来说,上面的那种执行实际上就是下面的那种执行
// 在call传入obj会让Person里面的this全部替换成obj,相当于在最初的时候,Person里面的this全部指向window,现在都有了新的地址,就是obj的,从第二开始传参

本质的一个表现是借用别人的函数实现自己的功能,就像下面的这个例子一样,Student涵盖了Person的全部内容,所以可以这样使用

        function Person(name, age, sex) {
            this.name = name;
            this.age = age;
            this.sex = sex;
        }
        function Student(name, age, sex, tel, grade){
//          var this = {name : "", age : "", sex : ""}
            Person.call(this, name, age, sex);
            this.tel = tel;
            this.grade = grade;
        }

apply和call差不多
不同点:
call传参是按顺序一个一个传,而apply里面只能传一个,而且得是数组,就是直接传一个实参列表,如下

    Person.apply(this,[name, age, sex]);

对于以上两个来说,除了改变this指向,还有一个功能是让函数自动执行

第三个方法bind,传参方法和call一样,但是bind的返回值是一个新函数,而且需要手动调用,不会自动执行

简单来说就是bind就是要重新调用一下返回的新函数,他相比call就多了这一个功能
例子如下,

    window.color = 'red';
    var obj = {
        color : 'blue'
    }
    function test() {
        console.log(this.color);
    }
    var newTest = test.bind(obj);
    newTest();//blue
btn.onclick = function () {
    this.disabled = true;
    setTimeout(function () {//this指向window
        this.disabled = false; 
    }.bind(this) ,3000)//bind里面的this指向btn
}

call,apply和bind的主要应用场景

  1. call常用做继承
  2. apply经常和数组有关系,比如想使用Math里面的函数
  3. bind不调用函数,但还想改变this指向,比如在定时器里面改变this指向

 Vue生命周期总共分为几个阶段?

Vue实例从创建到销毁的过程,就是生命周期。也就是从开始创建、初始化数据、编译模板、挂载 Dom→渲染、更新→渲染、卸载等一系列过程,我们称这是Vue的生命周期。

1、beforeCreate

在实例初始化之后,数据观测(data observer)和event/watcher事件配置之前被调用

2、created

在实例创建完成后被立即调用。在这一步,实例已完成以下的配置:数据观测 (data observer)属性和方法的运算,watch/event 事件回调。然而,挂载阶段还没开始,$el属性目前不可见

3、beforeMount

在挂载开始之前被调用:相关的render函数首次被调用

4、mounted

el被新创建的vm.$el替换,并挂载到实例上去之后调用该钩子,如果root实例挂载了一个文档内元素,当mounted被调用时vm.$el也在文档内

5、beforeUpdate

数据更新时调用,发生在虚拟 DOM 打补丁之前。这里适合在更新之前访问现有的DOM,比如手动移除已添加的事件监听器,该钩子在服务器端渲染期间不被调用,因为只有初次渲染会在服务端进行

6、updated

由于数据更改导致的虚拟 DOM 重新渲染和打补丁,在这之后会调用该钩子

7、activated

keep-alive 组件激活时调用。该钩子在服务器端渲染期间不被调用

8、deactivated

keep-alive 组件停用时调用。该钩子在服务器端渲染期间不被调用

9、beforeDestroy

实例销毁之前调用。在这一步,实例仍然完全可用。该钩子在服务器端渲染期间不被调用

10、destroyed(销毁后)

Vue 实例销毁后调用。调用后,Vue 实例指示的所有东西都会解绑定,所有的事件监听器会被移除,所有的子实例也会被销毁。该钩子在服务器端渲染期间不被调用

11、errorCaptured(2.5.0+ 新增)

当捕获一个来自子孙组件的错误时被调用。此钩子会收到三个参数:错误对象、发生错误的组件实例以及一个包含错误来源信息的字符串,此钩子可以返回false以阻止该错误继续向上传播

 vue actived生命周期---解决进入页面不会再次调用接口请求

created:在模板渲染成html之前调用,即通常初始化某些属性值,然后再渲染成视图;但是注意,只会触发一次

mounted:在渲染成html之后调用,通常是初始化页面完成后,再对html的dom节点进行一些需要的操作。是挂载vue实例后的钩子函数,钩子在主页挂载时执行一次,如果没有缓存的话,再次回到主页时,此函数还会执行。

activated:是组件被激活后的钩子函数,每次回到页面都会执行

执行顺序:created => mounted => activated

 created:html加载完成之前,执行。执行顺序:父组件-子组件
mounted:html加载完成后执行。执行顺序:子组件-父组件
methods:事件方法执行
watch:watch是去监听一个值的变化,然后执行相对应的函数。
computed:computed是计算属性,也就是依赖其它的属性计算所得出最后的值
created和mounted区别

created:在模板渲染成html前调用,即通常初始化某些属性值,然后再渲染成视图。

mounted:在模板渲染成html后调用,通常是初始化页面完成后,再对html的dom节点进行一些需要的操作。

 vue2和vue3区别

1. vue2和vue3双向数据绑定原理发生了改变
vue2的双向数据绑定是利用了es5 的一个API Object.definepropert() 对数据进行劫持 结合发布订阅模式来实现的。vue3中使用了es6的proxyAPI对数据进行处理。
相比与vue2,使用proxy API 优势有:defineProperty只能监听某个属性,不能对全对象进行监听;可以省去for in 、闭包等内容来提升效率(直接绑定整个对象即可);可以监听数组,不用再去单独的对数组做特异性操作,vue3可以检测到数组内部数据的变化。
2.Vue3支持碎片(Fragments)
就是说可以拥有多个跟节点。
3. Composition API
Vue2 与vue3 最大的区别是vue2使用选项类型api,对比vue3合成型api。旧得选项型api在代码里分割了不同得属性:data,computed,methods等;新得合成型api能让我们使用方法来分割,相比于旧的API使用属性来分组,这样代码会更加简便和整洁。

4. 建立数据data
vue2是把数据放入data中,vue3就需要使用一个新的setup()方法,此方法在组件初始化构造得时候触发。使用一下三个步骤来简=建立反应性数据: 1. 从vue引入reactive;使用reactive() 方法来声明数据为响应性数据;3. 使用setup()方法来返回我们得响应性数据,从而template可以获取这些响应性数据。
5. 生命周期

vue2     --------------- vue3
beforeCreate                         ->   setup()
Created                                 ->   setup()
beforeMount                          ->   onBeforeMount
mounted                                ->    onMounted
beforeUpdate                        ->    onBeforeUpdate
updated                                 ->    onUpdated
beforeDestroyed                    ->    onBeforeUnmount
destroyed                              ->     onUnmounted
activated                                ->     onActivated
deactivated                            ->     onDeactivated


6. 父子传参不同,setup()函数特性
setup()函数接收两个参数:props、context(包含attrs、slots、emit)
setup函数是处于生命周期beforeCreated和created俩个钩子函数之前
执行setup时,组件实例尚未被创建(在setup()内部,this不会是该活跃实例得引用,即不指向vue实例,Vue为了避免我们错误得使用,直接将setup函数中得this修改成了undefined)
与模板一起使用时,需要返回一个对象
因为setup函数中,props是响应式得,当传入新的prop时,它将会被更新,所以不能使用es6解构,因为它会消除prop得响应性,如需解构prop,可以通过使用setup函数中得toRefs来完成此操作。
父传子,用props,子传父用事件 Emitting Events。在vue2中,会调用this$emit然后传入事件名和对象;在vue3中得setup()中得第二个参数content对象中就有emit,那么我们只要在setup()接收第二个参数中使用分解对象法取出emit就可以在setup方法中随意使用了。
在setup()内使用响应式数据时,需要通过 .value 获取

import { ref } from 'vue'
const count = ref(0)
console.log(count.value)


从setup() 中返回得对象上得property 返回并可以在模板中被访问时,它将自动展开为内部值。不需要在模板中追加.value。
setup函数只能是同步的不能是异步的。

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值