CSS 面试

1、盒模型
盒子的组成:内容content、内边距padding、边框border、外边距margin
    盒模型的类型:
        标准盒模型:		盒子设置的宽高 = 内容(内边距自增加)
            margin+border+padding+content
        IE盒模型:      盒子把设置的宽高 = 内容+内边距+边框(盒子原本的内容高度会变小)
            margin+content(border+padding)
    控制盒子的模式:box-sizing:content-box(默认值:标准盒模型)、border-box;
2、CSS 选择器优先级
CSS特性:继承性,层叠性,优先级
优先级:
!important > 行内样式 > id > 类/伪类/属性 > 标签 > 全局选择器
3、隐藏元素的方法
1、display: none;元素在页面上消失,不占据空间
2、opacity:0;设置了元素的透明度为不可见,占据空间位置
3、visibility:hidden;让元素消失不可见,占据空间位置
4、position:absolute;clip-path(剪切元素)
4、px 和 rem 的区别是什么
px是像素,显示器上给我们呈现画面的像素绝对单位。
rem相对单位,相对于html根节点的font-size的值,给根节点html的font-size:62.5%;
    1rem = 10px; (16px*62.5%=10px)
5、重排和重绘的区别
重排(回流):布局引警会根据所有样式计算出页面的位置和大小。
重绘:计算好盒模型的位置,大小和其他一些属性,样式进行绘制。
位置大小改变进行重排,样式颜色背景改变进行重绘。
6、让元素水平垂直居中的方式
1、定位+margin:auto;
2、定位+transform;
3、flex布局
4、grid布局
5、table布局
7、CSS 的那些属性可以继承?那些不可以继承?
CSS三大特性:继承,层叠,优先级
可继承的样式:
    1、字体的属性:font
    2、文本的属性:line-height
    3、元素的可见性:visibility:hidden;
    4、表格的布局属性:border-spacing
    5、列表的属性:list-style
    6、页面的样式属性:page
    7、声音的样式属性
8、有没有用过预处理器
sass,less

JS

1、js有那三部分组成

ECMAScript: js的核心内容,描述了语言的基础语法,比如var,for,数据类型
文档对象模型(DOM):DOM把整个页面HTML页面规划为元素的构成文档
浏览器对象模型(BOM):对浏览器的窗口进行访问和操作

2、js有那些内置对象

String Boolean Number Array Object Functi	·on Math Date RegExp...
Math
    abs() sqrt() max() min()
Data
    new Data() getYear()
Array
String
    concat() length slice() split()

3、操作数组的方法有那些

push() pop() sort() splice() unshift() shift() reverse() concat() join()
map() filter() ervery() some() reduce() isArray() findIndex() 
会改变原数组的方法:
    push() pop() splice() unshift() shift() sort() reverse()

4、js对数据类的检查方法有那些,4种

typeof()    对于基本数据类型没问题,引用数据类型不可用
instanceof() 只能判断引用数据类型,不能判断基本数据类型
constructor()	几乎可以判断基本数据类型和引用数据类型
object.prototype.toString.call()最准确的类型检测方法返回格式:[object Type]
使用方法:console.log(typeof 666)
        console.log([] instanceof [1,2,3])
        console.log(('abc').constructor === String)
        Object.prototype.toString.call([]) // "[object Array]"
        

5、说一下闭包,闭包有什么特点

什么是闭包?函数嵌套函数,内部函数被外部函数返回并保存下来时,就会产生闭包
特点:可以重复利用变量,并且这个变量不会污染全局的一种机制;这个变量是一直保存在内存中,不会被垃圾回收机制回收。
缺点:闭包过多时会消耗内存,导致页面的性能下降,在IE浏览器才会导致内存泄漏
使用场景:防抖,节流,函数嵌套函数避免全局污染的时候

6、前端的内存泄漏怎么理解

js里已经分配内存地址的对象,但是由于长时间没有释放或者没办法清除,造成长期占用内存的现象,会让内存资源大幅度浪费,终导致运行速度慢,导致崩溃的情况。
垃圾回收机制:
因素:一些未声明直接赋值的变量,一些未清空的定时器,过度的闭包,一些引用元素没有被清除

7、事件委托是什么

又叫事件代理,原理就是利用了事件冒泡的机制来实现,也就是说把子元素的事件绑定到了父元素的身上
如果子元素组织了事件冒泡,那么委托也就不成立了
组织事件冒泡:event.stopPropagation()
addEventListener('click',函数名,true/false)默认是flase(事件冒泡),true(事件捕获)
好处:提高性能,减少事件绑定,也就减少了内存的占用。

8、基本数据类型和引用数据类型的区别

基本数据类型:String Number Boolean undefined null
    基本数据类型保存在栈内存当中,保存的就是一个具体的值
引用数据类型:Object Function Array
    引用数据类型保存在堆当中,声明一个引用类型的变量时保存的是地址,
    假如声明两个引用类型同时指向了一个地址的时候,修改其中一个那么另外一个也会改变

9、说一下原型链.prototype

原型就是一个普通对象,它时为构造函数的;实例共享属性和方法;所有的实例中引用的原型都时同一个对象。
使用.prototype.可以把方法挂载在原型上,内存只保存一份
__proto__可以理解为指针,实例对象的属性,指向了构造函数的原型(prototype)
class Person {
    constructor() {
        this.say = function () {
            console.log('hhhhhhhh')
        }
    }
}
Person.prototype.look = function () {
    console.log('ggggggggg')
}
let p = new Person()
console.log(p.__proto__ === Person.prototype)

10、new操作符具体做了什么?

    function newFun(Fun,...args){
        // 1.先创建一个空对象
        let newObj = {}
        // 2.把空对象和构造函数通过原型链进行链接
        newObj.__proto__ = Fun.prototype
        // 3.把构造函数的this绑定到新的空对象身上
        const result = Fun.apply(newObj,args)
        // 4.根据构建函数返回的类型判断,如果是值类型,则返回对象,如果是引用类型,就要返回这个引用类型
        return result instanceof Object ? result : newObj
    }

    function Person(name){
        this.name = name
    }
    Person.prototype.say = function(){
        console.log('123456')
    }
    const p1 = newFun(Person,'张三')
    p1.say()
    console.log(p1)

11、JS是如何实现继承的?

1、原型链继承               
    // 优点:写法方便简洁,容易理解。
    // 缺点:对象实例共享所有继承的属性和方法。无法向父类构造函数传参。
2、借用构造函数继承					
    // 优点:解决了原型链实现继承的不能传参的问题和父类的原型共享的问题。
    // 缺点:借用构造函数的缺点是方法都在构造函数中定义,因此无法实现函数复用。
    //在父类型的原型中定义的方法,对子类型而言也是不可见的,结果所有类型都只能使用构造函数模式。
3、组合式继承
    // 优点:就是解决了原型链继承和借用构造函数继承造成的影响。
    // 缺点:是无论在什么情况下,都会调用两次父类构造函数:
    //     一次是在创建子类原型的时候,另一次是在子类构造函数内部
4、ES6的class类继承
    // 优点:语法简单易懂,操作更方便。
    // 缺点:并不是所有的浏览器都支持class关键字

12、JS的设计原理是什么?

JS引擎 运行上下文 调用栈 事件循环 回调

13、JS中关于this指向问题

1、全局对象中的this指向
    指向的是window
2、全局作用域或者普通函数中的this
    指向的是window
3、this永远指向最后调用它的那个对象
    在不是箭头函数的情况下的情况下
4、new 关键词改变了this的指向
5、apply,call,bind
    可以改变this指向,不是箭头函数
6、箭头函数中的this
    它指向在定义的时候就已经确认了
    箭头函数没有this,看外层是否有函数,有就是外层函数的,没有就是window
7、匿名函数中的this
    永远指向了window,匿名函数的执行环境具有全局性,因此this指向window

14、script标签里的async和defer有什么区别?JS延迟执行

当没有async和defer这两个属性的时候
    浏览器会立刻加载并执行指定的脚本
有async
    加载和渲染后面元素的过程将和script的加载和执行并行进行(异步)
有defer
    加载和渲染后面元素的过程将和script的加载并行进行(异步),但是他的执行事件要等所有元素加载解析完成之后执行

15、setTimeout最小执行事件是多少

setTimeout最小执行时间是4ms
setInterval最小执行时间是10ms

16、ES6和ES5有什么区别,ES6的新特性

JS的组成ECMAScript BOM DOM
ES5指ECMAScript的第5此修订
区别和新特性:
1、新增块级作用域(let,const)
    不存在变量提升
    存在暂时性死区的问题
    块级域的内容
    不能在同一个作用域内重复声明
2、新增了定义类的语法糖(class)
3、新增了一种基本数据类型(symbol)
4、新增了解构赋值
    从数组或者对象中取值,然后给变量赋值
5、新增了函数参数的默认值
6、给数组新增了API
7、对象和数组新增了扩展运算符
8、Promise
    解决回调地狱的问题
    自身有all,reject,resolve,race方法
    原型上有then,catch
    把异步操作队列化
    三种状态:pending初始状态,fulfilled操作成功,rejected操作失败
      pending => fulfilled;pending => rejected一旦发生,状态就会凝结,不再改变
    async返回一个Promise对象,表明有异步操作
    await是async的表达式,结果取决于他等待的内容
9、新增了set和map数据结构
    set就是不重复
    map的key的类型不受限制
10、新增了generator
11、新增了箭头函数
    不能作为构造函数,不能用new
    箭头函数没有原型
    箭头函数不能改变this的执行
12、新增了模块化(import,export)

18、call,aply,bind三者有什么区别

call和apply功能类似,只有传承我的方式不同
  call的方法是一个参数列表
  apply传递的是一个数组
  bind传参后不会立刻执行,会返回一个改变this指向的函数,这个函数还是可以传参,
  bind(){},call方法的性能要比apply好些,所以call用的多些

19、用递归的时候有没有遇到什么问题

函数本身调用函数本身这就是递归
  函数内部调用自己
写递归时一定要return
// 递归计算阶乘
function factorial(n) {
    // 基线条件
    if (n <= 1) {
        return 1;
    }
    // 递归条件
    return n * factorial(n - 1);
}

20、如何实现一个深拷贝?

//1、扩展运算符
let obj = {
  name: 'zhangsan',
  age: 18
}
let obj1 = {...obj}
obj1.name = 'wangwu'//缺点:这个方法只能实现第一层,当有多层的时候还是浅拷贝
//2、JSON.parse(JSON.stringify())
let obj = {
  name:'zhangsan',
  age:18,
  say(){
    console.log(obj)
  }
}//缺点:该方法并不会拷贝内部函数
let obj = JSON.parse(JSON.stringify(obj))
//3、利用递归函数实现
let origin = {
  name:'zhangsan',
  age:18,
  say(){
    console.log('say hello')
  },
  arr:[[1,2],3,4]
}
function exten(org,deep){
  let obj={}
  if(org instanceof Array){
    obj = []
  }
  for(let key in org){
    let value = org[key]
    obj[key] = (!!deep && typeof value === 'object' && value !== null) ? exten(value,deep):value
  }
  return obj
}

21、JS事件循环

js是一个单线程脚本语言
主线程 执行栈 任务队列 宏任务 微任务
主线程先执行同步任务,然后才去执行任务队列里的任务,如果在宏任务之前有微任务,那么要先执行微任务
全部执行完之后等待主线程的调用,调用完之后再去任务队列中查看是否有异步任务,这样一个循环往复的过程就是事件循环

22、ajax是什么,怎么实现

创建交互式网页应用的网页开发技术
    在不重新加载整个网页的前提下,在服务器交换数据并更新部分内容
通过XMLHttpRequest对象、xmh
1、创建XmlHttpRequest对象xmh
2、通过xmh对象里的open()方法和服务器建立连接
3、构建通过所需数据,并通过xmh对象和服务器建立连接
4、通过xmh对象的onreadystate chansge事件监听服务器和你的通信状态
5、接收并处理服务器响应的数据结果
6、把处理的数据更新到HTML页面上

23、get和post有什么区别

1、get一般是获取数据,post一般是提交数据
2、get参数会放在url上,所以安全性比较差,post是放在body中
3、get请求刷新服务器或退回是没有影响的,post请求退回时会重新提交数据
4、get请求时会被缓存,post请求不会被缓存
5、get请求会被保存在浏览器历史记录中,post不会
6、get请求只能进行url编码,post请求支持很多种

24、Promise的内部原理是什么,以及优缺点

1、Promise是一个对象,封装一个异步操作还可以获取成功或失败的结果。
2、Promise主要解决回调地狱问题,之前异步任务比较多,同时他们之间有相互依赖的关系
就只能使用回调函数处理,这样容易形成回调地狱,代码可读性差,可维护性也差
3、有三种状态:pending初始状态 fulfiled成功状态 reject失败状态
  pending => fulfilled;pending => rejected一旦发生,状态就会凝结,不再改变
4、首先就是我们无法取消promise,一旦创建他就会立即执行,不能中途取消
5、原理:
构造一个Promise实例,实例需要传递函数的参数,这个函数有两个形参,分别都是函数类型,一个是resolve一个是reject
promise上还有then方法,这个方法就是来指定状态改变时的确定操作,resolve是执行第一个函数,reject是执行第二个函数
const p = new Promise((resolve, reject) => {
  // 模拟异步操作
  setTimeout(() => {
    const success = true
    if (success) resolve('成功结果')
    else reject('失败原因')
  }, 1000)
}).then(
  value => console.log('成功:', value),  // resolve执行时调用
  reason => console.log('失败:', reason) // reject执行时调用
).then(data => {
  console.log(data)
})

25、Promise和async await的区别是什么

1、都是处理异步请求的方法
2、promise是ES6,async await是ES7的语法
3、async await是基于promise实现的,他和promise都是非阻塞性的
4、优缺点:
    1、promise是返回对象我们要用then,catch方法去处理和捕获异常,并且书写方
式是链式,容易造成代码堆叠,不好维护,async await是通过try catch进行捕获异常的
    2、async await最大的优点就是能让代码看起来像同步一样,只要遇到await就会
立即返回结果,然后再执行后面的操作Promise.then()的方式返回,会出现请求还没返回,
就执行了后面的结果

26、储存方式在浏览器有哪些?

1、cookies
    H5标准前的本地存储方式
    兼容性好,请求头自带cookies
    存储量小,资源浪费,使用麻烦(封装)
2、localstorage
    H5加入的以键值对为标准的方式
    操作方便,永久存储,兼容性较好
    保存值的类型被限定,浏览器在隐私模式下不可读取,不能被爬虫
3、sessionstorage
    当前页面关闭后就会被立即清理,会话级别的存储方式
4、indexedDB
    H5标准的存储方式,他是以键值对进行存储,可以快速读取,适合WEB场景

27、token存在sessionstorage还是loaclstorage?

token:验证身份的令牌
1、存在loaclstorage里,后期每次请求接口都需要把他当成一个字段传给服务端
2、存在cookie中,会自动发送,缺点是不能跨域
如果存在localstorage中,容易被XSS攻击,但如果做好了应对措施,利大于弊
如果存在cookie中会有CSRF攻击

28、token的登入过程

1、客户端用账户密码请求登入
2、服务端收到请求后,需要去验证账户密码
3、验证成功后,服务端会发一个token,吧这个token发给客户端
4、客户端收到token后保存起来,可以放在cookie或localstorage中
5、客户端每次向服务端发送请求资源时,都需要携带这个token
6、服务端收到请求后,接着去验证客户端的token,验证成功后会返回客户端请求的数据

29、页面渲染的过程时怎么样的

DNS解析
建立TCP连接
发送http请求
服务端处理请求 
渲染页面
    浏览器获取HTML和CSS资源,然后把HTML解析成DOM树
    再把DOM和CSSOM合并成为渲染树
    布局
    把渲染树的每个节点渲染到屏幕上(绘制)
断开TCP连接

30、DOM树和渲染树有什么区别?

DOM树是和HTML标签一一对应的,包括head和隐藏元素
渲染树是不包含head和隐藏元素

31、精灵图和base64的区别是什么

精灵图:把多少张小图整合到一张大图上,利用定位的一些属性把这些小图显示在页面上,当访问页面请求减少,提高加载速度
base64:传输BBit字节代码的编码方式,把原本的二进制形式转换为64个字节的单位,
最后组成字符串
base64是会和html css一起下载到浏览器中,减少请求,减少跨越问题,
  但是一些低版本不支持,若base64体积比原图大,不利于css的加载

32、svg格式了解多少

基于xml语法格式的图像格式,可缩放矢量图,其他图像时基于像素的,SVG是属于对
图像图形的描述,本质是文本文件。
1、SVG可直接插入页面文件中,成立DOM的一部分,然后用js和css进行操作
    <svg></svg>
2、SVG可作为文件被引入
    <img src='pic.svg' />
3、SVG可以转为base64引入页面	

33、了解过JWT吗?

JSON Web Token 通过JSON形式作为web应用中的令牌,可以在各个方面直接安全的
把信息作为JSON对象传输  信息传输、授权
JWT认证流程
  1、前端把账户密码发送给后端的接口
  2、后端核对账户密码成功后,把用户id等其他信息最为JWT负责,把他和头部分别
进行base64编码拼接后签名,形成一个JWT(Token)
  3、前端每日请求时都把JWT放在HTTP请求头的Authorization字段内
  4、后端检查是否存在,如果存在就验证JWT的有效性(签名是否正确,token是否过期)
  5、验证通过后,后端使用jwt进行后续操作,并返回对应的结果
优点:简洁、包含性、因为是Token是Json加密的形式保存的,所以JST是跨语言的,
原则上是任何形式的web都支持

34、npm底层环境是什么

node package manager, node的包管理工具,已经成为分发node模块的标准
Js运行环境
npm组成:网站,注册表,命令行

35、HTTP协议规定的请求头和协议头都有哪些

1、请求头信息:
    Accept:浏览器告诉服务器所支持的数据类型
    Host:浏览器告诉服务器我想访问的那台主机
    Referer:浏览器告诉服务器从哪里来(防盗链)
    User-Agent:浏览器类型,版本信息
    Date:浏览器告诉服务器我是什么时候访问的
    Connerction:连接方式
    X-Request-with:请求方式
2、响应头信息:
    Location:这个就告诉浏览器你要去找谁
    Server:告诉浏览器服务器的类型
    Content-Type:告诉浏览器返回的数据类型
    Refresh:控制定时刷新

36、浏览器的缓存策略

强缓存(本地缓存)、协商缓存(弱缓存)
强缓:不发起请求,直接使用缓存的内容,浏览器会把js,css,image等存在内存中,
  下次用户使用的时候直接从内存中取,提高性能
协缓:需要后台发起请求,通过判断来决定是否使用协商缓存,如果请求的内容没有
  变化则返回304,浏览器就用缓存的内容
强缓存的触发:
  HTTP1.0:时间戳请求头
  HTTP1.1:Cache-Control响应标头
协商缓存触发:
  HTTP1.0:请求头:if-modified-since 响应头:last-modified
  HTTP1.1:请求头:if-none-match 响应头:Etag

37、说一下什么是“同源策略”

https://www.pengfei.site:8443/html/netweek.html
协议     子域名  主域名    端口号     资源
同源策略是浏览器的核心,没有就会受到网络攻击
主要指协议+域名+端口号三者一致,有一个不一样就不是同源,则产生跨域
三者允许跨域加载资源的标签:img link script
跨域是可以发送请求,后端也会返回结果,只不过这个结果会被浏览器拦截!
  JSONP		利用 <script> 标签没有跨域限制的“漏洞”来实现跨域数据获取
  CORS		由服务器端在HTTP响应头中声明,允许哪些源、方法、头信息来访问资源。这是W3C标准,
  websocket		WebSocket是一种全双工通信协议,其连接本身不受同源策略限制。浏览器在发起WebSocket握手时,会发送一个 Origin 头,但服务器可以根据这个头决定是否接受连接,而不是由浏览器强制阻止。
  反向代理

38、防抖和节流

都是解决页面中频繁触发事件的优化方案
  防抖:避免事件重复触发	(回城)
    使用场景:1、频繁和服务端交互,2、输入框的自动保存事件
  节流:把频繁的事件减少,每隔一段时间执行,在这段禁用时间内触发不会执行
    使用场景:scroll事件
// 防抖函数
function debounce(func, wait) {
    let timeout;
    return function() {
        const context = this;
        const args = arguments;
        clearTimeout(timeout);
        timeout = setTimeout(() => {
            func.apply(context, args);
        }, wait);
    };
}

// 简单节流函数 - 不使用时间戳
function throttle(func, wait) {
    let canRun = true;
    return function() {
        if (canRun) {
            func.apply(this, arguments);
            canRun = false;
            setTimeout(() => {
                canRun = true;
            }, wait);
        }
    };
}

39、什么是JSON

JSON是一种纯字符串形式的数据,他本身不提供任何方法,适合在网络中进行传播
JSON数据存储在.json文件中,也可以把JSON数据以字符串的形式保存在数据库、Cookise中
JS提供了JSON.parse()  JSON.stringify()
什么时候使用json:定义接口;序列化;生成token;配置文件package.json

40、当数据没有请求过来的时候该怎么做

有数据的地方先渲染默认的值
if进行判断

41、有没有做过无感登入

1、在响应器中拦截,判断token返回过期后,调用token的接口
2、后端返回过期时间,前端判断token的过期时间,去调用刷新token的接口
3、写定时器,定时刷新token接口
    流程:
      1、登入成功后保存token和refresh_token			refresh_token 是用于获取新的访问令牌(access_token)的凭证。
      2、在响应拦截器中401状态码的api方法调用
      3、替换保存本地新的token
      4、把错误对象里的token替换
      5、再次发送未完成的请求
      6、如果refresh_token过期了,判断是否过期,过期就清除所有token重新登入

42、大文件上传怎么做

分片上传:
    1、把需要上传的文件按照一定的规则,分割成相同大小的数据模块
    2、初始化一个分片上传的认为,返回本次分片上传的唯一标识
    3、按照一定的规则把各个数据块上传
    4、发送完成后,服务端会判断数据上传的完整性,如果完整,那么就会把数据库合并成原始文件
断点续传:
    服务端返回,从哪里开始    浏览器自己处理

3、HTML5,CSS3

1、语义化的理解

在写HTML页面结构时所用的标签有意义
头部用head  主体main  底部foot...
作用:让html结构清晰,方便团队协作,有利于爬虫,能够让浏览器更好去解析代码

2、H5C3有哪些新特性

H5的新特性
    1、语义化的标签
    2、新增音频视频
    3、画布canvas
    4、数据存储localstorage  sessionstorage
    5、增加了表单控件 Email、url、search...
    6、拖拽释放API
C3的新特性
    1、新增选择器:属性选择器、伪类选择器、伪元素选择器
    2、增加媒体查询
  文字阴影,边框,盒子模型box-sizing,渐变,过度,自定义动画,
  背景属性,2D和3D

3、rem是如何做适配的

rem是相当长度,相对于根元素的font-size,通常用于适配移动端
font-size: 16px
div设置1.5rem,1.2rem = 16px*1.2 = 19.2px

4、解决了哪些移动端兼容问题

1、设置样式overflow:scroll/auto时,IOS的滑动会卡顿
    
```1、插值表达式,{{  }}

可以插数据,计算式,方法函数fn(return),布尔值

```html
<body>
    <!-- 插值表达式 
    1、支持表达式,不支持语句 if for 
    2、不能直接在属性值中插值使用 
    3、响应式,数据变化,视图自动更新
    -->
    <div id="app">
        {{msg}}
        <p>{{count}}</p>
        <p>{{nickname}}</p>
        <div>{{nickname.toUpperCase()}}</div>
        <div>{{nickname + '你好'}}</div>
        <p>{{age >= 18 ? '成年' : '未成年'}}</p>
        <div>{{friend.name + friend.desc}}</div>
    </div>
    <script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
    <script>
        const app = new Vue({
            el: '#app',//指定vue管理的选择器
            data: {
                msg: 'hello 传智播客',
                count: 666,
                nickname: 'tony',
                age: 19,
                friend: {
                    name: 'pink',
                    desc: '热爱学习vue'
                }
            }
        })
    </script>
</body>
2、vue指令v-前缀,官网文档v-指令。v-XX=“内联语句,计算,比较,函数名等”
<body>
  <!-- v-html功能相当于innerhtml,用来解析H5标签 -->
  <!-- v-show是通过控制css的display: none;来控制元素的显示和隐藏,用于频繁切换的场景 -->
  <!-- v-if是通过渲染来控制,用于不平凡的切换 -->
  <!-- v-on:事件绑定,v-on:可以替换为@。如@click -->
  <!-- v-bind: = :用于标签属性的动态传参,可以简写为:加属性名,如url等 -->
  <!-- v-for="(item,index)in 数组名" 遍历数组。 :key是用来给列表一个唯一标识正确排序,防止错误编码 -->
  <!-- v-model双向数据绑定,视图和数据双向绑定 -->
  <div id="app">
    <div v-html="msg"></div>
    <div v-show="flag" class="box">我是v-show控制的盒子</div>
    <div v-if="score >= 90" class="box">大于等于90</div>
    <div v-else-if="score >= 70" class="box">大于70</div>
    <div v-else class="box">小于70</div>
    <div class="box" v-show="flag">值为{{score}}</div>
    <button class="box" v-on:click="score++">+</button>
    <button class="box" @click="score--">-</button>
    <button class="box" @click="fn">值隐藏</button><br>
    <button @click="buy(5)">可乐5元</button>
    <button @click="buy(10)">咖啡10元</button>
    <img :src="imgUrl" v-bind:title="mmg" alt="">
    <ul>
      <li v-for="(item,index) in list">{{item}}--{{index}}</li>
    </ul>
    输入框<input type="text" v-model="username">
    <button @click="reset">清空</button>
  </div>

  <script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
  <script>
    const app = new Vue({
      el: '#app',
      data: {
        mmg: '哈哈哈哈',
        msg: `<a href="#">学前端~来黑马!</a>`,
        flag: true,
        score: 92,
        imgUrl: './imgs/10-01.png',
        list: ['西瓜', '苹果', '香蕉'],
        username: '哈哈哈'
      },
      methods: {
        fn() {//this指向app,this.flag = app.flag
          this.flag = !this.flag
        },
        buy(a) {
          this.score -= a
        },
        reset() {
          this.username = ''
        }
      }
    })
  </script>
3、指令修饰符

1、事件绑定 @keyup.enter=“add”,监听键盘回车事件,@keyup.键盘=“函数名”
2、v-model修饰符,v-model.number将填写内容字符串转化为数字,v-model.trim清除首尾空格

<input type="text" v-model.number="price" />
//这个判断条件的使用必须基于,v-model.number来判断,否则写入的是数字也无法通过
if (typeof this.price !== 'number') {
            alert('请输入正确的消费价格')
            return
          }

3、@事件名.stop阻止冒泡和@事件名.prevent。如:@click.stop=“add”

4、v-bind操作class和style,后面是单引号
  <div class="box" :class="{ pink: true, big: x >= y }">黑马程序员</div>
  <div class="box" :class="['pink', 'big']">黑马程序员</div>
            注意这里style多个属性是用,连接的
  <div class="inner" 
  :style="{ width: percent + '%',height: percent + '%' }">
        <span>{{ percent }}%</span>
      </div>
5、计算属性 computed ,一定要return返回值
计算属性——>对内部的data值进行求和或计算,在return返回给vue
    <p>礼物总数:{{totalCount}} 个</p>
  </div>
  <script src="./vue.js"></script>
  <script>
    const app = new Vue({
      el: '#app',
      data: {
        // 现有的数据
        list: [
          { id: 1, name: '篮球', num: 1 },
          { id: 2, name: '玩具', num: 2 },
          { id: 3, name: '铅笔', num: 5 },
        ]
      },
      computed: {
      //与data统计
        totalCount() {
          //0是起始值,sum是累加的和
          let total = this.list.reduce((sum, item) => sum + item.num, 0)
          return total
        }
      }
    })
  </script>
6、计算机属性computed与方法methods的区别

computed不用调用可直接计算缓存下来,侧重数据的处理计算,只执行一次

7、计算属性的完整写法computed,get(),set()
  <div id="app">
    姓:<input type="text" v-model="first"><br>
    名:<input type="text" v-model="last"><br>
    <p>姓名:{{full}}</p>
    <button @click="chang">修改姓名</button>
  </div>
  <script src="./vue.js"></script>
  <script>
    const app = new Vue({
      el: '#app',
      data: {
        first: '刘',
        last: '备'
      },
      computed: {
        // full() {
        //   return this.first + this.last
        // }
        full: {
          get() {
            return this.first + this.last
          },
          set(v) {
            this.first = v.slice(0, 1)
            this.last = v.slice(1)
          }
        }
      },
      methods: {
        chang() {
          this.full = '吕小布'
        }
      }
    })
  </script>
8、watch监听器,执行异步操作或业务逻辑
    const app = new Vue({
      el: '#app',
      data: {
        // words: ''
        obj: {
          words: ''
        }
      },
      // 具体讲解:(1) watch语法 (2) 具体业务实现
      watch: {
        // 该方法会在数据变化时调用执行
        // newValue新值, oldValue老值(一般不用)
        // words (newValue) {
        //   console.log('变化了', newValue)
        // }
        'obj.words'(newValue) {
          // console.log('变化了', newValue)
          //防止一段时间内多次请求
          // 防抖: 延迟执行 → 干啥事先等一等,延迟一会,一段时间内没有再次触发,才执行
          clearTimeout(this.timer)
          this.timer = setTimeout(async () => {
            const res = await axios({
              url: 'https://applet-base-api-t.itheima.net/api/translate',
              params: {
                words: newValue
              }
            })
            this.result = res.data.data
            console.log(res.data.data)
          }, 300)
        }
      }
      }
    })
9、watch监听器的完整写法
    const app = new Vue({
      el: '#app',
      data: {
        obj: {
          words: '小黑',
          lang: 'italy'
        },
        result: '', // 翻译结果
      },
      watch: {
        obj: {
          deep: true, // 深度监视,可以监听对象中的所有属性
          immediate: true, // 立刻执行,一进入页面handler就立刻执行一次
          handler(newValue) {
            clearTimeout(this.timer)
            this.timer = setTimeout(async () => {
              const res = await axios({
                url: 'https://applet-base-api-t.itheima.net/api/translate',
                params: newValue
              })
              this.result = res.data.data
              console.log(res.data.data)
            }, 300)
          }
        }
      }
    })
10、生命周期:创建,挂载,更新,销毁(8个钩子函数,一个阶段两个)

关键的两个created(初始化操作),mounted(操作dom)

      //1、创建阶段
      beforeCreate() {
      },
      created() {
      //最重要请求渲染
      },
      //2、挂载阶段
      beforeMount() {
      },
      mounted() {
      //
      },
      //更新阶段
      beforeUpdate() {
      },
      update() {
      },
      //卸载阶段
      beforeDestroy() {
      },
      destroyed() {
      }

created使用发送请求

  <script>
    // 接口地址:http://hmajax.itheima.net/api/news
    // 请求方式:get
    const app = new Vue({
      el: '#app',
      data: {
        list: []
      },
      async created() {
        const res = await axios.get('http://hmajax.itheima.net/api/news')
        this.list = res.data.data
      }
    })
  </script>

mounted使用操作dom

  <script>
    const app = new Vue({
      el: '#app',
      data: {
        words: ''
      },
      mounted() {
        //dom渲染完成输入框获取焦点
        document.querySelector('#inp').focus()
      }
    })
  </script>
11、mounted操作Echarts页面图标的实时更新
methods:{
    async getlist() {
          //重新渲染请求函数
          const res = await axios.get('https://applet-base-api-t.itheima.net/bill', { params: { creator: '换行' } })
          this.list = res.data.data
          //那部分变了就更新哪部分
          this.myC.setOption({
            series: [
              {
                data: this.list.map(item => ({
                  value: item.price, name: item.name
                })
                )
              }
            ]
          })
        }
},
mounted() {
        //操作dom在页面上绘制出图标
        this.myC = echarts.init(document.querySelector('#main'))
        this.myC.setOption({
          title: { //大标题
            text: '消费列表',
            left: 'center'
          },
          tooltip: { //提示框
            trigger: 'item'
          },
          legend: { //图例的对其等
            orient: 'vertical',
            left: 'left'
          },
          series: [
            {
              name: '消费账单',
              type: 'pie',
              radius: '50%', //半径
              data: [
              ],
              emphasis: {
                itemStyle: {
                  shadowBlur: 10,
                  shadowOffsetX: 0,
                  shadowColor: 'rgba(0, 0, 0, 0.5)'
                }
              }
            }
          ]
        })
      }
    })
12、工程化开发模式&手脚架Vue CLI

1、vue create p-name

2、yarn serve 或 npm run serve (找package.json)

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

13、组件化开发&根组件

1、局部注册 组件的注册和使用

<template>
    <div class="App">
        <hmHeader />
        <hmMain></hmMain>
        <hmFooter></hmFooter>
    </div>
</template>

<script>
import hmHeader from './components/hmHeader.vue';
import hmMain from './components/hmMain.vue';
import hmFooter from './components/hmFooter.vue';
export default {
    components: {
        hmHeader: hmHeader,
        hmMain,
        hmFooter
    }
}
</script>

2、全局注册,后全局可直接使用

//main.js文件全局注册
import Vue from 'vue'
import App from './App.vue'
import HmButton from './components/HmButton.vue'

Vue.component('HmButton', HmButton);

Vue.config.productionTip = false

new Vue({
  render: h => h(App),
}).$mount('#app')

14、多个组件的样式冲突问题,加scoped来解决
<style scoped>

</style>
15、data(){ return {} }写成一个函数,防止多次调用同一组件的数据干扰
export default{
    data(){
        return {
            count: 188,
        }
    }
}
16、父子关系的组件通信,数据传递

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传
1、父传子,props: [’ ']

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传
2、子传父,this.$emit('change','传的内容')

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

17、props的校验 props:{ 属性名: 类型 }
props: {
    w: {
      type: Number,
      required: true,//非空校验
      default: 30,//默认值,空值填为默认值
      validator(value) { //自定义校验
        if (value >= 0 && value <= 100) {
          return true
        } else {
          console.error('传入的值必须是0~100的数字')
          return false
        }
      }
    }
  }
18、非父子关系的组件通讯,event bus事件总线,一对多

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

19、v-model=“value"的原理 :value=”"和@input事件的合写

在组件通讯时,用:value接收传来的值

<input type="text" v-model="msg1" />   //相同功能
<input type="text" :value="msg2" @input="msg2 = $event.target.value" />

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

20、.sync修饰符对比v-model的通讯写法

两种简写都是对子组件有命名约束

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

21、ref和$refs获取dom对象,echarts实例

父组件调用子组件的方法
this.$refs.子组件名.子组件的方法()

<template>
  <div class="app">
    <h4>父组件 -- <button>获取组件实例</button></h4>
    <BaseForm ref="baseFrom"></BaseForm>
    <div>
      <button @click="getFormData">获取数据</button>
      <button @click="resetFormData">重置数据</button>
    </div>
  </div>
</template>

<script>
import BaseForm from './components/BaseForm.vue'
export default {
  components: {
    BaseForm,
  },
  methods: {
    getFormData() {
      console.log(this.$refs.baseFrom.getFormData())
    },
    resetFormData() {
      this.$refs.baseFrom.resetValues()
    }
  }
}
</script>

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传
基于准备好的dom,初始化echarts实例

<template>
  <div ref="mychart" class="base-chart-box">子组件</div>
</template>

<script>
import * as echarts from 'echarts'

export default {
  mounted() {
    // 基于准备好的dom,初始化echarts实例
    // const myChart = echarts.init(document.querySelector('.base-chart-box'))
    const myChart = echarts.init(this.$refs.mychart)
    // 绘制图表
    myChart.setOption({
      title: {
        text: 'ECharts 入门示例',
      },
      tooltip: {},
      xAxis: {
        data: ['衬衫', '羊毛衫', '雪纺衫', '裤子', '高跟鞋', '袜子'],
      },
      yAxis: {},
      series: [
        {
          name: '销量',
          type: 'bar',
          data: [5, 20, 36, 10, 10, 20],
        },
      ],
    })
  },
}
</script>

<style scoped>
.base-chart-box {
  width: 400px;
  height: 300px;
  border: 3px solid #000;
  border-radius: 6px;
}
</style>
22、vue异步更新,用 this.$nextTick( () => { })

this.$nextTick( () => { })。等dom更新完成后,再立刻执行this.$nextTick( () => { })中的语句

1、自定义指令,v- 指令
全局注册指令,在main.js中注册
Vue.directive('focus', {
  inserted(el) { //组件插入页面时触发这个钩子
    el.focus()
  }
})
局部注册,组件内部自己使用
<template>
  <div>
    <h1>自定义指令</h1>
    <input v-focus type="text">
  </div>
</template>

<script>
export default {
  directives: {
    focus: {
      inserted(el) {
        el.focus()
      }
    }
  }
}
</script>
自定义指令的传参,数据的绑定,更新
<template>
  <div>
    <h1 v-color="color1">自定义指令1111</h1>
    <h1 v-color="color2">自定义指令2222</h1>
  </div>
</template>

<script>
export default {
  data() {
    return {
      color1: 'red',
      color2: 'green'
    }
  },
  directives: {
    color: {
      inserted(el, binding) { //渲染时的钩子
        el.style.color = binding.value
      },
      update(el, binding) {  //更新时的钩子
        el.style.color = binding.value
      }
    }
  }
}
</script>
常用自定义的指令,v-loading加载展示的指令

加载动画的实现效果

<template>
  <div class="main">
    <div class="box" v-loading="isLodaing"></div>
    <div class="box2" v-loading="is2"></div>
  </div>
</template>

<script>
// 安装axios =>  yarn add axios
import axios from 'axios'

export default {
  data() {
    return {
      list: [],
      isLodaing: true,
      is2: true
    }
  },
  async created() {
    const res = await axios.get('http://hmajax.itheima.net/api/news')
    setTimeout(() => {
      // 2. 更新到 list 中
      this.list = res.data.data
      this.isLodaing = false
    }, 2000)
  },
  directives: {
    loading: {
      inserted(el, binding) {
        binding.value ? el.classList.add('loading') : el.classList.remove('loading')
      },
      update(el, binding) {
        binding.value ? el.classList.add('loading') : el.classList.remove('loading')
      }
    }
  }
}
</script>

<style>
/* 伪类 - 蒙层效果 */
.loading:before {
  content: '';
  position: absolute;
  left: 0;
  top: 0;
  width: 100%;
  height: 100%;
  background: #fff url('./loading.gif') no-repeat center;
}

2、插槽,让组件的内部的一些结构支持自定义,(如文字,样式等)
1、定义,使用方法

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传
外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

2、默认值,<solt>默认值</solt>后备内容

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

3、具名插槽,一个组件需要多个地方要定制,就要给<slot name="">定义名字

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

4、作用域插槽,定义slot的同时,是可以传递数据的

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

3、路由VueRouter的使用

在main.js中注册
外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

1、自定义匹配的类名,高亮选择的类名

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

2、声明式导航跳转传参

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传
记得加?号{ path: '/search/:words?', component: Search },
外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

3、路由重定向,起始页面的配置,{path: '/',redirect: '/home'}

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

4、vue路由404,{path: '*',component: NotFind}

要建立NotFind.vue文件,展示此文件的页面
外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

5、去出导航的#,转换为历史路由

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传
外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

6、编程式导航-基本跳转-传参

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传
外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传
外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

7、二级路由,子路由,children: [{path: ,component: }]

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

8、返回上一页

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

9、动态传参

静态用query
外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传
外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

4、@绝对路径,@/ = src/ 。 就是从src出发
Logo

AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。

更多推荐