web前端巨无霸长文-持续更新2021-10-13(1.6w+字)

前端巨无霸长文-持续更新

  • 一,界面构建相关
    • 1,浏览器渲染机制
      • 浏览器渲染原理
      • JS加载与执行机制
      • defer 和async 属性的区别
    • 2,HTML
      • HTML行内元素与块级元素
      • HTML5特性
        • 标签语义化
        • 多媒体播放
        • 新增表单控件
        • 新增技术Webwork
        • 新增技术Websocket
        • 本地离线存储localStorage
    • 3,CSS
      • 盒模型
      • 引入样式时,使用link和@import有什么区别
      • CSS选择器优先级
      • 伪元素和伪类的区别
      • CSS3特性
        • 盒子阴影
        • 新增选择器
          • 属性选择器:elem[property]
          • 结构伪选择器
          • 伪元素选择器
        • 圆角
        • 2D转换
        • 动画
        • 3D转换
    • 4,常见页面布局操作
      • 三栏式布局
        • float布局
        • 绝对定位布局
        • flex布局
      • 水平垂直居中
        • 定位 + 负margin
        • 定位 + auto margin
        • 定位 + transfrom
        • 定位 + calc
        • 通过flex
      • CSS画一个三角形和箭头
      • 超出内容显示省略号
      • 轮播图的实现
  • 二,JS相关
    • JS基础概念
      • EventLoop事件循环机制
      • this指向
      • 作用域链
      • 词法作用域
      • 闭包
      • new关键之的实现原理
      • 原型以及原型链
      • call方法实现原理
    • 防抖节流
    • JS算法
      • 冒泡排序法
  • 三,前端框架相关
    • 1,Vue
      • 双向数据绑定原理
      • 响应式原理
      • 父子组件之间的传值
        • 父组件传值给子组件
        • 子组件传值给父组件
      • 非父子组件之间的传值
        • bus模式/总线模式
      • vuex
      • 生命周期
      • $nextTick
  • 四,其他知识总结
    • 浏览器
      • Cookie、Session、Token
      • 常见浏览器所用内核
    • 程序、进程、线程
    • 数据通讯

一,界面构建相关

1,浏览器渲染机制

浏览器渲染原理

1,将HTML解析成DOM树
2,将CSS解析成CSSOM树
3,将DOM和CSSOM树合并后生产Render树(渲染树);
4,Layout(布局),计算节点的位置;
5,Paint(绘制),将布局绘制在屏幕上;
注意:
重排即回流(reflow)和重绘(repaint)是不同的,只要改变元素的位置的操作就会触发重排(例如:元素尺寸改变——边距、填充、边框、宽度和高度),位置不变只是样式改变则只是触发重绘(例如:改变元素的color、background、box-shadow等属性)
特别地:display:none会触发reflow,而visibility:hidden只会触发repaint,因为没有发现位置变化。
web前端巨无霸长文-持续更新2021-10-13(1.6w+字)_第1张图片

JS加载与执行机制

JavaScript 的加载、解析与执行会阻塞文档的解析, 等 JavaScript 引擎运行完毕,浏览器再从中断的地方恢复继续解析文档。

如果你想首屏渲染的越快,就越不应该在首屏就加载 JS 文件,这就是建议将 script 标签放在 body 标签底部的原因。当然并不是说 script 标签必须放在底部,因为你可以给 script 标签添加 defer 或者 async 属性。

defer 和async 属性的区别

一图胜千言
web前端巨无霸长文-持续更新2021-10-13(1.6w+字)_第2张图片

2,HTML

HTML行内元素与块级元素

  • HTML常见行内元素:img,a,b,span,strong,em,sub,sup,button,input,label,select,textarea
  • HTML常见块级元素:div,ul,ol,li,dl,dt,dd,h1-h6,p
  • HTML行内元素与块级元素的区别
    · 行内元素设置:width,height,margin-top,margin-bottom,padding-top,padding-bottom无效,但是line-height有效。
    · 行内元素不会独占一行,块级元素会独占一行
    · 可以通过display:block;或display:inline;或者display:inline-block改变元素类型
    其中line-block使得元素与block几乎一样,但却保留了inline不会独占一行的特性

HTML5特性

标签语义化

比如:article,footer,header,nav,section
1,提高了代码的可读性,便于维护和开发
2,更便于搜索引擎优化(SEO)

多媒体播放

音频

<audio controls="controls">
    <source src="demo.mp3" type="audio/mp3">
audio>

视频

<video width="320" height="240" controls="controls">
    <source src="demo.mp4" type="video/mp4">
video>

新增表单控件

    <label>日期label><input type="date"><br>
    <label>时间label><input type="time"><br>
    <label>邮箱label><input type="email"><br>
    <label>搜索label><input type="search"><br>
    <label>网址urllabel><input type="url"><br>
    <label>颜色label><input type="color"><br>
    <label>范围label><input type="range">

新增技术Webwork

铺垫:
(1)对于Chrome浏览器内部至少有6个线程负责向服务器发起请求获取资源,此处称之为:请求线程;另外还有一个线程负责绘制所有资源并且执行js程序,此处称之为:UI主线程;问题就在于这个UI主线程既要绘制又要执行JS程序,因此当执行JS代码的过程中会阻塞UI的绘制;
代码示例:

正常运行UI主线程

DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Titletitle>
head>
<body>
<button>按钮1button>
<script src="js/demo.js">script>
<button>按钮2button>
body>
html>

效果是:先出现【按钮1】五秒后出现【按钮2】并且输出console.log()打印语句

通过Webworker创建一个线程帮助UI主线程执行JS代码

DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Titletitle>
head>
<body>
<button>按钮1button>
<script>
  let worker = new Worker("js/demo.js")
script>
<button>按钮2button>
body>
html>

效果是:同时出现【按钮1】【按钮2】然后输出console.log()打印语句

js/demo.js
let startTime = new Date().getTime()
let endTime = null;
do {
     
     endTime = new Date().getTime()
}while (endTime - startTime < 5000)
console.log("执行demo.js的5秒后")

注意:不同浏览器的渲染机制会有所不同,此处实验使用的是chrome浏览器

新增技术Websocket

(1)Websoket传输数据的方式是全双工的。通讯拥有更强的实时性
(2)由于低延迟,高及时的特性,多应用于多人协同的场景。

本地离线存储localStorage

本地离线存储,localStorage长期存储数据,浏览器关闭后数据不会丢失;与sessionStorage相比,sessionStorage的数据在浏览器关闭后会自动删除。

3,CSS

盒模型

(1)标准盒模型:(box-sizing:content-box) width,height只包含content内容,因此padding进而boder不受height和width控制,所以当padding值>0时候会增大盒子大小。
(2)怪异盒模型:(box-sizing:border-box) width,height包含了content,padding,border,因此padding和border纳入height,width控制的。
web前端巨无霸长文-持续更新2021-10-13(1.6w+字)_第3张图片

引入样式时,使用link和@import有什么区别

(1)从属关系的区别: @import是CSS提供的语法规则,只有导入样式表的作用;link是HTML提供的标签,它不仅可以加载CSS文件还可以定义RSS、rel连接属性,引入网站图标等。
(2)加载机制的区别:加载页面时候,link标签引入的CSS被同时加载;@import 引入的CSS需要在页面加载完毕后再被加载。
(3)兼容性的区别,link标签没有兼容性问题,@import是CSS2.1才支持的语法,因此需要IE5+才能够支持;
(4)DOM可控性区别可以通过JS操作DOM插入link标签进而改变样式;而@import导入CSS样式的方式无法通过DOM进行操作。

CSS选择器优先级

ID 选择器:如 #id{}
类选择器:如 .class{}
属性选择器: 如 a[href="segmentfault.com"]{}
伪类选择器: 如 :hover{}
伪元素选择器: 如 ::before{}
标签选择器: 如 span{}
通配选择器:如 *{}

!important (权重最高)>内联样式 (权重为:1000)> ID 选择器(权重为:100)> 类选择器= 属性选择器= 伪类选择器(权重为:10)> 标签选择器 = 伪元素选择器(权重为1)

伪元素和伪类的区别

(1)伪元素用来创建一些不在文档树中的元素,并为七天假对应的样式。使用::进行表示,但是由于在旧版的W3C标准规范并为对其进行特别区分,因此目前大多数浏览器都支持这儿两种方式(:: 或者:)表示伪元素。常见::before、::after
(2)伪类用于为元素处于某种状态下,对其添加对应样式。常见 :hover、:focus

CSS3特性

盒子阴影

box-shadow: offset-x offset-y [blur [spread]] [color] [inset]
  • box-shadow 属性用于向盒子添加一个或多个阴影效果。
  • offset-x:阴影的水平偏移量。正数向右偏移,负数向左偏移。
  • offset-y:阴影的垂直偏移量。正数向下偏移,负数向上偏移。
  • blur:阴影模糊度,不能取负数。
  • spread:阴影大小。正数阴影扩大(阴影大小大于盒子大小),负数阴影缩小(阴影大小小于盒子大小),0阴影与盒子同等大小。
  • inset:表示添加内阴影,默认为外阴影。

新增选择器

属性选择器:elem[property]
结构伪选择器

(1)elem:nth-child(n)选择父元素下n个子元素,并且这个元素的标签名称为elem,n可以接受具体的数字、值(odd和even)、公式(作为公司的时候n是从0开始的)。
(2)elem:nth-last-child(n)作用同上,区别在于该伪类从后开始查找
(3)elem:last-child选父元素中饭中最后一个子元素
(4)elem:first-child选中父元素中第一个子元素
(5)elem:only-child如果elem是父元素下唯一的子元素,则选中之
(7)elem:nth-of-type(n)选择父元素下第n个elem类型元素,n可以接受具体的数值,也可以接受函数
(8)elem:first-of-type选择父元素下第一个elem类型元素
(9)elem:last-of-type择父元素下最后一个elem类型元素
(10)elem:only-of-type选择父元素下只有一个elem类型元素
(11)elem:empty选中不包含子元素和内容的elem类型元素
(12)not(elem)选择非 elem 元素的每个元素
(13)checked 单选框或复选框被选中

伪元素选择器

(1)::before 在元素内部前面插入内容
(2)::after 在元素内部后面插入内容
注意

  • before和after必须有content属性
  • before在内容的前面,after内容的后面
  • before和after创建的是一个元素,但是在DOM里面是看不见的元素因此称之为伪元素,这个元素属于行内元素,定义宽高的时候必须设置box-sizing:block或者box-sizing:inline-block
  • 伪元素和标签选择器一样权重为1

圆角

border-radius:8px

2D转换

(1) 2D 移动: transform: translate(x,y); 单位px
(2)2D 旋转: transform:rotate(0deg)l
(3)转换中心点(缩放与旋转都有影响):transform-origin: x y;
重点:

  • 注意后面的参数x和y用空格隔开
  • x y 默认转换中心电视元素的中心点(50% 50%) 或者(center center)
  • x y 可以是像素数值,或者方位名词:top bottom left right center
    (4)2D 缩放: transform:scale( x y) ;
    重点:
  • 没有单位,x y 指的宽度和高度的倍数
    (5)过度:transition: all 0.5s;
    重点:
  • 语法transition: property(属性) duration(过度时长) timing-function(过度方法) delay(延迟时长);

动画

(1)动画基本使用步骤:

  • 定义动画
  • 使用动画
DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Titletitle>
head>
<body>
<div class="animation-box">div>
body>
<style>
    /*定义动画*/
    @keyframes move {
       
        0%{
       
            transform: translate(0px,0px);
        }
        100%{
       
            transform: translate(1000px,0px);
        }
    }
    .animation-box{
       
        height: 100px;
        width: 100px;
        background-color: pink;
        /*使用动画*/
        animation-name: move;
        animation-duration: 2s;
        animation-direction: alternate;
        animation-iteration-count: infinite;
    }
style>
html>

(2)动画常用属性:
web前端巨无霸长文-持续更新2021-10-13(1.6w+字)_第4张图片
(3)暂停动画:animation-paly-state:paused

(4)动画简写属性:
animation:动画名称 持续事件 运动曲线 何时开始 播放次数 是否反方向 动画起始或者结束的状态;

animation:name 5s linear 2s infinite alternate;
  • 简写属性里面不包含animation-play-state
  • 暂停动画:animation-play-state:paused;经常和鼠标经过配合使用
  • 想要动画偶组回来,而不是直接跳回来:animation-direction:alternate;
  • 动画结束后,停在结束的位置:animation-fill-mode:forwords;

3D转换

(1)转换

  • transform:translateX(100px):在X轴移动
  • transform:translateY(100px):在Y轴移动
  • transform:translateZ(100px):在Z轴移动(垂直于屏幕)配合透视来观察
  • transform:translate3d(x,y,z):其中x,y,z指的是要移动轴的方向距离

(2)透视:perspective: 100px;
注意:

  • 透视需要写到被观察元素的父元素上
  • 透视就是模拟视距,值越小,代表越近,看的越大

(3)3d旋转

  • transform:rotate(45deg):沿着x轴旋转45度
  • transform:rotate(45deg):沿着y轴旋转45度
  • transform:rotate(45deg):沿着z轴旋转45度
  • transform:rotate3d(x,y,z,deg):x,y,z组成矢量方向,deg为旋转角度
左手螺旋法则,拇指指向旋转轴的正方向,手指方向为旋转方向。
x轴正方向:→
y轴正方向:↓
z轴正方向:垂直屏幕向外

4,常见页面布局操作

三栏式布局

float布局

web前端巨无霸长文-持续更新2021-10-13(1.6w+字)_第5张图片

绝对定位布局

web前端巨无霸长文-持续更新2021-10-13(1.6w+字)_第6张图片

flex布局

web前端巨无霸长文-持续更新2021-10-13(1.6w+字)_第7张图片

水平垂直居中

定位 + 负margin

web前端巨无霸长文-持续更新2021-10-13(1.6w+字)_第8张图片

定位 + auto margin

web前端巨无霸长文-持续更新2021-10-13(1.6w+字)_第9张图片

定位 + transfrom

web前端巨无霸长文-持续更新2021-10-13(1.6w+字)_第10张图片

定位 + calc

web前端巨无霸长文-持续更新2021-10-13(1.6w+字)_第11张图片

通过flex

web前端巨无霸长文-持续更新2021-10-13(1.6w+字)_第12张图片

CSS画一个三角形和箭头

三角形的原理:
相邻边框连接处是均分的。将其他边颜色值设置为transparent透明即可实现三角形的效果;
web前端巨无霸长文-持续更新2021-10-13(1.6w+字)_第13张图片

web前端巨无霸长文-持续更新2021-10-13(1.6w+字)_第14张图片

超出内容显示省略号

overflow: hidden;
text-overflow:ellipsis;
white-space: nowrap;

轮播图的实现

以下的实现方式不是最优的,但是这里通过CSS最大限度的对其进行实现,剩余的自动播放与交互还是用回了JS,因此做复杂了。建议主要使用JS进行实现。

  • labell标签可以通过for="元素id"属性绑定对应的input元素,进而使得点击label标签即可触发checked的变动。
  • 用到CSS “~” 这个符号的选择器,该符号可以选择其后同级元素的层级元素,搭配:checked这个选择器,即可使得当某个radio选项被选中时候,同级的 ul下所有li同时向左移动。在此之上加上transition过度效果既可以实现点击选项切换图片的效果。
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<div class="swiper">
    <ul class="sliders" onmouseover="handleMouseover()" onmouseout="handleMouseout()">
        <input type="radio" id="control-1" name="slider-radio" checked>
        <input type="radio" id="control-2" name="slider-radio">
        <input type="radio" id="control-3" name="slider-radio">
        <div class="label-box">
            <label for="control-1" index="1"></label>
            <label for="control-2" index="2"></label>
            <label for="control-3" index="3"></label>
        </div>
        <li class="slider">1</li>
        <li class="slider">2</li>
        <li class="slider">3</li>
    </ul>
</div>
<style>
    input[type="radio"]{
     
        position: relative;
        z-index: 100;
        display: none;
    }
    .swiper{
     
        height: 100vh;
        width: 100vw;
        display: flex;
        justify-content: center;
        align-items: center;
        position: relative;
    }
    .sliders{
     
        position: relative;
        height: 300px;
        width: 400px;
        background-color: gray;
        padding: 0;
        margin: 0;
        overflow: hidden;
    }
    .slider{
     
        position: absolute;
        list-style: none;
        padding:0;
        margin: 0;
        height: inherit;
        width: inherit;
        display: flex;
        justify-content: center;
        align-items: center;
        color: aliceblue;
        font-size: 100px;
        transition: all 0.5s;
    }
    .slider:nth-of-type(1){
     
        background-color: #ffb700;
    }
    .slider:nth-of-type(2){
     
        left:100%;
        background-color: #ff0073;
    }
    .slider:nth-of-type(3){
     
        left: 200%;
        background-color: #0066ff;
    }
    .label-box{
     
        position: absolute;
        bottom: 10px;
        width: 100%;
        text-align: center;
        z-index: 100;
    }
    .label-box>label{
     
        display: inline-block;
        height: 10px;
        width: 10px;
        border:2px solid #ffffff;
        border-radius: 50%;
        background-color: aliceblue;
        cursor: pointer;
    }
     input[type="radio"]:nth-child(1):checked ~ .label-box label:nth-child(1){
     
        background-color: #232323;
    }
     input[type="radio"]:nth-child(2):checked ~ .label-box label:nth-child(2){
     
        background-color: #232323;
    }
     input[type="radio"]:nth-child(3):checked ~ .label-box label:nth-child(3){
     
        background-color: #232323;
    }
     input[type="radio"]:nth-child(1):checked ~ .slider{
     
        transform: translateX(0)
    }
     input[type="radio"]:nth-child(2):checked ~ .slider {
     
        transform: translateX(-100%)
    }
     input[type="radio"]:nth-child(3):checked ~ .slider {
     
        transform: translateX(-200%)
    }
</style>
<script>
    let slides = document.getElementsByTagName("input")
    let i = 1
    let timer
    function startTimeout(){
     
        timer = setInterval(function () {
     
            if (i>=slides.length){
     
                i = 0
            }
            slides[i].checked = true
            i++
        },2000)
    }
    startTimeout()
    function handleMouseover(){
     
        clearTimeout(timer)
    }
    function handleMouseout (){
     
        startTimeout()
    }
    //这里是为了使得点击按钮后,使得i的值与轮播图此时轮播到第几张进行对应。
    function setCurrentIndex(e){
     
        i = parseInt(e.target.getAttribute("index"))
    }
    let labels = document.getElementsByTagName("label")
    for (let k = 0 ;k<labels.length;k++){
     
        labels[k].addEventListener("click",setCurrentIndex)
    }
</script>
</body>
</html>

二,JS相关

JS基础概念

EventLoop事件循环机制

Event Loop 是一个很重要的概念,指的是计算机系统的一种运行机制。
JavaScript语言就采用这种机制,来解决单线程运行带来的一些问题。
JS通过事件循环机制已达到非阻塞的效果,当遇到异步任务我们现将其挂起,直到同步代码执行完毕后,再去任务队列中去执行异步任务(先执行微任务,后指向宏任务)
微任务:promise …
宏任务:setTimeout、setInterval …

this指向

this的指向是动态进行绑定的。不受作用域的限制。
方法中的this指向问题可以通过call,apply,bind指向。call和apply的区别在于传参的形式不同。bind则是绑定了不执行罢了。
凡是通过 obj.func()进行调用的,func中的this指向的就是调用者obj如果被调用的函数为箭头函数则另当别论,箭头函数没有this,因此箭头函数中的this静态的,它指向它的词法作用域中的this
嵌套函数和普通函数,仅仅作为函数进行调用,而非通过对象进行调用时候,通常指向的是全局对象,严格模式下为undefined

作用域链

  • JS没有块作用域,只有全局作用域和局部作用域,局部作用域只存在于function中。
  • 直到ES6出现了let和const才缓解了块作用域的问题,同时伴随则暂时性死区的问题。
  • 当我们访问一个变量的时候,首先会在自身所在的作用域进行查询,如果没有则往上进行查找直到查找到全局作用域时,仍然无法找到,则会报错。不存在嵌套函数的的情况下只有两层作用域,一个是全局作用域,一个是函数作用域。存在嵌套函数的情况下作用域大于等于三层。

词法作用域

词法作用域指的是声明时所在作用域,而非运行时。

闭包

一个函数和对其周围状态(lexical environment,词法环境)的引用捆绑在一起(或者说函数被引用包围),这样的组合就是闭包。
闭包是由函数以及声明该函数的词法环境组合而成的。该环境包含了这个闭包创建时作用域内的任何局部变量。
在循环中创建闭包是常见第一种错误使用方式,解决这个问题可以通过使用更多的闭包或者使用let进行声明循环变量。

new关键之的实现原理

new 关键字做了什么动作

  • 创建了一个对象 let obj
  • 将这个新创建的对象的原型指向构造函数的原型上 obj.__proto__ = constructor.prototype
  • 调用构造函数对这个对象进行初始化 constructor.apply(obj,arg)
function myNew (constructor,...arg){
     
    let obj = {
     }//创建一个对象
    obj.__proto__ = constructor.prototype //将新创建的对象的原型指向构造函数的原型
    constructor.apply(obj,arg)//调用构造函数初始化对象
    return obj//将对象返回
}

原型以及原型链

每个对象都有一个私有属性(proto)指向它的构造函数的原型对象(prototype)该(prototype)原型对象也有自己私有属性(proto)指向它的构造函数的原型对象(prototype),层层向上知道一个对象的原型对象为null。根据定义null没有原型。
基于原型链的继承,对象可以访问到原型链上的方法和属性。

call方法实现原理

Function.prototype.myCall = function(){
     
    let caller = this//这里相当于fun.call(obj,...arg)中fun
    let targetObj = arguments[0]//这里相当于fun.call(obj,...arg)中的第一个参数obj
    let otherArgs = []//这里相当于fun.call(obj,...arg)中的除了第一个参数的所有参数的集合...arg
    for (let i = 1 ;i<arguments.length;i++){
     
        otherArgs.push(arguments[i])
    }
    targetObj.caller = caller
    let res = targetObj.caller(...otherArgs)//这里完成了this的动态绑定
    delete  caller
    return res
}

console.log([].filter.myCall([1,2,6,2,3,5],function (item){
     
    return item >3
}))

防抖节流

/*防抖函数*/
//事件连续触发多次,只执行最后一次触发,并且停止触发事件后的timing秒才会执行
function debounce(fun,timing){
     
    let timer//用于记录定时
    return function (){
     
        clearTimeout(timer)//清除定时
        timer = setTimeout(function (){
     
            fun()
        },timing)
    }
}
/*节流函数*/
//事件触发多次,只在一定时间内执行一次
function throttle(fn,timing){
     
    let trigger//是否触发的判断值
    return function (){
     
        if (trigger) return //如果已经触发过了直接返回,不再往下执行
        trigger = true //如果没有触发过,往下执行触发,并且把该状态改为触发
        fn()
        //并且通过定时器,设置timing秒后才将状态变为未触发,即timing秒后才可以再次触发
        setTimeout(function (){
     
            trigger = false
        },timing)
    }
}

JS算法

冒泡排序法

let arr = [4,9,10,22,7,3,2]
//冒泡排序法
function bubbleSort(arr){
     
    let temp
    for (let i = 0;i<arr.length;i++){
     
        for(let j=0;j<arr.length-1-i;j++){
     
            if (arr[j+1]<arr[j]){
     
                temp = arr[j+1]
                arr[j+1] = arr[j]
                arr[j] = temp
            }
        }
        console.log(arr.join("-"))
    }
    return arr
}
bubbleSort(arr)

三,前端框架相关

1,Vue

双向数据绑定原理

v-model其实是v-on和input事件监听的一个语法糖。
v-model原理:通过v-on实现了对数据对象data的监听,通过input事件监听,把输入框中的值更新到数据对象data,这样一来就实现了双向数据绑定。

响应式原理

通过Object.defineProperty来实现监听数据的改变和读取(属性中的getter和setter方法) 实现数据劫持。

父子组件之间的传值

  • 父组件引用子组件的时候直接在组件标签上定义标签属性,如果需要使用data中的值可以使用v-bind进行绑定
//此处title为传递给子组件的值
....
<Demo v-bind:title="title" @myEvent="listenSun"></Demo>
....
  • 子组件通过porps属性进行接受父组件传递过来的值
....
//定义的是传递过来的数值类型
props:{
     
    title: String
  }
....

父组件传值给子组件

  • 子组件通过this.$emit(“eventName”,",message")进行触发自定义事件
<template>
  <div class="demo-layout">
    <h1  v-on:click="handleClick">点击这里触发/h1>
    </div>
</template>
....
methods:{
     
    handleClick: function (){
     
      this.$emit("myEvent","message")//这个message就是传递给父组件的值
    }
}
....
  • 父组件通过v-on:eventName=“handleEventName” 对其进行监听
<template
  <div id="app">
    <Demo v-bind:title="title" @myEvent="listenSun"></Demo>
  </div>
</template>
....
  methods: {
     
    listenSun: function (message){
     //这里的message就是子组件传递过来的值
    	....
      }
  }
}
....
  • handleEventName(message){} 可以接受到传递过来的message

子组件传值给父组件

非父子组件之间的传值

bus模式/总线模式

  • 首先在Vue构造函数的原型链上挂载一个Vue的实例对象

vuex

  • 安装
npm install vuex --save
  • 在src目录下创建 store目录,同时创建一个index.js文件
import Vuex from 'vuex'
import Vue from 'vue'
Vue.use(Vuex)

export default new Vuex.Store({
     
    //用于存放全局的数据
    state:{
     
        num:0
    },
    //相当于组件中计算属性,省去在每个组件使用计算属性的操作。
    getters:{
     
        getNum(state){
     
            return state.num
        }
    },
    //vuex推荐改变sate中的数据在此处进行.触发需要使用$store.commit("mutationsName")
    mutations:{
     
        increaseNum(state){
     
            state.num++
        }
    },
    //相当于可以处理异步的mutation.触发需要使用$store.dispatch("mutationsName")
    actions:{
     
        asyncIncreaseNum(context){
     
            setTimeout(()=>{
     
                context.commit('increaseNum')
            },1000)
        }
    },
    modules:{
     }
})
  • 在全局中引入vuex
import Vue from 'vue'
import App from './App.vue'
import store from '@/store'
Vue.config.productionTip = false
Vue.prototype.bus = new Vue()
new Vue({
     
  store,//全局注册
  render: h => h(App),
}).$mount('#app')

  • 在组件中使用vuex
<template>
  <div class="count-layout">
    <h1>{
     {
     this.$store.getters.getNum}}</h1>
    <h1>{
     {
     this.$store.state.num}}</h1>
    <input type="button" value="+1" @click="handleClickAdd">
    <input type="button" value="async+1" @click="handleAsyncClickAdd">
  </div>
</template>

<script>
export default {
     
  name: "Count",
  methods: {
     
    handleClickAdd() {
     
      this.$store.commit("increaseNum")
    },
    handleAsyncClickAdd(){
     
      this.$store.dispatch("asyncIncreaseNum")
    }
  }
}
</script>

<style scoped>

</style>
文件:main.js

import Vue from 'vue'
import App from './App.vue'

Vue.config.productionTip = false
Vue.prototype.bus = new Vue()
new Vue({
     
  render: h => h(App),
}).$mount('#app')
  • 一个组件使用this.bus.$emit(“eventName”,“message”)
<template>
  <div class="demo-layout">
    <h1  v-on:click="handleClickSendBus">点击此处触发</h1>
  </div>
</template>
....
 methods:{
     
    handleClickSendBus: function (){
     
      this.bus.$emit("busEvent","busMessage")
          }
  }
....
  • 另一个组件使用this.bus.$on(“eventName”,“message”)
....
 created() {
     
    this.bus.$on("busEvent",message => {
     //此处的message就是其他组件传递过来的值
      ....
    })
  }
....

生命周期

beforeCreate:data和method还没有创建,在这个声明周期钩子函数上不能使用data;
created:可以访问里面的数据对象data和方法对象methods;
beforeMount:el实力和data都初始化了,但未挂载到DOM;
mounted:vue实例挂载到DOM了,此时可以对DOM进行操作;
beforeupdated:响应式数据更新时调用,此时并未完成DOM重新渲染;
updated:虚拟DOM重新渲染和打补丁之后调用,组成新的DOM已经更新,避免在这个钩子函数中操作数据,防止死循环;
beforeDestroy:实例销毁前调用,实例还可以用,this能获取到实例,常用于销毁定时器,解绑事件;
destroyed:实例销毁后调用,调用后所有事件监听器会被移除,所有的子实例都会被销毁;

$nextTick

在Vue中数据发生改变,Dom不是立即更新的,为了准确的获取到最新的Dom我们可以使用$nextTick

四,其他知识总结

浏览器

Cookie、Session、Token

(1)Cookie:客户端访问服务器,服务器为了识别用户创建Session,将SessionId保存到Cookie中发送给客户端,客户端将其存储在浏览器中,当再次访问服务器的时候会自动将Cookie加入到请求,随着请求一并传递到服务器端。
(2)Session是存储在服务器端的,服务器端通过解析Cookie获取到对应的SessionId来找到对应的Session,Session是依赖Cookie的
(3)Token由三部分组成:uid(用户唯一标识)、time(时间戳)、sign(签名),相当于一个令牌,用户信息存储到Token中,服务器接收到Token解密后才识别到用户信息,与Cookie不同的,发送需要开发者手动添加。

常见浏览器所用内核

(1)IE浏览器内核:Trident内核俗称IE内核;
(2)Chrome浏览器内核:以前是Webkit内核现在是Blink内核。
(3)Safari浏览器内核:Webkit内核
(4)Firefox浏览器内核:Gecko内核,俗称Firefox内核
(5)Opera浏览器内核:起初是自己的Presto内核,后再加入了谷歌大军,从Webkit又到了Blink;
(6)360浏览器,猎豹浏览器内核:IE+Chrome双内核
(7)搜狗,遨游,QQ浏览器内核:Trident(兼容模式)+Webkit(高速模式)
(8)百度浏览器、世界之窗内核:IE内核
(9)2345浏览器内核:IE+Chrome双内核
(10)UC浏览器内核:众口不一,UC自称自己研发U3内核,但是还是基于Webkit和Trident,还有说是基于火狐内核的。

程序、进程、线程

程序的概念:通俗的讲,程序是存储在磁盘中运行在cpu的代码,例如c:/demo.js
进程的概念:通俗的讲,将程序调入内存中并分配一定的空间,在内存中的程序为内存。
线程:通俗的讲,进程中包含多个线程。线程就好比如一个工厂中的其中一条流水线。

数据通讯

(1)单工通讯:收发端口固定,一个固定为发送端口,一个固定为接受端口。例如遥控器。
(2)半双工通讯:两端都具备发送器和接收器,但同一时刻只能发送或只能接收数据的传输方式。由于这种方式要频繁变换信道方向,故效率低,但可以节约传输线路。例如无线对讲机
(3)全双工通讯:发送数据的同时也能够接收数据,两者同步进行。例如:打电话,说话的同时依然能够听到对方的声音。

你可能感兴趣的