当前位置: 首页 > news >正文

培训类网站开发推广自己的网站

培训类网站开发,推广自己的网站,在线商城app下载,哪个网站能看到学做标书一、Vue 文章目录 一、Vue1、vue 修改数据页面不重新渲染**数组/对象的响应式 #xff0c;vue 里面是怎么处理的#xff1f;** 2、生命周期Vue 生命周期都有哪些#xff1f;父子组件生命周期执行顺序 3、watch 和 computed 的区别4、组件通信#xff08;组件间传值#xf…一、Vue 文章目录 一、Vue1、vue 修改数据页面不重新渲染**数组/对象的响应式 vue 里面是怎么处理的** 2、生命周期Vue 生命周期都有哪些父子组件生命周期执行顺序 3、watch 和 computed 的区别4、组件通信组件间传值5、$nextTick6、修饰符事件修饰符v-bind 修饰符鼠标修饰符表单相关修饰符系统修饰符按键修饰符 7、图片上传 TODO⭐⭐8、v-for 和 v-if / v-if 和 v-show9、Vue.use()10、 跨域**什么是跨域**跨域解决方法 1-代理跨域解决方法 2-CORS跨域解决方法 3-JSONP 11、cookie12、[keep-alive 原理](https://blog-1gxfs2h1401f4f58-1254415986.tcloudbaseapp.com/%E9%9D%A2%E8%AF%95%E9%A2%98%E7%B3%BB%E5%88%97/%E4%BA%8C%E3%80%81%E5%AF%B9keep-alive%E7%9A%84%E7%90%86%E8%A7%A3.html#%E5%8E%9F%E7%90%86)keep-alive 是什么**使用场景**缓存后如何获取数据 13、ref14、scoped 原理是什么15、$router 和 $route16、[发布订阅模式和观察者模式](https://juejin.cn/post/7055441354054172709#heading-3)发布订阅模式观察者模式总结 17、[vue 响应式原理数据劫持](https://blog-1gxfs2h1401f4f58-1254415986.tcloudbaseapp.com/vue%E5%8E%9F%E7%90%86/vue2%E5%8E%9F%E7%90%86/1.%E5%93%8D%E5%BA%94%E5%BC%8F%E5%8E%9F%E7%90%86.html)18、eventBus19、v-model 与.sync20、如何做样式穿透21、你对SPA单页面的理解它的优缺点分别是什么单页应用优缺点 22、怎么理解 Vue 的单向数据流 二、JS1、手动实现防抖和节流2、let、const、var 的区别3、箭头函数与普通函数区别4、Promise5、数据类型6、检测数据类型的常用方法1 .typeof**2 . instanceof****3 .constructor****4 . 使用 Object.prototype.toString.call()检测对象类型**⭐**5 . 自己封装函数****6、isArray** 7、数组的常用方法有哪些一、操作方法增删改查 二、排序方法reverse()sort() 三、转换方法join() 四、迭代方法some()every()forEach()filter()map() 8、深浅拷贝深拷贝和浅拷贝的区别浅拷贝深拷贝 9、闭包10、数组去重**Set 去重**indexOf 去重splice 去重includes 去重**filter 去重****findIndex**数组对象去重**Map**数组对象去重reduce 数组对象去重lodash 库数组和数组对象去重: 11、逻辑运算符 和 ||12、new 的过程13、事件循环 Event Loop 结合着14条讲14、async 和 await 宏任务 和 微任务宏任务 和 微任务1、什么是宏任务和微任务2、宏任务和微任务的执行顺序 async与awaitasyncawait 15、**call、apply、bind 的区别**16、继承Class 继承ES5 继承 17、原型链18、堆和栈 TODO ⭐⭐19、ES6 Set 和 Map TODO ⭐⭐20、**includes**21、**find** 三、Git1、列举工作中常用的几个 git 命令 四、HTML-C31、盒子水平垂直局中的方法flex 布局**Position Transform**利用**Position** **margin:auto****inline-block****table 布局**总结内联元素居中布局块级元素居中布局 2、BFC经典面试题3、盒模型4、flex15、c3 新属性6、 五、HTTPHTTP 缓存HTTP 状态码信息响应成功的响应重定向客户端错误服务端错误 5、c3 新属性6、 五、HTTPHTTP 缓存HTTP 状态码信息响应成功的响应重定向客户端错误服务端错误 1、vue 修改数据页面不重新渲染 vue2是用过Object.defineProperty实现数据响应式, 组件初始化时对 data 中的 item 进行递归遍历对 item 的每一个属性进行劫持添加 set , get 方法。我们后来 新加的属性 并没有通过Object.defineProperty设置成响应式数据修改后不会视图更新。 通过数组索引号修改了数组界面会不会相应更新为什么 答不会。vue 监听不到 vue 为什么没有提供 arr[下标] val 变成响应式 尤大“因为性能问题性能代价和获得的用户体验收益不成正比” 数组/对象的响应式 vue 里面是怎么处理的 对象使用了Object.defineProperty中的 get 和 set 如何监测对象中的数据 通过 setter 实现监视且要在 new Vue 时就传⼊要监测的数据 对象中后追加的属性Vue 默认不做响应式处理如需给后添加的属性做响应式请使⽤如下 API Vue.set(target,propertyName/index,value) vm.$set(target,propertyName/index,value) 数组 Vue重写了数组的原型更准确的表达是拦截了数组的原型 如何监测数组中的数据 通过包裹数组更新元素的⽅法实现本质就是做了两件事 调⽤原⽣对应的⽅法对数组进⾏更新 重新解析模板进⽽更新⻚⾯ 在 Vue 修改数组中的某个元素⼀定要⽤如下⽅法 使 ⽤ 这 些 API push() pop() shift() unshift() splice() sort() reverse()Vue.set() 或 vm.$set()覆盖整个数组 为什么对象和数组要分开处理? 对象的属性通常比较少对每一个属性都劫持set和get并不会消耗很多性能 数组有可能有成千上万个元素如果每一个元素都劫持set和get无疑消耗太多性能了 所以对象通过defineProperty进行正常的劫持set和get 数组则通过修改数组原型上的部分方法来实现修改数组触发响应式 2、生命周期 Vue 生命周期都有哪些 生命周期执行时机beforeCreate在组件实例被创建之初、组件的属性⽣效之前被调用created在组件实例已创建完毕。此时属性也已绑定但真实 DOM 还未⽣成$el 还不可⽤beforeMount在组件挂载开始之前被调⽤。相关的 render 函数⾸次被调⽤mounted在 el 被新建的 vm.$el 替换并挂载到实例上之后被调用beforeUpdate在组件数据更新之前调⽤。发⽣在虚拟 DOM 打补丁之前update在组件数据更新之后被调用activited在组件被激活时调⽤使用了 keep-alive 的情况下deactivated在组件被销毁时调⽤使用了 keep-alive 的情况下beforeDestory在组件销毁前调⽤destoryed在组件销毁后调⽤ 父子组件生命周期执行顺序 加载渲染过程 -父beforeCreate-父created-父beforeMount-子beforeCreate-子created-子beforeMount-子mounted-父mounted更新过程 父beforeUpdate-子beforeUpdate-子updated-父updated销毁过程 父beforeDestroy-子beforeDestroy-子destroyed-父destroyedkeep-alive可以实现组件缓存当组件切换时不会对当前组件进行卸载 https://juejin.cn/post/6844903641866829838#heading-11 https://juejin.cn/post/7114252241166401573 3、watch 和 computed 的区别 官方文档对于任何复杂逻辑你都应当使用计算属性 扩展vue 中 Computed、Methods、Watch 区别 computed计算属性watch监视属性/侦听器根据你所依赖的数据动态显示新的计算结果不用再 data 中声明否则报错data 的数据监听回调,依赖 data 的数据变化直接使用 data 声明的数据支持缓存不支持缓存不支持异步支持异步有 get 和 set 方法当数据变化时调用 set 方法可以深度监视 deep,加载就调用 immediate监听的函数接收两个函数newVal 和 oldVla当需要进行数值计算并且依赖于其它数据时用 computed在某个数据变化时做一些事情或需要异步操作时用 watchcomputed 能做的watch 都能做到 4、组件通信组件间传值 props $emit.sync v-model$parent / $children $parent 获取父组件的实例任意调用父组件的方法修改父组件的数据ref 父组件获取子组件实例任意调用子组件的方法获取子组件的属性provide / injectprpvide 父组件内部提供数据 inject 嵌套的子组件可以注入数据$attrs / $listeners $attrs(没有被 props 接收的所有自定义属性) $listeners(可以获取所有的父组件传递过来的自定义事件)eventBus 定义一个事件总线 使用$on 绑定 $emit 触发vuex路由传参 https://www.wpgdadatong.com/cn/blog/detail?BIDB3650 https://juejin.cn/post/7110223595359436813 5、$nextTick NextTick 是什么 在下次 DOM 更新循环结束之后执行延迟回调。在修改数据之后立即使用这个方法获取更新后的 DOM // 修改数据 this.message 修改后的值; // 此时DOM还没有更新 console.log(this.$el.textContent); // 原始的值 this.$nextTick(function () {// DOM 更新了console.log(this.$el.textContent); // 修改后的值 });6、修饰符 引用https://juejin.cn/post/7026867875990208543#heading-22 事件修饰符 stop stop修饰符的作用是阻止冒泡 prevent⭐ prevent修饰符的作用是阻止默认事件例如 a 标签的跳转 capture 事件流默认冒泡使用 capture 进行捕获捕获 self self修饰符作用是只有点击事件绑定的本身才会触发事件 once once修饰符的作用是事件只执行一次 native⭐ native修饰符是加在自定义组件的事件上保证事件能执行native是用来是在父组件中给子组件绑定一个原生的事件就将子组件变成了普通的 HTML 标签看待 passive 当我们在监听元素滚动事件的时候会一直触发 onscroll 事件在 pc 端是没啥问题的但是在移动端会让我们的网页变卡因此我们使用这个修饰符的时候相当于给 onscroll 事件整了一个.lazy 修饰符 v-bind 修饰符 sync⭐ 当父组件传值进子组件子组件想要改变这个值时可以这么做 // 父组件里 children :foo.syncbar/children // 子组件里 this.$emit(update:foo, newValue)camel .camel 修饰符允许在使用 DOM 模板时将 v-bind property 名称驼峰化例如 SVG 的 viewBox property svg :view-box.camelviewBox/svg鼠标修饰符 left right middle 这三个修饰符是鼠标的左中右按键触发的事件 表单相关修饰符 trim⭐ trim修饰符的作用类似于 JavaScript 中的trim()方法作用是把v-model绑定的值的首尾空格给过滤掉。 lazy lazy修饰符作用是改变输入框的值时 value 不会改变当光标离开输入框时v-model绑定的值 value 才会改变 number number修饰符的作用是将值转成数字但是先输入字符串和先输入数字是两种情况 先输入数字的话只取前面数字部分 先输入字母的话number修饰符无效 系统修饰符 .ctrl、.alt、.shift、.meta 按键修饰符 配合键盘事件使用: .enter .tab .delete .esc .space .up .down left… 7、图片上传 TODO⭐⭐ FileReader 与 URL.createObjectURL 实现图片、视频上传预览 event.target.files 就是用户上传的图片信息 配合 cropperjs 可以实现图片裁剪功能 // 如果接口要求 Content-Type 是 multipart/form-data // 则你必须传递 FormData 对象8、v-for 和 v-if / v-if 和 v-show 为什么 v-if 和 v-for 不能同时使用 v-if 不能和 v-for 一起使用的原因是 v-for 的优先级比 v-if 高一起使用会造成性能浪费 解决方案有两种把 v-if 放在 v-for 的外层或者把需要 v-for 的属性先从计算属性中过滤一次 v-if 和 v-for 的优先级问题在 vue3 中不需要考虑vue3 更新了 v-if 和 v-for 的优先级使 v-if 的优先级高于 v-for v-if 和 v-show v-show隐藏则是为该元素添加display:none。v-if是将dom元素整个添加或删除 v-show 由false变为true的时候不会触发组件的生命周期v-if由false变为true的时候触发组件的beforeCreate、create、beforeMount、mounted钩子由true变为false的时候触发组件的beforeDestory、destoryed方法 性能消耗v-if有更高的切换消耗v-show有更高的初始渲染消耗 如果需要非常频繁地切换则使用 v-show 较好 如果在运行时条件很少改变则使用 v-if 较好 9、Vue.use() Vue.use是用来安装插件的 用法Vue.use(plugin) 如果插件是一个对象必须提供 install 方法。如果插件是一个函数它会被作为 install 方法。install 方法调用时会将 Vue 作为参数传入。Vue.use(plugin)调用之后插件的 install 方法就会默认接受到一个参数这个参数就是 Vue 总结Vue.use 是官方提供给开发者的一个 api用来注册、安装类似 Vuex、vue-router、ElementUI 之类的插件的。 10、 跨域 什么是跨域 跨域问题是浏览器的同源策略所导致的 其中域名、协议、端口号相同称之为同源如果不同称之为跨源或跨域 跨域常见的解决方法 代理常用CORS常用JSONP 跨域解决方法 1-代理 代理适用的场景是生产环境不发生跨域但开发环境发生跨域 因此只需要在开发环境使用代理解决跨域即可这种代理又称之为开发代理 在实际开发中只需要对开发服务器稍加配置即可完成 // vue 的开发服务器代理配置 // vue.config.js module.exports {devServer: {// 配置开发服务器proxy: {// 配置代理/api: {// 若请求路径以 /api 开头target: http://dev.taobao.com, // 将其转发到 http://dev.taobao.com},},}, };跨域解决方法 2-CORS 阮一峰 CORS: https://www.ruanyifeng.com/blog/2016/04/cors.html CORS是基于http1.1的一种跨域解决方案它的全称是Cross-Origin Resource Sharing跨域资源共享。 CORS 需要浏览器和后端同时支持。 整个 CORS 通信过程都是浏览器自动完成不需要用户参与。对于开发者来说CORS 通信与同源的 AJAX 通信没有差别代码完全一样。浏览器一旦发现 AJAX 请求跨源就会自动添加一些附加的头信息有时还会多出一次附加的请求但用户不会有感觉。 因此实现 CORS 通信的关键是服务器。只要服务器实现了 CORS 接口就可以跨源通信。 浏览器将 CORS 请求分成两类简单请求simple request和非简单请求not-so-simple request 只要同时满足以下两大条件就属于简单请求。 凡是不同时满足下面两个条件就属于非简单请求。 1) 请求方法是以下三种方法之一 HEADGETPOST 2HTTP 的头信息不超出以下几种字段 AcceptAccept-LanguageContent-LanguageLast-Event-IDContent-Type只限于三个值application/x-www-form-urlencoded、multipart/form-data、text/plain 跨域解决方法 3-JSONP JSONP 的做法是当需要跨域请求时不使用 AJAX转而生成一个 script 元素去请求服务器由于浏览器并不阻止 script 元素的请求这样请求可以到达服务器。服务器拿到请求后响应一段 JS 代码这段代码实际上是一个函数调用调用的是客户端预先生成好的函数并把浏览器需要的数据作为参数传递到函数中从而间接的把数据传递给客户端 JSONP 优点是简单兼容性好可用于解决主流浏览器的跨域数据访问的问题。缺点是仅支持 get 方法具有局限性,不安全可能会遭受 XSS 攻击。 11、cookie 什么是 cookie cookie 是储存在用户本地终端上的数据是网站为了识别用户和跟踪会话而存储在用户本地终端中的文本数据 怎么操作 可以使用js-cookie插件 模块化开发时直接引入import Cookies from js-cookie js-cookie.js 常用的 API 和方法 设置 cookie Cookies.set(name, value, { expires: 7, path: }); //7天过期 Cookies.set(name, { foo: bar }); //设置一个json读取 cookie Cookies.get(name); //获取cookie Cookies.get(); //读取所有的cookie删除 cookie Cookies.remove(name); //删除cookie时必须是同一个路径。12、keep-alive 原理 keep-alive 是什么 vue 自带的组件 主要功能是缓存组件 提升性能使用场景可以少网络请求如果当前组件数据量比较大就可以节省网络请求 提升用户体验举例如果详情页面之间进行切换就可以使用keep-alive进行缓存组件防止同样的数据重复请求 keep-alive 包裹动态组件时会缓存不活动的组件实例而不是销毁它们 keep-alive可以设置以下props属性 include - 字符串或正则表达式。只有名称匹配的组件会被缓存exclude - 字符串或正则表达式。任何名称匹配的组件都不会被缓存max - 数字。最多可以缓存多少组件实例 关于keep-alive的基本用法 keep-alivecomponent :isview/component /keep-alive匹配首先检查组件自身的 name 选项如果 name 选项不可用则匹配它的局部注册名称 (父组件 components 选项的键值)匿名组件不能被匹配 设置了 keep-alive 缓存的组件会多出两个生命周期钩子activated与deactivated 首次进入组件时beforeRouteEnter beforeCreate created mounted activated … … beforeRouteLeave deactivated再次进入组件时beforeRouteEnter activated … … beforeRouteLeave deactivated 使用场景 使用原则当我们在某些场景下不需要让页面重新加载时我们可以使用keepalive 举个栗子: 当我们从首页–列表页–商详页–再返回这时候列表页应该是需要keep-alive 从首页–列表页–商详页–返回到列表页(需要缓存)–返回到首页(需要缓存)–再次进入列表页(不需要缓存)这时候可以按需来控制页面的keep-alive 在路由中设置keepAlive属性判断是否需要缓存 {path: list,name: itemList, // 列表页component (resolve) {require([/pages/item/list], resolve)},meta: {keepAlive: true,title: 列表页} }使用keep-alive div idapp classwrapperkeep-alive!-- 需要缓存的视图组件 --router-view v-if$route.meta.keepAlive/router-view/keep-alive!-- 不需要缓存的视图组件 --router-view v-if!$route.meta.keepAlive/router-view /div缓存后如何获取数据 解决方案可以有以下两种 beforeRouteEnteractived 13、ref 作用 放到 dom 节点上 获取原生 dom组件身上 获取组件实例 可以获取组件内部所有的方法和数据 14、scoped 原理是什么 作用使样式私有化模块化不对全局造成污染 原理动态的给组件加上一个 hash 值用属性选择器去匹配 15、$router 和 $route $route当前的路由信息对象获取到路由参数、路径 $route.path 字符串对应当前路由的路径总是解析为绝对路径如/foo/bar。$route.params 一个 key/value 对象包含了 动态片段 和 全匹配片段如果没有路由参数就是一个空对象。** r o u t e . q u e r y ∗ ∗ 一个 k e y / v a l u e 对象表示 U R L 查询参数。例如对于路径 / f o o ? u s e r 1 则有 route.query** 一个 key/value 对象表示 URL 查询参数。例如对于路径 /foo?user1则有 route.query∗∗一个key/value对象表示URL查询参数。例如对于路径/foo?user1则有route.query.user 1如果没有查询参数则是个空对象。$route.hash 当前路由的 hash 值 (不带#) 如果没有 hash 值则为空字符串。锚点$route.fullPath 完成解析后的 URL包含查询参数和 hash 的完整路径。$route.matched 数组包含当前匹配的路径中所包含的所有片段所对应的配置参数对象。$route.name 当前路径名字$route.meta 路由元信息 ** r o u t e r ∗ ∗ 全局路由 v u e R o u t e r 的实例挂载到 V u e 原型上 router**全局路由 vueRouter 的实例挂载到 Vue 原型上 router∗∗全局路由vueRouter的实例挂载到Vue原型上router 属性可以获取到全局路由配置信息跳转方法 $router.replace({path:‘home’})//替换路由没有历史记录 $router.push(‘/login’) ,跳转到指定路由 $router.back() $router.go() 16、发布订阅模式和观察者模式 发布订阅模式 发布订阅模式中有三个角色发布者 Publisher 信息中心 Event Channel 订阅者 Subscriber 。 我们假定存在一个信号中心某个任务执行完成就向信号中心发布publish一个信号其他任务可以向信号中心订阅subscribe这个信号从而知道什么时候自己可以开始执行。这就叫做发布/订阅模式publish-subscribe pattern) 通常是通过 on 事件订阅消息emit 事件发布消息remove 事件删除订阅 class PubSub {constructor() {// 事件中心// 存储格式: warTask: [], routeTask: []// 每种事件(任务)下存放其订阅者的回调函数this.events {};}// 订阅方法subscribe(type, cb) {if (!this.events[type]) {}this.events[type].push(cb);}// 发布方法publish(type, ...args) {if (this.events[type]) {this.events[type].forEach((cb) cb(...args));}}// 取消订阅方法unsubscribe(type, cb) {if (this.events[type]) {const cbIndex this.events[type].findIndex((e) e cb);if (cbIndex ! -1) {this.events[type].splice(cbIndex, 1);}}if (this.events[type].length 0) {delete this.events[type];}}unsubscribeAll(type) {if (this.events[type]) {delete this.events[type];}} }观察者模式 当对象之间存在一对多的依赖关系时其中一个对象的状态发生改变所有依赖它的对象都会收到通知这就是观察者模式 观察者(订阅者) – Watcher update()当事件发生时具体要做的事情 目标(发布者) – Dep subs 数组存储所有的观察者addSub()添加观察者notify()当事件发生调用所有观察者的 update() 方法 没有事件中心 总结 设计模式观察者模式发布订阅模式主体Watcher 观察者、Dep 目标对象Publisher 发布者、Event Channel 信息中心、Subscribe 订阅者主体关系Dep 中通过 subs 记录 WatcherPublisher 和 Subscribe 不想不知道对方通过中介联系优点角色明确Watcher 和 Dep 要遵循约定的成员方法松散耦合灵活度高通常应用在异步编程中缺点紧耦合当事件类型变多时会增加维护成本使用案例双向数据绑定事件总线 EventBus 17、vue 响应式原理数据劫持 18、eventBus 19、v-model 与.sync 相同点都是语法糖都可以实现父子组件中的数据的双向通信。 // v-model son v-modelnum/ //父组件使用子组件 model:{prop:newValue, // 默认为 value 可以使用prop自定义属性名event:updateValue, // event 修改事件名 默认为input }, props: { // 子组件接收value: { // 默认为valuetype: Number,} } // .sync son :title.syncdoc.title/son // 父组件 props:{title:{type:...} } this.$emit(update:title, newTitle) // 子组件区别点格式不同 v-model“num”, :num.sync“num” v-model input value :num.sync: update:num 另外需要特别注意的是: v-model只能用一次.sync可以有多个 20、如何做样式穿透 背景修改当前组件嵌套的子组件内部的样式 问题 如果不添加 scoped可能影响全局样式如果添加 scoped嵌套的子组件内部样式不能生效 如何解决添加/deep/ / ::v-deep scss: 使用::v-deep less: 使用 /deep/ 21、你对SPA单页面的理解它的优缺点分别是什么 SPA single-page application 仅在 Web 页面初始化时加载相应的 HTML、JavaScript 和 CSS。一旦页面加载完成SPA 不会因为用户的操作而进行页面的重新加载或跳转取而代之的是利用路由机制实现 HTML 内容的变换UI 与用户的交互避免页面的重新加载。 单页应用优缺点 优点 具有桌面应用的即时性、网站的可移植性和可访问性用户体验好、快内容的改变不需要重新加载整个页面SPA 相对对服务器压力小良好的前后端分离分工更明确 缺点 SEO搜索引擎难度较大首次渲染速度相对较慢前进后退路由管理由于单页应用在一个页面中显示所有的内容所以不能使用浏览器的前进后退功能所有的页面切换需要自己建立堆栈管理 22、怎么理解 Vue 的单向数据流 ①单向数据流是指数据从父组件传向子组件子组件没有权限直接修改该数据 ②子组件需要在 data 或者 computed 中重新定义变量来接收父组件传来的值以便修改 ③子组件可以通过 $emit 的方式通知父组件修改值再重新传回给子组件 二、JS 1、手动实现防抖和节流 防抖在限定时间内总是执行最后一次 ( 类似回城打断就得重新回 ) 节流在限定时间内只会执行第一次 ( 类似技能需要冷却时间到了才能用 ) /*** debounce 防抖* param fn [function] 需要防抖的函数* param delay [number] 毫秒防抖期限值*/ function debounce(fn, delay) {let timer null; //借助闭包return function (...arg) {if (timer) {//进入该分支语句说明当前正在一个计时过程中并且又触发了相同事件。// 所以要取消当前的计时重新开始计时clearTimeout(timer);}timer setTimeout(() {fn.apply(this, arg); // 使用apply将fn函数的this指向修改为return后的function}, delay); // 进入该分支说明当前并没有在计时那么就开始一个计时}; } /*** debounce 节流* param fn [function] 需要节流的函数* param delay [number] 毫秒*/ function throttle(fn, delay) {let valid false; // 节流阀return function (...arg) {if (valid) {//休息时间 暂不接客return;}// 工作时间执行函数并且在间隔期内把状态位设为无效valid true;setTimeout(() {fn.apply(this, arg);valid false;}, delay);}; }2、let、const、var 的区别 1.是否存在变量提升 var声明的变量存在变量提升将变量提升到当前作用域的顶部。即变量可以在声明之前调用值为undefined let和const不存在变量提升。即它们所声明的变量一定要在声明后使用否则报ReferenceError错 2.是否存在暂时性死区 let和const存在暂时性死区。即只要块级作用域内存在 let 命令它所声明的变量就“绑定”binding这个区域不再受外部的影响 3.是否允许重复声明变量 var允许重复声明变量。 let和const在同一作用域不允许重复声明变量。 4.是否存在块级作用域 var 不存在块级作用域。let 和 const 存在块级作用域。 块作用域由{ }包括if语句和for语句里面的{ }也属于块作用域 5. 是否能修改声明的变量 var和let可以。const声明一个只读的常量。一旦声明常量的值就不能改变。const声明的变量不得改变值这意味着const一旦声明变量就必须立即初始化不能留到以后赋值。 3、箭头函数与普通函数区别 1.箭头函数是匿名函数不能作为构造函数不能使用 new 2.箭头函数内没有arguments可以用展开运算符...解决 3.箭头函数的 this始终指向父级上下文箭头函数的this取决于定义位置父级的上下文跟使用位置没关系普通函数this指向调用的那个对象 4.箭头函数不能通过call() 、 apply() 、bind()方法直接修改它的 this 指向。(call、apply、bind会默认忽略第一个参数但是可以正常传参) 5.箭头函数没有原型属性 4、Promise 状态 进行中pending 已成功resolved 已失败rejected 特点 对象的状态不受外界影响 一旦状态改变就不会再变任何时候都可得到这个结果 声明new Promise((resolve, reject) {}) 出参 resolve将状态从未完成变为成功在异步操作成功时调用并将异步操作的结果作为参数传递出去 reject将状态从未完成变为失败在异步操作失败时调用并将异步操作的错误作为参数传递出去 ① 什么是 Promise Promise简单说就是一个容器包含异步操作结果的对象从语法上说promise 是一个对象从它可以获取异步操作的的最终状态成功或失败。Promise 是一个构造函数对外提供统一的 API自己身上有 all、reject、resolve 等方法原型上有 then、catch 等方法。 ② Promise 有什么用 解决回调地狱 ③Promise 有哪些方法 **then()**分别指定resolved状态和rejected状态的回调函数 第一参数状态变为resolved时调用 第二参数状态变为rejected时调用(可选) 链式调用 promise.then()then 方法返回一个 Promise 对象其允许方法链从而创建一个 promise 链 catch()指定发生错误时的回调函数 Promise.resolve()将对象转为 Promise 对象 等价于 new Promise(resolve resolve()) Promise 实例原封不动地返回入参 thenable 对象 thenable对象指的是具有then方法的对象 Promise.resolve方法会将这个对象转为 Promise 对象然后就立即执行thenable对象的then方法 不具有 then()的对象将此对象转为 Promise 对象并返回状态为resolved 不带参数返回 Promise 对象状态为resolved Promise.reject()将对象转为状态为rejected的 Promise 对象(等价于new Promise((resolve, reject) reject())) Promise.all() 并发发起多个并发请求将多个实例包装成一个新实例数组形式然后在所有 promise 都被解决后执行一些操作(齐变更再返回) 成功只有全部实例状态变成fulfilled 成功 最终状态才会变成fulfilled失败其中一个实例状态变成rejected最终状态就会变成rejected每一个 promise 成功的值会按照传入的顺序返回数组内用 all 方法进行接口请求就算其中有失败的情况别的请求也会进行但最后的状态还是rejected Promise.race() 赛跑机制 将多个实例包装成一个新实例返回全部实例状态优先变更后的结果(先变更先返回) 成功失败哪个实例率先改变状态就返回哪个实例的状态 Promise.finally()指定不管最后状态如何都会执行的回调函数**Promise.allSettled()**⭐将多个实例包装成一个新实例返回全部实例状态变更后的状态数组(齐变更再返回) 成功成员包含status和valuestatus为fulfilledvalue为返回值失败成员包含status和valuestatus为rejectedvalue为错误原因 Promise.any()将多个实例包装成一个新实例返回全部实例状态变更后的结果数组(齐变更再返回) 成功其中一个实例状态变成fulfilled最终状态就会变成fulfilled 失败只有全部实例状态变成rejected最终状态才会变成rejected Promise.try()不想区分是否同步异步函数包装函数为实例使用then()指定下一步流程使用catch()捕获错误 常见的错误 Uncaught TypeError: undefined is not a promise 如果在控制台中收到 Uncaught TypeError: undefined is not a promise 错误则请确保使用 new Promise() 而不是 Promise() UnhandledPromiseRejectionWarning 这意味着调用的 promise 被拒绝但是没有用于处理错误的 catch。 在 then 之后添加 catch 则可以正确地处理 扩展手写 Promise 5、数据类型 原始数据类型基本类型按值访问可以操作保存在变量中实际的值。 空值null用于未知的值 —— 只有一个 null 值的独立类型。未定义undefined: 用于未定义的值 —— 只有一个 undefined 值的独立类型。布尔值boolean用于 true 和 false。数字number用于任何类型的数字整数或浮点数在 ±(253-1) 范围内的整数。字符串string用于字符串一个字符串可以包含 0 个或多个字符所以没有单独的单字符类型。符号symbol:用于唯一的标识符。 引用类型复杂数据类型引用类型的值是保存在内存中的对象。 对象Object 数组对象Array函数对象Function布尔对象Boolean数字对象Number字符串对象String日期对象Date正则对象RegExp错误对象Error ⚠️ 注意 与其他语言不同的是JavaScript 不允许直接访问内存中的位置也就是说不能直接操作对象的内存空间。在操作对象时实际上是在操作对象的引用而不是实际的对象。所以引用类型的值是按引用访问的。 6、检测数据类型的常用方法 typeof、instanceof、constructor、Object.prototype.toString.call() 1 .typeof console.log(typeof 100, //numbertypeof undefined, //undefinedtypeof null, //objecttypeof function () {console.log(aaa);}, //functiontypeof new Number(100), //objecttypeof new String(abc), // stringtypeof new Boolean(true) //boolean );typeof 可以正常检测出number、boolean、string、object、function、undefined、symbol、bigint 检测基本数据类型null 会检测 object因为 null 是一个空的引用对象检测复杂数据类型除 function 外均为 object 2 . instanceof instanceof运算符需要指定一个构造函数或者说指定一个特定的类型用来判断这个构造函数的原型是否在给定对象的原型链上 基本数据类型中NumberStringBoolean。字面量值不可以用 instanceof 检测但是构造函数创建的值可以 注意null 和 undefined 都返回了 false这是因为它们的类型就是自己本身并不是 Object 创建出来它们所以返回了 false。 console.log(100 instanceof Number, //falseundefined instanceof Object, //false[1, 2, 3] instanceof Array, //truenew Error() instanceof Error //true );3 .constructor constructor 是 prototype 对象上的属性指向构造函数。根据实例对象寻找属性的顺序若实例对象上没有实例属性或方法时就去原型链上寻找因此实例对象也是能使用 constructor 属性的。可以检测出字面量方式创建的对象类型 如果输出一个类型的实例的 constructor就如下所示 console.log(new Number(123).constructor); //ƒ Number() { [native code] }可以看到它指向了 Number 的构造函数因此可以使用num.constructor Number来判断一个变量是不是 Number 类型的 除了 undefined 和 null 之外其他类型都可以通过 constructor 属性来判断类型。 var num 123; var str abcdef; var bool true; var arr [1, 2, 3, 4];// undefined和null没有constructor属性 console.log(num.constructor Number,str.constructor String,bool.constructor Boolean,arr.constructor Array ); //所有结果均为true4 . 使用 Object.prototype.toString.call()检测对象类型⭐ const toString Object.prototype.toString;toString.call(123); //[object Number] toString.call(undefined); //[object Undefined] toString.call(null); //[object Null] toString.call(/^[a-zA-Z]{5,20}$/); //[object RegExp] toString.call(new Error()); //[object Error]可以使用Object.prototype.toString.call(obj).slice(8-1)来判断并截取 使用Object.prototype.toString.call()的方式来判断一个变量的类型是最准确的方法 5 . 自己封装函数 function getType(obj) {const type typeof obj;if (type ! object) {return type;}//如果不是object类型的数据直接用typeof就能判断出来//如果是object类型数据准确判断类型必须使用Object.prototype.toString.call(obj)的方式才能判断return Object.prototype.toString.call(obj).replace(/^\[object (\S)]$/, $1); }6、isArray isArray 可以检测出是否为数组 const arr []; Array.isArray(arr); // true7、数组的常用方法有哪些 一、操作方法 增 下面前三种是对原数组产生影响的增添方法第四种则不会对原数组产生影响 push( ) unshift( ) splice( ) concat( ) push() push()方法接收任意数量的参数并将它们添加到数组末尾返回数组的最新长度 unshift() unshift()在数组开头添加任意多个值然后返回新的数组长度 splice 传入三个参数分别是开始位置、0要删除的元素数量、插入的元素返回的是空数组 concat() 合并 首先会创建一个当前数组的副本然后再把它的参数添加到副本末尾最后返回这个新构建的数组不会影响原始数组 let colors [red].concat(yellow, [black]);// [red, yellow, black] 删 下面三种都会影响原数组最后一项不影响原数组 pop() shift() splice() slice() pop() pop() 方法用于删除数组的最后一项同时减少数组的length 值返回被删除的项 shift() shift()方法用于删除数组的第一项同时减少数组的length 值返回被删除的项 splice() 传入两个参数分别是开始位置删除元素的数量返回包含删除元素的数组 slice() slice(开始索引, 结束索引) 返回一个新数组不会影响原始数组 改 即修改原来数组的内容常用splice splice() 传入三个参数分别是开始位置要删除元素的数量要插入的任意多个元素)返回删除元素的数组 会改变原数组 查 查找元素返回元素坐标或者元素值 indexOf( ) includes( ) find( ) indexOf() 返回要查找的元素在数组中的位置如果没找到则返回 -1 includes() 返回要查找的元素在数组中的位置找到返回true否则false find() 返回第一个匹配的元素 二、排序方法 reverse()sort() reverse() 翻转 sort() 排序 function sortArr(a, b) {return a - b; // 升序return b - a; // 降序 }三、转换方法 join() join() 方法接收一个参数即字符串分隔符返回包含所有项的字符串转为字符串 四、迭代方法 常用来迭代数组的方法除 forEach 外其他都不会对空数组进⾏检测、不会改变原始数组有如下 some() every() forEach() filter() map() some() 对数组每一项都运行传入的测试函数如果至少有 1 个元素返回 true 则这个方法返回 true every() 对数组每一项都运行传入的测试函数如果所有元素都返回 true 则这个方法返回 true forEach() 对数组每一项都运行传入的函数没有返回值 filter() 对数组每一项都运行传入的函数函数返回 true 的项会组成数组之后返回 map() 映射 对数组每一项都运行传入的函数返回由每次函数调用的结果构成的数组 8、深浅拷贝 基本类型数据保存在在栈内存中 引用类型数据保存在堆内存中引用数据类型的变量是一个指向堆内存中实际对象的引用存在栈中 深拷贝和浅拷贝的区别 1.浅拷贝 将原对象或原数组的引用直接赋给新对象新数组新对象/数组只是原对象的一个引用。 如果属性是基本类型拷贝的就是基本类型的值。如果属性是引用类型拷贝的就是内存地址即浅拷贝是拷贝一层深层次的引用类型则共享内存地址 2.深拷贝 创建一个新的对象和数组将原对象的各项属性的“值”数组的所有元素拷贝过来是“值”而不是“引用” 浅拷贝 数组浅拷贝: // 直接遍历 function shallowCopy(arr) {const newArr [];arr.forEach((item) newArr.push(item));return newArr; } // slice const arr2 [1, 2, 3, 4, 5]; const newArr2 arr2.slice(); // concat() 合并空数组实现 const arr3 [11, 22, 33, 44, 55]; const newArr3 arr3.concat([]);对象浅拷贝: // 直接遍历 function shallowCopy(obj) {const newObj {};for (let item in obj) {newObj[item] obj[item];}return newObj; }// 使用拓展运算符 const obj2 { name: Bob, age: 17 }; const newObj2 { ...obj2 };深拷贝 用深拷贝最后要递归到全部是基本值不然可能会陷入死循环/循环引用导致栈溢出 TODO(待理解)⭐ 处理过的数据使用 map 结构缓存起来 递归的时候碰到相同的数据 直接使用缓存里面的 1. 先转换成字符串在转换成(数组/对象) JSON.parse(JSON.stringify(XXXX)) 有一个缺点 里面的函数不能拷贝 const array [{ number: 1 }, { number: 2 }, { number: 3 }]; const str JSON.stringify(array); const copyArray JSON.parse(str);递归实现简单的深拷贝 function deepClone(obj {}) {if (typeof obj ! object || obj null) {// obj 是 null 或者不是对象和数组直接返回return obj;}// 初始化返回结果let result;obj instanceof Array ? (result []) : (result {});for (let key in obj) {// 保证 key 不是原型的属性if (obj.hasOwnProperty(key)) {// 递归调用result[key] deepClone(obj[key]);}}// 返回结果return result; }小结 前提为拷贝类型为引用类型的情况下 浅拷贝是拷贝一层属性为对象时浅拷贝是复制两个对象指向同一个地址深拷贝是递归拷贝深层次属性为对象时深拷贝是新开栈两个对象指向不同的地址 9、闭包 什么是闭包 通俗地讲闭包就是在一个函数里边再定义一个函数这个内部函数一直保持有对外部函数中作用域的访问权限(小房间一直可以有大房子的访问权限) 闭包的作用 访问其他函数内部变量保护变量不被 JS 的垃圾回收机制回收避免全局变量被污染 方便调用上下文的局部变量 加强封装性 闭包的优点 一变量长期驻扎在内存中 二另一个就是可以重复使用变量并且不会造成变量污染 ① 全局变量可以重复使用但是容易造成变量污染。不同的地方定义了相同的全局变量,这样就会产生混乱。 ② 局部变量仅在局部作用域内有效不可以重复使用不会造成变量污染。 ③ 闭包结合了全局变量和局部变量的优点。可以重复使用变量并且不会造成变量污染 闭包的缺点 由于闭包会使得函数中的变量都被保存在内存中内存消耗很大所以不能滥用闭包否则会造成网页的性能问题在 IE 中可能导致内存泄露。解决方法是在退出函数之前将不使用的局部变量全部删除。 10、数组去重 https://segmentfault.com/a/1190000016418021 Set 去重 const arr [1, 2, 3, 3, 3, 2, 3, 4, 5, 4, 4]; const newArr [...new Set(arr)]; // [ 1, 2, 3, 4, 5 ]indexOf 去重 function unique(arr) {let newArr [];for (let i 0; i arr.length; i) {if (newArr.indexOf(arr[i]) -1) newArr.push(arr[i]);}return newArr; }splice 去重 function unique(arr) {for (let i 0; i arr.length; i) {for (let j i 1; j arr.length; j) {if (arr[i] arr[j]) {arr.splice(j, 1);j--;}}}return arr; }includes 去重 function unique(arr) {const newArr [];for (let i 0; i arr.length; i) {if (!newArr.includes(arr[i])) {newArr.push(arr[i]);}}return newArr; }filter 去重 function unique(arr) {return arr.filter(function (item, index, arr) {//当前元素在原始数组中的第一个索引当前索引值否则返回当前元素return arr.indexOf(item) index;}); }findIndex数组对象去重 function unique(arr) {// todo:待总结数组去重方法// 方法一return arr.filter((item, index) {return arr.findIndex((child) child.id item.id) index;}); }Map数组对象去重 function unique(arr) {const res new Map();return arr.filter((item) !res.has(item.id) res.set(item.id, 1)); }reduce 数组对象去重 function unique(arr) {let obj {};return arr.reduce((pre, item) {obj[item.id] ? : (obj[item.id] true pre.push(item));return pre;}, []); }lodash 库数组和数组对象去重: import { isEqual, uniqWith, uniqBy } from lodash; let arr [{ id: 1, name: sli, year: 2012 },{ id: 2, name: ap, year: 2015 },{ id: 1, name: alslion, year: 2012 },{ id: 3, name: pose, year: 2012 },{ id: 3, name: pose, year: 2012 }, ]; // 根据id去掉相同的元素: console.log(uniqBy(arr, id)); // 深检查数组每一项进行去重: console.log(uniqWith(arr, isEqual));11、逻辑运算符 和 || ||运算符: 条件 1 || 条件 2 若条件 1 为 true、返回条件 1若条件 1 为 false、不管 || 后面是 true 还是 false、都是返回||后面的值、即则返回条件 2; console.log(0 || ); // console.log( || 0); // 0运算符: 条件 1 条件 2 若条件 1 为 false、无论条件 2 为 true 或 false, 都将返回条件 1 的值;若条件 1 为 true, 无论条件 2 为 true 或者 false, 都将返回条件 2 的值; console.log(0 ); // 0 console.log( 0); // 12、new 的过程 分析一下 new 的整个过程 1、创建一个空对象2、this 指向 obj并调用构造函数3、继承构造函数的原型4、返回对象 简单实现一下 new function myNew(fn, ...args) {// 第一步创建一个空对象const obj {};// 第二步this指向obj并调用构造函数fn.apply(obj, args);// 第三步继承构造函数的原型obj.__proto__ fn.prototype;// 第四步返回对象return obj; }13、事件循环 Event Loop 结合着14条讲 是什么 首先JavaScript是一门单线程的语言意味着同一时间内只能做一件事如果前面一个任务耗时太长后续的任务不得不等待可能会导致程序假死的问题但是这并不意味着单线程就是阻塞而实现单线程非阻塞的方法就是事件循环 在JavaScript中所有的任务都可以分为 同步任务立即执行的任务同步任务一般会直接进入到主线程中执行异步任务异步执行的任务比如ajax网络请求setTimeout定时函数等 同步任务进入主线程即主执行栈异步任务进入任务队列主线程内的任务执行完毕为空会去任务队列读取对应的任务推入主线程执行。过程不断重复就是事件循环 14、async 和 await 宏任务 和 微任务 https://www.mianshiya.com/qd/bf4a0bf261c7e2500090d9482499675f 宏任务 和 微任务 下面代码执行顺序是什么 console.log(1) // 同步setTimeout((){ // 宏任务console.log(2) }, 0)new Promise((resolve, reject){console.log(new Promise) // 同步resolve() }).then((){console.log(then) // 微任务 })console.log(3) // 同步1new Promise 3 then 2 1、什么是宏任务和微任务 Javascript 把异步任务又做了进一步的划分异步任务又分为两类分别是 微任务 一个需要异步执行的函数执行时机是在主函数执行结束之后、当前宏任务结束之前 常见的微任务有 Promise.thenMutaionObserverObject.observe已废弃Proxy 对象替代process.nextTickNode.js 宏任务 宏任务的时间粒度比较大执行的时间间隔是不能精确控制的对一些高实时性的需求就不太符合 常见的宏任务有 script (可以理解为外层同步代码)setTimeout/setIntervalUI rendering/UI事件postMessage、MessageChannelsetImmediate、I/ONode.js promise里面的代码是同步任务 promise的方法.then()等是异步任务 微任务 2、宏任务和微任务的执行顺序 每一个宏任务执行完之后都会检查是否存在待执行的微任务如果有则执行完所有微任务之后再继续执行下一个宏任务。 1、微任务比宏任务的执行时间要早 2、微任务在DOM渲染之前执行宏任务在DOM渲染之后执行 async与await async 是异步的意思await是等待。所以可以理解async就是用来声明一个异步方法而 await是用来等待异步方法执行 async async函数返回一个promise对象 await 正常情况下await命令后面是一个 Promise对象返回该对象的结果。如果不是 Promise对象就直接返回对应的值 不管await后面跟着的是什么await都会阻塞后面的代码加入微任务列表 下面代码执行顺序是什么 async function async1() {console.log(async1 start)await async2()console.log(async1 end) } async function async2() {console.log(async2) } console.log(script start) setTimeout(function () {console.log(settimeout) }) async1() new Promise(function (resolve) {console.log(promise1)resolve() }).then(function () {console.log(promise2) }) console.log(script end)分析过程 执行整段代码遇到 console.log(script start) 直接打印结果输出 script start遇到定时器了它是宏任务先放着不执行遇到 async1()执行 async1 函数先打印 async1 start下面遇到await怎么办先执行 async2打印 async2然后阻塞下面代码即加入微任务列表跳出去执行同步代码跳到 new Promise 这里直接执行打印 promise1下面遇到 .then()它是微任务放到微任务列表等待执行最后一行直接打印 script end现在同步代码执行完了开始执行微任务即 await下面的代码打印 async1 end继续执行下一个微任务即执行 then 的回调打印 promise2上一个宏任务所有事都做完了开始下一个宏任务就是定时器打印 settimeout 所以最后的结果是script start、async1 start、async2、promise1、script end、async1 end、promise2、settimeout 15、call、apply、bind 的区别 都可以改变 this 指向call 和 apply 会立即执行bind 不会而是返回一个函数call 和 bind 可以接收多个参数apply 只能接受两个第二个是数组bind 参数可以分多次传入 16、继承 继承的是 属性 和 原型方法 Class 继承 ES6https://es6.ruanyifeng.com/#docs/class-extends Class 可以通过extends关键字实现继承让子类继承父类的属性和方法 子类如果写 constructor()就必须要写 super(),且要写在最前面否则报错只有super()方法才能让子类实例继承父类。 class Parent {constructor(x,y) {this.x xthis.y y...}toString() {...} }class Son extends Parent {constructor(x, y, color) {super(x, y); // 调用父类的constructor(x, y)this.color color;}toString() {return this.color super.toString(); // 调用父类的toString()} }ES5 继承 js 中有很多中继承的方式不过每一种继承方式都有优缺点重点掌握 ES5 继承别的继承方式基本都是 ES5 继承的语法糖 先创造子类实例通过Parent.call(this, arg1, arg2...)将父类的属性方法添加到this上继承了父类的属性 再通过 Son.prototype Object.create( Father.prototype )将父类的原型继承过来 最后可以通过Son.prototype.constructor Son 将子类的原型指到子类身上 function Father(name) {this.name name; }Father.prototype.get function () {return 黑马; };// 继承的是 属性 和 原型方法 function Son(name) {Father.call(this, name); }// Son.prototype new Father() // 相互影响 会存在一个 {name:undefined}// Object.create 创造出一个空对象 // 让当前对象的__proto__ 指向传入的对象 Son.prototype Object.create(Father.prototype); Son.prototype.constructor Son;const son new Son(程序员); console.log(son); console.log(son.get() son.name); // 黑马程序员17、原型链 什么是原型原型链 每个函数都有一个 prototype 原型(原型就是对象)原型对象有一个 constructor 属性指向的是构造函数 访问对象的某一个属性或者方法时会从对象自身查找如果查找不到就会去原型链上去找原型的最终目的就是让所有的实例能够共享其属性和方法 查找顺序: 自身 __proto__ 构造函数的原型对象 __proto__ Object 的原型对象 __proto__ null 18、堆和栈 TODO ⭐⭐ https://juejin.cn/post/6844903618999500808 19、ES6 Set 和 Map TODO ⭐⭐ 20、includes includes() 方法用来判断一个数组是否包含一个指定的值根据情况如果包含则返回 true否则返回 false 语法 arr.includes(valueToFind[, fromIndex])valueToFind 需要查找的元素值。Note: 使用 includes()比较字符串和字符时是区分大小写。 fromIndex 可选 从fromIndex 索引处开始查找 valueToFind。如果为负值则按升序从 array.length fromIndex 的索引开始搜 即使从末尾开始往前跳 fromIndex 的绝对值个索引然后往后搜寻。默认为 0。 [1, 2, 3].includes(2); // true [1, 2, 3].includes(4); // false [1, 2, 3].includes(3, 3); // false [1, 2, 3].includes(3, -1); // true [1, 2, NaN].includes(NaN); // true21、find find() 方法返回数组中满足提供的测试函数的第一个元素的值。否则返回 undefined arr.find(callback[, thisArg])callback 在数组每一项上执行的函数接收 3 个参数element当前遍历到的元素。index可选当前遍历到的索引。array可选数组本身。 thisArg可选 执行回调时用作 this 的对象。 三、Git 1、列举工作中常用的几个 git 命令 git rm 删除工作区文件并将这次删除放入暂存区 git add 增加指定文件到暂存区 git init 新建初始化 git 代码库 git status 显示有变更的文件 git branch 列出所有分支 git commit -m [message] 提交暂存区到仓库区可选填备注信息 message git checkout -b [branch] 新建分支并切换到该分支四、HTML-C3 1、盒子水平垂直局中的方法 flex 布局 /* html代码: */div classwrapdiv classbox/div/div/* CSS代码 */.wrap{/* 设置为弹性布局 */display: flex;/* 子元素在主轴对齐方式为居中 */justify-content: center;/* 交叉轴在y轴对齐 */align-items: center;} Position Transform /* html代码: */div classwrapdiv classbox/div/div /* CSS代码 */.wrap{width: 600px;height: 600px;border: 2px solid black;/* 设置为相对定位用来作为绝对定位元素的容器块。 */position: relative;}.box{width:50px;height: 50px;/* 设置为绝对定位位置在父容器的中心 */position: absolute;margin: auto;left: 50%;top:50%;/* 向回移动自身一半的长宽 */transform: translateX(-50%) translateY(-50%);}利用Position margin:auto style.father {margin: 100px auto;width: 500px;height: 300px;border: 1px solid #0a3b98;position: relative;}.son {width: 100px;height: 40px;background: #f0a238;position: absolute;top: 0;left: 0;right: 0;bottom: 0;margin: auto;}/stylediv classfatherdiv classson/div/divinline-block /* html代码: */div classwrapdiv classbox/div/div /* CSS代码 */.wrap{width: 600px;border: 2px solid black;/* 设置行高为600px */line-height: 600px;/* 让子盒子水平居中 */text-align: center;}.box{height: 50px;width: 50px;/* 设置为块级元素 */display: inline-block;/* 设置为垂直居中 */vertical-align: middle;background-color: red;}table 布局 设置父元素为display:table-cell子元素设置 display: inline-block。利用vertical和text-align可以让所有的行内块级元素水平垂直居中 style.father {display: table-cell;width: 200px;height: 200px;background: skyblue;vertical-align: middle;text-align: center;}.son {display: inline-block;width: 100px;height: 100px;background: red;}/stylediv classfatherdiv classson/div/div总结 根据元素标签的性质可以分为 内联元素居中布局块级元素居中布局 内联元素居中布局 水平居中 行内元素可设置text-align: centerflex 布局设置父元素display: flex ; justify-content: center 垂直居中 单行文本父元素确认高度height line-height多行文本父元素确认高度disaply: table-cell; vertical-align: middle 块级元素居中布局 水平居中 定宽: margin: 0 auto绝对定位 left:50% margin: 负自身一半 垂直居中 position: absolute 设置 left、top、margin-left、margin-top(定高)display: table-celltransform: translate(x, y)flex (不定高不定宽)grid(不定高不定宽)兼容性相对比较差 2、BFC经典面试题 概念 Block Formatting Context,翻译过来就是块级格式化上下文 bfc 实际是一种属性拥有这种属性后就会让该渲染区域独立并且该渲染区域中的内容布局不会影响到外界 如何触发: 根元素(html) float 属性不为 none position 为 absolute 或 fixed display 为 inline-block, table-cell, table-caption, flex, inline-flex overflow 不为 visible 解决什么问题 外边距重叠 外边距重叠,要注意这不是 bug规范就是这样的当两个盒子上下同时拥有上下间距会取最大值 清除浮动当子盒子开启 float 后会影响后面的布局以及盒子高度浮动覆盖 由于浮动导致盒子被覆盖 3、盒模型 盒模型主要分为 4 部分内容、外边距、内边距、边框 Css3 盒子模型可以通过 box-sizing 来改变 标准盒模型W3C 标准content-box 盒子实际宽度加上 padding 和 border ie 盒模型/怪异盒模型/c3 盒模型box-sizing: border-box; 设置 width 后实际盒子的宽度就固定为该宽度包含了 内容 padding border 4、flex1 flex1 → {flex-grow: 1;flex-shrink: 1;flex-basis: 0%; }flex-grow:1 flex-grow 是用来增大盒子的比如当父盒子的宽度大于子盒子的宽度父盒子的剩余空间可以利用 flex-grow 来设置子盒子增大的占比 flex-shrink: 1 flex-shrink 用来设置子盒子超过父盒子的宽度后进行缩小的比例取值 flex-basis: 0% 设置盒子的基准宽度并且 basis 和 width 同时存在会把 width 干掉 5、c3 新属性 c3 盒模型 box-sizingflex 布局transition 过渡transform2D 转换background-size 背景缩放border-radius 圆角… 6、 五、HTTP HTTP 缓存 https://juejin.cn/post/6844904153043435533#heading-1 HTTP 状态码 1xx - 信息响应 - 传达传输协议级别的信息2xx - 成功的响应 - 表示客户端的请求已成功接受3xx - 重定向 - 表示客户端必须采取一些额外的操作才能完成其请求4xx - 客户端错误 - 此类错误状态码指向客户端5xx - 服务端错误 - 服务器对这些错误状态代码负责 信息响应 100接受的请求正在处理信息类状态码 成功的响应 200成功OK — 请求成功201正创建Created — 请求已完成已创建新资源 重定向 301永久移动Moved Permanently — 资源永久移动到新的 URL302临时移动Moved Temporarily — 资源临时移动到新的 URL304未修改Not Modified— 当协商缓存命中时会返回这个状态码。 客户端错误 此类错误状态代码指向客户端 400请求错误Bad Request — 服务器无法理解和处理请求401未经授权Unauthorized — 需要验证用户尚未验证403禁止Forbidden — 对资源的访问权限不足404未找到Not Found — 找不到请求的资源 服务端错误 500内部服务器错误Internal Server Error— 通用未处理的服务器错误 503服务不可用Service Unavailable— 服务器暂时无法处理请求 1.浏览器缓存机制 2.get 和 post 的区别 3.$ nextTick(),原理 4.防抖节流 5.组件通信方式 6.生命周期 7.promise 8.promise.all 方法什么时候走成功什么时候走失败 9.v-if、v-for 10、对象和数组的响应式区别 11、keep-alive 12、组件通信的方式 13.vue 数据响应式如何实现 14.vue for 循环的时候 key 的作用 15、call、apply、bind 区别 15、vue.use 做了什么东西 16、插槽 什么场景下使用插槽 17、平时工作中封装过哪些组件怎么封装这些组件 18、响应拦截器里面都做什么事情响应拦截器里面的回调什么时候调用 19、 r o u t e 和 route 和 route和router 20、单页和多页面的缺点 21、keepalive 的作用原理 22、http 和 https 的区别 23、状态码有哪些 24、如何实现实时更新比如股票数据websocket 25、如何判断一个数据是数组还是对象 26、路由懒加载原理 27、data 为什么是对象而不是函数 28、.catch 能捕获到 return 一个 reject 吗 29、如何做移动端的 rem 适配除了 flexible还要装 pxtorem 30、如何解决跨域问题生产环境如何解决跨域问题什么是反向代理跨是浏览器的机制 31、回流和重绘 32、图片懒加载的原理 33、项目优化的方式各个方式打包发请求 34、观察者模式和发布订阅模式区别 的宽度父盒子的剩余空间可以利用 flex-grow 来设置子盒子增大的占比 flex-shrink: 1 flex-shrink 用来设置子盒子超过父盒子的宽度后进行缩小的比例取值 flex-basis: 0% 设置盒子的基准宽度并且 basis 和 width 同时存在会把 width 干掉 5、c3 新属性 c3 盒模型 box-sizingflex 布局transition 过渡transform2D 转换background-size 背景缩放border-radius 圆角… 6、 五、HTTP HTTP 缓存 https://juejin.cn/post/6844904153043435533#heading-1 [外链图片转存中…(img-J96pnFCj-1705469393226)] HTTP 状态码 1xx - 信息响应 - 传达传输协议级别的信息2xx - 成功的响应 - 表示客户端的请求已成功接受3xx - 重定向 - 表示客户端必须采取一些额外的操作才能完成其请求4xx - 客户端错误 - 此类错误状态码指向客户端5xx - 服务端错误 - 服务器对这些错误状态代码负责 信息响应 100接受的请求正在处理信息类状态码 成功的响应 200成功OK — 请求成功201正创建Created — 请求已完成已创建新资源 重定向 301永久移动Moved Permanently — 资源永久移动到新的 URL302临时移动Moved Temporarily — 资源临时移动到新的 URL304未修改Not Modified— 当协商缓存命中时会返回这个状态码。 客户端错误 此类错误状态代码指向客户端 400请求错误Bad Request — 服务器无法理解和处理请求401未经授权Unauthorized — 需要验证用户尚未验证403禁止Forbidden — 对资源的访问权限不足404未找到Not Found — 找不到请求的资源 服务端错误 500内部服务器错误Internal Server Error— 通用未处理的服务器错误 503服务不可用Service Unavailable— 服务器暂时无法处理请求 1.浏览器缓存机制 2.get 和 post 的区别 3.$ nextTick(),原理 4.防抖节流 5.组件通信方式 6.生命周期 7.promise 8.promise.all 方法什么时候走成功什么时候走失败 9.v-if、v-for 10、对象和数组的响应式区别 11、keep-alive 12、组件通信的方式 13.vue 数据响应式如何实现 14.vue for 循环的时候 key 的作用 15、call、apply、bind 区别 15、vue.use 做了什么东西 16、插槽 什么场景下使用插槽 17、平时工作中封装过哪些组件怎么封装这些组件 18、响应拦截器里面都做什么事情响应拦截器里面的回调什么时候调用 19、 r o u t e 和 route 和 route和router 20、单页和多页面的缺点 21、keepalive 的作用原理 22、http 和 https 的区别 23、状态码有哪些 24、如何实现实时更新比如股票数据websocket 25、如何判断一个数据是数组还是对象 26、路由懒加载原理 27、data 为什么是对象而不是函数 28、.catch 能捕获到 return 一个 reject 吗 29、如何做移动端的 rem 适配除了 flexible还要装 pxtorem 30、如何解决跨域问题生产环境如何解决跨域问题什么是反向代理跨是浏览器的机制 31、回流和重绘 32、图片懒加载的原理 33、项目优化的方式各个方式打包发请求 34、观察者模式和发布订阅模式区别
http://www.dnsts.com.cn/news/2002.html

相关文章:

  • 郑州网站建设专业公司sem是什么意思
  • 苏州pc网站开发百度一下你就知道官页
  • 不花钱怎么做网站运营seo网站建设公司
  • CSS3网站推广有哪些搜索引擎网站
  • 搭建网站 网页seo引擎优化培训
  • 素材下载网站开发交换链接
  • 乐清app开发公司google关键词seo
  • 网站建设 关于我们西安seo排名
  • 国际网站怎么样做什么是引流推广
  • 石家庄做网站的网址大全实用网址
  • 弹幕网站怎么做网站提交百度收录
  • wordpress软件站主题高端企业网站模板
  • 浙江省网站重点学科建设青岛seo推广公司
  • 单页面 网站 模板足球排名世界排名
  • 在北京网站建设的岗位营销宣传方案
  • 做外包的网站有哪些广东东莞今日最新消息
  • 郑州响应式网站建设论述搜索引擎优化的具体措施
  • 建网上商城的第三方网站哪个好百度指数人群画像怎么看
  • 小企业网站建设怎样seo 首页
  • 以下属于免费推广的方式是网站搜索引擎优化工具
  • 株洲公司dedecmsseo原创工具
  • 网站集约化建设意见公司推广渠道
  • 工业设计招聘百度seo按天计费
  • 做网站购买什么腾讯控股第三季度营收1401亿
  • 定制网站系统今日新闻头条热点
  • 旅游网站建设背景分析报告百度网
  • 广州监狱门户网站网络销售真恶心
  • 纯手工建网站百度网站联系方式
  • 系统网站界面设计黄冈网站推广软件视频下载
  • 做美国大学生建模的相关网站合肥建站公司seo