持续不断更新中... 自己整理的一些前端知识点以及前端面试题,包括vue2,vue3,js,ts,css,微信小程序等

Vue3自考题

1,如何使用vue3的组合式api

答:

  1. 在普通的前端项目工程中,在script标签中增加setup即可使用api
  2. 使用setup()钩子函数

2,computed 与各个watch之间和method的区别

答:

​ 注意:

  1. 不要在计算属性中进行异步请求或者更改DOM
  2. 不要直接修改computed的值

区别:

  1. 计算属性值基于其响应式依赖被缓存,意思就是只要他之前的依赖不发生变化,那么调用他只会返回之前缓存的结果,而watch是监听的对象发生变化,则会被触发,方法则是每次重新渲染或者手动调用就会发生变化

3,如何进行样式绑定

答:

  • 使用 :class 进行绑定

    //绑定一个对象 编译后:
    //绑定一个数组 编译后:
    let isActive = "hello" let activeClass = "activeValue" let errorClass = "errorValue"
  • 使用内联样式进行绑定

4,v-if 与 v-show 的应用场景和区别

应用场景:如果切换不是太频繁,则应该使用v-if,反之使用v-show

区别:v-if是销毁后在新建,v-show则是通过display:none来控制,v-show的性能比v-if的性能要高一些

5,v-if,v-for的优先级问题

答: vue2中v-for优先于v-if,vue3相反。不建议在同一节点同时使用vif,与v-for,如果想过滤一些数据的话,可以这样做

//computedItems是经过处理后的数据列表。

6,vue3 修改了数组的哪些方法,使其能监听响应式数组的变更方法

答:push(),pop(),shift(),unshift(),splice(),sort(),reverse()

7,vue3修饰符

  • 事件修饰符
修饰符 说明
.stop 事件停止冒泡
.prevent(坡蕊温特) 阻止标签默认行为
.capture 使用事件捕获模式,即元素自身触发的事件先在此处处理,然后才交由内部元素进行处理
.self 只当在event.target 是当前元素自身时触发处理函数
.once 事件将只会触发一次
.passive([ˈpæsɪv]) 不阻止事件默认行为
  • 按键修饰符
修饰符 说明
.enter 按回车
.tab TAB键
.delete 删除键
.esc ESC
.space ([speɪs]) 空格
.up||.down||.left||.right 上下左右方向键
  • v-model修饰符
修饰符 说明
.lazy 在每次 change 事件后更新数据
.number 用户输入自动转换为数字,如果parseFloat()无法解析,那么则返回原始值
.trim 去除用户输入值两端的空格

8,vue的生命周期

  • vue2:
生命周期(页面) 说明
beforeCreate 组件实例被创建之前,此时data还未生成。
created 实例创建后,此时vm已经生成,但是还未挂载到页面上,el还未生成
beforeMount 实例挂载前,此时vm即将要挂载到dom上,el还不生成
mounted 实例挂载后,此时页面已经渲染成功,可以访问到el
beforeUpdate 实例数据更新前,
updataed 数据更新后
beforedestory 实例销毁前,此时实例还未销毁
destoryed 实例销毁后
生命周期(组件) 说明
actived 被 keep-alive 缓存的组件激活时调用。
deactivated 被 keep-alive 缓存的组件失活时调用。
  • vue3:
生命周期(组合式API) 说明
onMounted 组件挂载完成后执行。ssr渲染不会被调用
onUpdated 在组件因为响应式状态变更而更新其 DOM 树之后调用。ssr渲染不会被调用
onUnmounted 组件实例被卸载之后调用。ssr渲染不会被调用
onBeforeMount 组件被挂载之前被调用
onBeforeUpdate 在组件即将因为响应式状态变更而更新其 DOM 树之前调用。
onBeforeUnmount 组件实例被卸载之前调用。
onErrorCaptured 捕获了后代组件传递的错误时调用
生命周期(组件) 说明
onActivated 若组件实例是 KeepAlive缓存树的一部分,当组件被插入到 DOM 中时调用
onDeactivated 注册一个回调函数,若组件实例是 KeepAlive缓存树的一部分,当组件从 DOM 中被移除时调用。
生命周期(选项式API) 说明
beforeCreate 组件实例初始化完成之后立即调用。
created 组件实例处理完所有与状态相关的选项后调用。
beforeMount 组件被挂载之前调用。
mounted 组件被挂载之后调用。
beforeUpdate 在组件即将因为一个响应式状态变更而更新其 DOM 树之前调用。
updated 在组件因为一个响应式状态变更而更新其 DOM 树之后调用
beforeUnmount 在一个组件实例被卸载之前调用。
unmounted 在一个组件实例被卸载之后调用。
errorCaptured 捕获了后代组件传递的错误时调用。

9,组件注册的方式

  1. 全局注册:vue.component

    //语法
    vue.component(componentName:string,template:components)
    
  2. 局部注册

    • setup注册:如果使用了setup函数,则在组件引入后,即可直接使用,而无需注册
    • components:直接在里面注册,然后在template模板中直接引用

10,组件接收prop的方式

  1. 组合式api:使用defineProps函数

    let props = defineProps({
    	prop1
    })
    
  2. 选项式api:props

    props:{
    	prop1,
    }
    

11,vue哪个生命周期才能访问dom,为什么

  • vue在mounted实例挂载后才可以访问dom,因为此时vue实例已经挂载到了el上

12,组件中的data为什么是个函数

答:因为vue中组件是复用的,如果组件中的data返回的是个对象的话,那么在多个组件同用一个data的时候,往往这个组件中的data发生了改变,那么其他组件也会发生改变。为了避免这个问题,就必须返回一个函数,这就相当于为每个组件开辟了一个私有的data

13,什么是MVVM?

  • MVVM是一种设计思想,M代表的是model,V代表的是视图,VM代表的是控制器,负责的是视图与数据模型的交互
  • MVVM能实现前端开发和js逻辑层的分离

14,vue2组件的通信方式

答:

  • 父传子:父组件直接在子组件上绑定属性,然后子组件用props来接收
  • 子传父:子组件使用**$emit(‘eventName’,params)**来向父组件传递信息,父组件使用on来监听子组件传递过来的事件,在methods中进行处理
  • 父传子孙:使用provide 分发 ,inject接收
  • 使用eventBus.js
  • 插件使用vuex

15,如何实现vue首屏加载优化的?

  • 把不常改变的库放到index.html中,用cdn来引入
  • 使用路由懒加载
  • 一些较小的图片使用base64格式返回
  • 使用轻量型的工具库
  • vue组件尽量不要全局引入
  • 使用雪碧图(将多个小图片合并成一张大图,通过定位来控制位置)

16,vue项目性能优化

  • 压缩代码
  • v-if和v-for区分使用场景
  • 路由懒加载
  • 单页面使用keep-alive缓存
  • 使用防抖节流
  • 避免书写行内样式,以免造成重绘
  • 使用轻量型工具库
  • dll分包

17,watch与watchEffect的区别

答:

  1. 区别:

    • watch只追踪明确侦听的数据源,仅在数据源确实改变时触发回调
    • watchEffect则会在副作用发生期间追踪依赖,会在同步过程中,自动追踪所有能访问到的响应式属性
  2. watchEffect的触发时机

    • 语法

      watch(source, callback, options)
      
      watchEffect(callback, options)
      
      
    • post:能在侦听器回调中访问被 Vue 更新之后的 DOM,他的另一个别名函数叫做:watchPostEffect()

    • sync:有必要在响应式依赖发生改变时立即触发侦听器的时候 别名:watchSyncEffect()

  3. watch的options

    watch (source: WatchSource,  callback: WatchCallback,  options?: WatchOptions)
    
    watchOptions:{
    	immediate ( [ɪˈmiːdiət] ):boolean, // 侦听器创建时立即触发回调。第一次调用时旧值是 undefined
    	deep:boolean,//如果源是对象,强制深度遍历,以便在深层级变更时触发回调
    	flush:post|sync,//触发时机
    	onTrack / onTrigger:调试侦听器的依赖。
    	
    }
    

18,常用api参考

18.1,全局api

api 说明 补充
createApp(rootComponent:component,rootOptions:Object) 创建一个vue实例 Object是要传递给跟组件的props
createSSRApp() 从服务端创建一个实例 跟createApp一样的,区别是ssr
app.mount(rootContainer: Element||string) 将应用实例挂载在一个容器元素中。 对于每个应用实例,mount() 仅能调用一次。
app.unmount() 卸载一个已挂载的应用实例。 卸载一个应用会触发该应用组件树内所有组件的卸载生命周期钩子。
app.provide(key:InjectionKey|symbol|string , value:T) 提供一个值,可以在应用中的所有后代组件中注入使用。
app.component(name: string, component: Component): this
app.component(name:string ): Component|undefined
如果传入一个组件名和一个组件,则代表全局注册一个组件,只传入一个组件名,那么返回一个组件或者undefined this:指的是注册的组件
app.directive(name:string): directive|undefined
app.directive(name: string, directive: directive): this
注册指令 this指的是指令
app.use(plugin: Plugin, …options: any[]): this 安装一个插件。 Plugin:插件
options:要传递给插件的选项。
this:返回的是插件本身
app.mixin(mixin: ComponentOptions): this 混入 vue3不推荐用了,可以用组合式函数来代替

18.2,通用api

api 说明 补充
nextTick(callback?: () => void): Promise 等待下一次 DOM 更新刷新的工具方法。 常用来解决同步失效的问题
defineComponent(component: ComponentOptions | ComponentOptions[‘setup’]):ComponentConstructor 在定义 Vue 组件时提供类型推导的辅助函数。 最大的用处就是给ts提供更好的类型推导

18.3,组合式api

api 说明 补充
setup(props,this) 组合式api的入口 props:组件的 props
this:Setup 上下文对象
ref(value) 把value变成一个ref代理对象,并把他返回来 默认访问属性需要value.value才能访问到
computed(getter:() => T) 计算属性
reactive(Object) 返回一个对象的响应式代理。
readonly(object) 返回一个object的只读代理
watchEffect(effect: (onCleanup: OnCleanup) => void, options?: WatchEffectOptions): StopHandle 立即运行一个函数,同时响应式地追踪其依赖,并在依赖更改时重新执行。 StopHandle:返回一个停止监听
watchPostEffect() watchEffect() 使用 flush: 'post' 选项时的别名。 设置 flush: 'post' 将会使侦听器延迟到组件渲染之后再执行
watchSyncEffect() watchEffect() 使用 flush: 'sync' 选项时的别名。 在某些特殊情况下 (例如要使缓存失效),可能有必要在响应式依赖发生改变时立即触发侦听器。
watch (source: WatchSource, callback: WatchCallback, options?: WatchOptions) 侦听一个或多个响应式数据源,并在数据源变化时调用所给的回调函数。 WatchOptions:
响应式工具
isRef(r: Ref|unknown) 检查某个值是否为 ref。 请注意,返回值是一个类型判定 (type predicate),这意味着 isRef 可以被用作类型守卫
unref(ref: T | Ref): T 如果参数是 ref,则返回内部值,否则返回参数本身。这是 val = isRef(val) ? val.value : val 计算的一个语法糖
toRef(T extends object, K extends keyof T) 基于响应式对象上的一个属性,创建一个对应的 ref。
toRefs(T) 将一个响应式对象转换为一个普通对象,
isProxy(value: unknown): boolean 检查一个对象是不是proxy对象
isReactive(value: unknown): boolean 检查一个对象是否是由 reactive()shallowReactive() 创建的代理。
isReadonly(value: unknown): boolean 检查传入的值是否为只读对象。
依赖注入
provide(key: InjectionKey | string, value: T): void 提供一个值,可以被后代组件注入。 key:要注入的 key
value:要注入的值
inject() 注入一个由祖先组件或整个应用 (通过 app.provide()) 提供的值。也可以理解为接收

19,keep-alive组件首次渲染,二次渲染触发的生命周期

答:

  1. 第一次进入触发的生命周期是:created -> mounted -> activated,退出时触发deactivated
  2. 第二次渲染时:只触发activated

20,如何实现动态添加keep-alive组件

通过路由中的meta对象下的keepAlive(boolean)属性来控制缓存组件是否缓存

语句:this.$route.meta.keepAlive=true||false

21,vue的优势

  1. vue是一种基于MVVM软件设计架构的轻量型框架
  2. vue可以进行组件化开发
  3. vue可以实现双向数据绑定
  4. vue视图和数据结构分离,
  5. vue的生态好,有丰富的ui框架以及插件
  6. vue不直接操作dom,vue是先通过diff算法生成ast树,然后通过pach算法比较差异,再生成dom树
  7. vue是单项数据流

22,虚拟dom的优缺点

  • 保证性能下限
  • 无需手动操作dom
  • 跨平台
  • 缺点是无法进行极致优化

24,解决跨域的方法

  • 在vue.config.js中的devserve.proxy:{url:“地址”}中可以解决跨域
  • 跨域是指不在同源策略(域名,协议,端口一致)内,就会产生跨域
  • 也可以设置nginx(恩急壳死)反向代理来解决跨域
  • 也可以用jsonp来解决跨域,只支持get调用

26,插槽slot简介

  1. 分类:

    • 具名插槽:带有名字的插槽

      //组件内
      
      	
      		  //这个name就是插槽的名字
      	
      
      
      //使用组件
      
      	
      
      
    • 匿名插槽:没有名字的插槽,一个标签只能有一个匿名插槽

    • 作用域插槽:

      
        {{ text }} {{ count }}
      
      
      
    • 动态插槽名:

      
        
      
        
        
      
      
  2. 缩写形式:#

  3. 作用:可以扩展组件,增加组件的灵活性

27,动态组件&异步组件

  1. 动态组件

    动态组件需要用keep-alive标签

  2. 异步组件

    异步组件需要使用vue.component(“组件名”,callback():promise),返回一个模板对象

28,vue双向绑定原理

  1. vue2:

    使用了Object.defineProperty结合发布者/订阅设计模式,递归遍历对象的每个属性,为每个属性都设置了setter/getter,一旦属性发生了变化,则通知相关的订阅者,订阅者调用setter直接改变对象的属性

  2. vue3:
    使用Proxy代理对象来实现。

29,render()函数的使用

  • 使用场景:当场景中用template实现起来代码繁琐且有大量重复的时候
  • render(contentHTML,htmlStyle,vNode),参数一:模板结构,参数二,模板样式,参数三,设置分发内容

30,父子组件的渲染过程,更新过程,销毁过程

  • 渲染过程:父beforeCreate -> 父created -> 父beforeMount -> 子beforeCreate -> 子beforeMount -> 子mounted ->父mounted
  • 更新过程:
    1. 父beforeUpdate -> 子beforeUpdate -> 子updated ->父updated —
  • 子组件更新过程
    • beforeUpdate -> updated
  • 销毁过程:父beforeDestory -> 子beforeDestory -> 子destoryed ->父 destoryed

vuex 部分

1,vuex中状态存储在那里?如何去改变他?

答:存储在state中,改变state的状态只能通过mutation,或者通过Action使用commit触发mutation来改变状态

2,vuex页面刷新数据丢失怎么办?

答:

  1. 把数据存到本地
  2. 使用vuex-persist (破尔色死特)插件

3,简述vuex得数据传递流程

  • 使用dispatch||commit来触发action和mutition中得方法来改变state状态
  • 使用getter来向外暴露state
  • 然后在页面可以使用助手函数mapstate来获取vuex中得state,或者使用this.$store.state来获得数据

4,vuex中Mutation与Action得区别是什么?

  • Mutation可以直接改变state得状态,这里进行得是同步操作
  • Action不可以直接改变state得状态,不过这里可以进行异步操作

5,vuex嵌套的子模块中可以重复嵌套吗?

答:
可以,因为每一个子模块中都有 statenamespacedmutationsactionsgettersmodules,而且模块中多了一个属性namespace(命名空间),当模块被注册后,它的所有 getter、action 及 mutation 都会自动根据模块注册的路径调整命名,

6,vuex和pinia(皮尼啊)的区别

  1. Pinia 对 vue2 和 vue3 都支持,尤其是 TypeScript 的项目
  2. 没有模块的嵌套结构
  3. 不需要注入、导入函数、调用它们
  4. 无需手动添加 store ,它的模块默认情况下创建就自动注册的
  5. 支持 Vue DevTools
  6. 支持服务端渲染
  7. Vuex: State、Gettes 、 Mutations (同步)、 Actions (异步),modules(子模块)
    Pinia: State、Gettes 、 Actions (同步异步都支持)

7,组合式api中如何使用vuex

答:

在组合式api中,需要先引入useStore函数import {userStore} form vuex

8,dispatch和commit的区别

  • 相同点:二者最终都是用来提交mutation来更改state的值的
  • 不同点:dispatch是异步提交,commit是同步提交

vue-router部分

1,怎么在组件中监听路由参数的变化

  1. 在watch直接监听$route(to,from)
  2. 在路由导航守卫中监听,beforeRouterEnter

2,Vue-router是干什么得?他得原理是什么

答:
vue-router是vue官方指定的路由插件,是单页面应用的核心组成部分,vue-router用于设定访问路径,并将路径和组件映射起来。传统多页面应用中,页面跳转是用超链接来实现页面切换和跳转的,但在单页面应用中,页面跳转则是使用路径的切换,路由的作用是建立url和页面的映射关系
vue-router的实现主要靠url中的hash和history中新增的接口来实现的。

3,路由间是如何跳转得?

  1. 在route-link中使用to属性来进行跳转
  2. 在js中使用this. r o u t e r . p u s h ( ) 或者 t h i s . router.push()或者this. router.push()或者this.router.replace(),或this. r o u t e r . g o ( ) , t h i s . router.go(),this. router.go()this.router.back()来进行跳转

4,vue-router怎么配置路由

新建一个router文件夹,建立一个index文件,然后引入router,创建一个routers路由表,实例化一个router对象,使用这个路由表,设定mode

5,vue-router有哪几种路由守卫

  1. 全局守卫:

    • beforeEach(to,from,next)
    • afterEach
  2. 独享守卫:beforeEnter()

  3. 组件内守卫

    • beforeRouterEnter
    • beforeRouterUpdate
    • beforeRouterLeave

6,路由传值的方式有几种?

  1. 编程式路由

    • this.$router.push({name:“index”,params:{id:123}})
    • 接收参数,在路由页面使用this.$route.params来接收
  2. 声明式路由

  3. 获取路由参数

    this. r o u t e . p a r a m s , t h i s . route.params,this. route.paramsthis.route.query

7,route和router的区别

route是页面路由对象,他里面会有query,params等属性,router是全局路由对象mate路由元数据等

8,vue-router中常用的路由模式实现原理

  • hash模式:利用window.hashChange来实现
  • history:通过H5的history 新增的pushState和replaceState来实现

常用的库

说明 补充
Lodash.js Lodash 通过降低 array、number、objects、string 等等的使用难度从而让 JavaScript 变得更简单。非常适用于:遍历 array、object 和 string 对值进行操作和检测 创建符合功能的函数
PDF.js 由js编写的pdf阅读器 用来解决小程序安卓端的pdf阅读问题
voca.js 提供完整的函数集来操作、截断、格式化、转义和查询字符串
video.js 适用于vue的js视频播放器
bowser.js 适用于浏览器和节点的小型、快速且丰富的 API 浏览器/平台/引擎检测器。
moment.js 解析、验证、操作和显示日期。
countdown.js 倒计时插件
dayjs Day.js 是一款拥有和 Moment.js 一样的现代化接口的日期库,但它仅仅有 2kb 大小,可以用来替换 Moment.js。
accounting.js 对数字、金钱、货币进行格式化的轻量库,完全本地化和无依赖。 英文发音:鹅康听
chance.js JavaScript 随机生成器,可以生成数字、字符串等。
Vue I18n 国际化vue插件 用来做中英适配
log 浏览器日志插件 看日志更方便点
qs.js qs.js是用来处理url中参数的一个js库
js-cookie 用于处理 cookie 的简单、轻量级 JavaScript API
flv.js 一个用纯 JavaScript 编写的 HTML5 Flash 视频 (FLV) 播放器,没有 Flash。 哔哩哔哩开源的
mpegts.js flv.js的迭代品
Animate.css 一个跨浏览器的 css3 动画库,内置了很多典型的 css3 动画,兼容性好,使用方便。
animejs 一款功能强大的 Javascript 动画库。可以与CSS3属性、SVG、DOM元素、JS对象一起工作,制作出各种高性能、平滑过渡的动画效果。
mescroll.js 一款精致的、在H5端运行的下拉刷新和上拉加载插件,主要用于列表分页、刷新等场景。

axios

1,axios是什么,怎么使用他,怎么解决跨域问题

  1. axios是基于promise的http库,是vue官方指定的http库
  2. axios需要npm install axios 和npm install vue-axios
  3. axios解决跨域需要在请求头加上content-type即可

移动端适配

1,解决方案

  • postcss-px-to-viewport
  • 使用rem+媒体查询
  • 使用flex布局

小程序相关

1,哪些函数拥有页面跳转的功能?

  • uni. navigateTo (Object):保留当前页面到路由栈中,然后跳转目标页面
  • uni.redirectTo(Object): 关闭当前页面,跳转到应用内的某个页面。
  • uni.reLaunch(Object):关闭所有页面,打开到应用内的某个页面。
  • uni.switchTab():跳转到 tabBar 页面,并关闭其他所有非 tabBar 页面。
  • uni.navigateBack(Object):关闭当前页面,返回上一页面或多级页面

2,uniapp如何进行条件编译?

​ **写法:**以 #ifdef 或 #ifndef 加 %PLATFORM% 开头,以 #endif 结尾。

  • #ifdef:if defined 仅在某平台存在
  • #ifndef:if not defined 除了某平台均存在
  • %PLATFORM%:平台名称

3,如何进行页面滚动监听

使用onPageScroll 生命周期函数监听

4,小程序切换tabbar,不触发onload怎么解决

在onTabItemTap()生命周期中写入代码

5,页面获取数据,渲染闪烁

可能页面上存在图片,但是没有指定高度。

6,小程序优化方案

  • 核心点:

    1. 提高加载性能

      • 加载流程:

        1. 代码包准备(下载代码包)优化措施:

          • 分包加载
          • 代码重构和优化:减少不常用的库引入和依赖
          • 避免在代码包中包含过多,过大的图片,应尽量采用网络图片
          • 清理无用代码
        2. 开发者代码注入

          1. 减少启动过程的同步调用

            • 在小程序启动流程中,会注入开发者代码并顺序同步执行App.onLaunch(昂蓝吃),App.onShow,Page.onLoad,Page.onShow。
            • 在小程序初始化代码(Page,App定义之外的内容)和启动相关的几个生命周期中,应避免执行复杂的计算逻辑或过度使用以Sync结尾的同步API,如:wx.getStorageSync,wx.getSystemInfoSync等。
            • 对于getSystemInfo,getSystemInfoSync的结果应进行缓存,避免重复调用。
          2. 使用懒注入
            通常情况下,小程序启动时,启动页面所在分包和主包(独立分包除外)的所有js代码会全部合并注入,包括其他未访问到的页面和未用到的自定义组件。影响注入耗时和内存占用

            • 开启仅注入当前页面需要的自定义组件和当前页面代码,在app.json中配置

              {
              	"lazyCodeLoading":"requiredComponents"
              }
              
        3. 初次渲染

          1. 骨架屏:提升用户等待意愿
          2. 提升首屏数据请求
            • 数据预拉取
            • 周期性更新
          3. 精简首屏数据:
            • 数据懒加载
            • 数据合并
            • 减少请求次数
            • 数据局部更新
          4. 缓存请求数据:可以使用wx.setStorage,wx.getStorage等读写本地缓存的能力,来提升首屏数据渲染
    2. 提高渲染性能

      1. 及时清理定时器,因为小程序共享一个js运行环境
      2. 谨慎使用onPageScorll
      3. 合理封装组件:可以将一些高频执行setData的功能模块封装成组件,
      4. 图片懒加载:渲染页面时,只渲染出现在视图范围内的元素。
      5. 善用onload和onReady:
        • onload是页面加载阶段,在onload阶段请求页面展示数据,
        • onready是页面加载完成阶段,对于页面之后需要展示或者使用,但刚开始并不展示的数据可以在onReady阶段进行请求。

7,小程序登录流程

  1. 通过wx.login()获取code
  2. 向服务端发送code
  3. 服务端使用appid+appsecret+code登录凭证来对接微信接口服务
  4. 后端返回seesion_key+openId,
  5. 后端自定义登录态,与openid,session_key关联
  6. 后端返回给前端自定义登录状态
  7. 前端将登录状态存入本地(setStorageSync)
  8. 前端携带登录态发起业务请求
  9. 后端校验登录态,
  10. 后端返回业务数据

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-2rO9rkJy-1676604621014)(https://res.wx.qq.com/wxdoc/dist/assets/img/api-login.2fcc9f35.jpg)]

原生js

1,检测数据类型

  • 基本类型:typeof
  • 复杂类型:instanceof, Array.isArray() , object.prototype.toString.call( type )

2,call , apply 的区别以及功能

功能:对象A调用对象b的方法。改变this的指向,call的性能会更好一些。

不同的地方:传递参数不同,apply接收数组,call 接收参数1,2,3

3,== 和 === 的区别

==会进行类型隐式转换,===不会

4,什么是同源策略

同协议,同域名,同端口

5,js中的数据类型

基本类型:number,string ,boolean,null,undefined,symbol,

引用类型:array,object,

6,pormise的优缺点

  1. 优点
    • 统一异步api:
    • 可以链式调用。
    • 解决回调地狱(回调函数里嵌套回调函数)的问题
  2. 缺点
    • 无法取消promise
    • 如果不设置回调函数,promise内部抛出的错误,不会反应到外部
    • 当处于pending状态时无法获取状态进展到哪个阶段。
    • Promise 真正执行回调的时候,定义 Promise 那部分实际上已经走完了,所以 Promise的报错堆栈上下文不太友好。

7,浏览器的渲染过程

  1. 用户输入域名,然后dns解析成ip地址
  2. 浏览器根据ip地址请求服务器
  3. 服务器响应http请求,并返回数据给浏览器
  4. 浏览器开始渲染
    • 根据html,生成dom树
    • 根据css,生成css树
    • 将html树与css树结合,生成render树
    • 根据render树渲染页面
    • 遇到script,则暂停渲染,优先执行js,然后继续渲染。
    • 渲染完成。

8,哪些行为会造成内存泄漏

  1. 意外的全局变量
  2. 没有及时清除的定时器
  3. 脱离dom的元素引用(一个dom容器删除之后,变量未置为null,则其内部的dom元素则不会释放。)
  4. 持续绑定的事件(函数中addEventListener绑定事件,函数多次执行,绑定便会产生多次,产生内存泄漏。)
  5. 闭包
  6. console.log不能被垃圾回收

9,async/await的优缺点,他和pormise的使用场景分别是

  • **缺点:**await可能会造成线程阻塞
  • 优点:
    • 阅读性比较好。
    • 可以直接写在条件判断里
  • 使用场景:
    • 并行的请求最好用pormise
    • 不需要并行的时候,如果要传递参数,最好用pormise

10,Object 于与Map的区别:

  • 共同点:都是键值对的动态集合,支持删除和增加键值对

  • 不同点:

    区别 Map Object
    构造方式 let Map = new Map([
    [“key”,“value”]
    ])
    let obj = {
    key:value
    }
    key的类型 any string||symbol
    key的顺序 有序(按照插入先后) 无序
    size长度 通过访问Map.size属性 Object.keys() || for…in
    访问方式 判断用has(),获取用get(),删除用delete(),获取所有keys(),清空clear() .或者 []
    迭代 keys(),value(),entries() for…in
    JSON序列化 JSON.stringify(Array.from(map)) 通过JSON.stringify()

11,宏任务和微任务

  • 宏任务:
    • 由宿主(浏览器或node)发起
    • 包括:setTimeout,setInterval,MessageChannel I/O(消息通道),setImmediate(node环境),script(整体代码块)
  • 微任务:
    • 由js自身发起
    • MutationObserver(浏览器环境),pormise.[then/catch/finally],process.nextTick(node环境)
  • 执行顺序:
    • 首先必须先执行所有的初始化同步任务
    • 然后会检查微任务队列,并将其清空
    • 接着取出第一个宏任务
    • 当该宏任务执行完成,会检查这个宏任务中还有没有微任务,如果没有就执行下一个宏任务,如果有,则清空微任务。然后再执行下一个宏任务。

12,简述原型与原型链,原型链的作用有那些

  1. 原型:js声明构造函数时,会在内存中创建一个对应的对象,这个对象就是原函数的原型,构造函数中有个属性prototype就指向原型对象,而实例化出来的对象会拥有一个proto属性,也指向原型
  2. 原型链:当实例化的对象查找一个属性的时候,首先会在本身查找这个属性,如果没有,则去他的proto原型上去找,如果proto上没有,那么就去proto的原型中去找,这种链状过程就是原型链
  3. 作用:数据共享,节约空间,实现集成

13,什么是闭包?用途有那些?

  • 如果一个函数访问了此函数的父级及父级以上的作用域变量,那么这个函数就是一个闭包。

  • 用途:防抖(在指定时间内,用户多次触发事件只触发一次),节流(在指定间隔时间内,请求只发送一次)

  • 例子

    for(var i = 1;i<10;i++){
    	setTimeout(()=>{
    		console.log(i)
    	},1000)
    }
    //11,11,11,11....
    for(var i = 1;i<10;i++){
    	(setTimeout((j)=>{
    		console.log(i)
    	}),1000)(i)
    }
    //1,2,3,4,5,6,7...
    
  • 闭包的优点:

    • 减少全局变量的定义数量,避免全局变量污染
    • 读取函数内部变量
    • 在内存中维护一个变量,可以用作缓存
  • 闭包的缺点

    • 造成内存泄露,消耗内存,影响网页性能,解决方法是用完他之后,把他设置成null
    • 闭包可能在父函数外部改变父函数内部的值

TypeScript部分

1,将对象转化成数组

//type:类型别名  Record:用来定义对象的key和value  这句话的意思是定义一个key和value都是string类型的对象。
type Obj = Record<string,string>   

//定义一个接口
interface FormatItem{
 key:string,
 op:string,
 value:string,
}

function objToArray(obj:Record<string,Obj>) :FormatItem[]{
	return Object.keys(obj).reduce((value:Array<FormatItem> , key:string)=>{
		var op:string = Object.keys(obj[key])[0];
		value.push({key:key,op:op,value:obj[key][op]});
		return value;
	},[])
}
console.log(
    objToArray({
        key1: {
            op1: "value1",
        },
        key2: {
            op2: "value2",
        },
    })
);
// result示例
// [
//     {key: 'key1', op: 'op1', value: 'value1'},
//     {key: 'key2', op: 'op2', value: 'value2'}
// ]

2,反转句子

/**
 * @file 反转句子
 * 
 * 同时满足以下条件:1、去除首尾空格,2、单词间隔中多个空格变成一个;
 * 注意console示例运行结果
 */

function reverseWord(str: string) {
	// 补全此处代码
	return (<string[]>str.match(/\S+/g)).reverse().join(" ");
}

console.log(reverseWord('the sky is blue')); // blue is sky the
// 去除首尾空格
console.log(reverseWord("  hello world  ")); // world hello
// 单词间隔中多个空格变成一个
console.log(reverseWord("a good   example")); // example good a

export default {}

3,找出字符串中第一个只出现一次的字符

/**
 * @file 找出字符串中第一个只出现一次的字符
 */

function firstSingleChar(str: string) {
  // 参考答案
  return str.split("").filter((item: string, index: number, arr: string[]) => {
    arr.splice(index, 1);
    return !arr.includes(item);
  })[0];
}

// a 和 b 都出现了两次,只有 c 出现了一次,返回 c
console.log(firstSingleChar("abcba")); // c
// b c d 都出现了一次,返回第一个
console.log(firstSingleChar("aabcdee")); // b
// a 和 b 都出现了多次,没有只出现一次的元素,返回 undefined
console.log(firstSingleChar("aaaabbbb")); // undefined
console.log(firstSingleChar("dabvb"));

export default {};

4,合并两个有序数组

/**
 * @file 合并两个有序数组
 */

function merge(arr: number[], arr2: number[]): number[] {
  // 参考答案
  return arr.concat(arr2).sort((a: number, b: number) => a - b);
}

// 参数数组从小到大排列
console.log(merge([1, 2, 3], [2, 5, 6])); // [ 1, 2, 2, 3, 5, 6 ]

export default {};

5,实现数组 map 方法

/**
 * @file 实现数组 map 方法
 */

function myMap(arr: T[], callbackFn: (v: T) => R): R[] {
  // 参考答案
  var arr1: R[] = [];
  for (var i = 0; i < arr.length; i++) {
    if (i in arr) arr1[i] = callbackFn(arr[i]);
  }
  return arr1;
}
// 测试
console.log(myMap([1, 2, 3], (v) => v * 2)); // [2, 4, 6]

export default {};

6, 二叉树所有路径

/**
 * @file 二叉树所有路径
 */

type Tree = {
  value: number;
  left?: Tree;
  right?: Tree;
};

const tree: Tree = {
  value: 1,
  left: {
    value: 2,
    right: { value: 5 },
  },
  right: { value: 3 },
};

function treePath(root: Tree): string[] {
  // 补全此处代码
  // throw new Error('功能待实现');
  const answer: [] = [];
  let tmp: [][] = [];
  const travel = (r: Tree) => {
    if (r == null) {
      return;
    }
    //@ts-ignore
    tmp.push(r.value);
    if (r.left == null && r.right == null) {
      //@ts-ignore
      answer.push(tmp);
      tmp = [tmp[0]];
      return;
    }
    if (r.left) travel(r.left);
    if (r.right) travel(r.right);
  };
  travel(root);
  //@ts-ignore
  return answer.map((t) => t.join("->"));
}
console.log(treePath(tree)); // [ '1->2->5', '1->3' ]

export default {};

7,树结构映射

/**
 * @file 树结构映射
 * 数组 map 保持数组长度相同,将对应位置元素进行映射。
 * 与之类似,在二叉树 Tree 上的映射我们称为 mapTree,该函数返回一个结构相同的新树,对应位置 value 字段经过 fn 映射。
 */

type Tree = {
  value: number;
  left?: Tree;
  right?: Tree;
};

function mapTree(tree: Tree, fn: (v: number) => number): Tree {
  // 参考答案
  if (tree == null) {
    return tree;
  }
  tree.value = fn(tree.value);
  if (tree.left) mapTree(tree.left, fn);
  if (tree.right) mapTree(tree.right, fn);
  return tree;
}

// 测试
const tree: Tree = {
  value: 1,
  left: { value: 2 },
  right: { value: 3 },
};
console.log(mapTree(tree, (v) => v * 2)); // { value: 2, left: { value: 4 }, right: { value: 6 } }

export default {};

8,计算数组笛卡尔积

/**
 * @file 计算数组笛卡尔积
 */

// 示例
console.log(product([1, 2], [3, 4])); // [[1, 3], [1, 4], [2, 3], [2, 4]]

function product(xList: number[], yList: number[]): [number, number][] {
  // 参考答案
  return xList.reduce((v, t) => {
    return v.concat(yList.map((item) => [t, item]));
  }, [] as [number, number][]);
}

export default {};

9,返回一个 Promise,并在 ms 毫秒后 Promise 变为完成状态

/**
 * @file 返回一个 Promise,并在 ms 毫秒后 Promise 变为完成状态
 */

export function sleep(ms: number): Promise<undefined> {
  // 参考答案
  return new Promise(
    (
      resolve: (value: undefined) => void,
      reject: (value: undefined) => void
    ) => {
      setTimeout(() => {
        resolve(undefined);
      }, ms);
    }
  );
}

async function main() {
  console.log("a");
  await sleep(1000);
  console.log("b");
  await sleep(1000);
  console.log("c");
}
main();

export default {};

10,实现 PromiseAll 方法

/**
 * @file 实现 PromiseAll 方法
 */

import { sleep } from "./8.sleep";

async function myAll<T extends unknown[] | []>(
  values: T
): Promise<{ [P in keyof T]: Awaited<T[P]> }> {
  // 补全此处代码,使用 Promise.all 以外的语法完成
  // throw new Error('功能待实现');
  var arr = [];
  for (var i = 0; i < values.length; i++) {
    arr.push(await values[i]);
  }
  return arr as { [P in keyof T]: Awaited<T[P]> };
}

// 一秒钟后返回结果 value
async function request(value: string) {
  await sleep(1000);
  return value;
}
async function main() {
  console.log("start");
  const res = await myAll([request("a"), request("b"), request("c")]);
  console.log(res); // 预期输出 start 一秒后输出 ['a', 'b', 'c']
}
main();

export default {};

11,假设加法是一个异步过程,如何计算多个数组之和?

/**
 * @file 假设加法是一个异步过程,如何计算多个数组之和?
 */
function sleep(ms: number) {
  return new Promise((r) => {
    setTimeout(() => {
      r(undefined);
    }, ms);
  });
}

async function asyncAdd(a: number, b: number) {
  await sleep(1000);
  return a + b;
}

async function sum(arr: number[]): Promise<number> {
  // 参考答案
  var s: number = arr[0];
  for (var i = 1; i < arr.length; i++) {
    s = await asyncAdd(s, arr[i]);
  }
  return s;
}

console.time("a");
sum([1, 2, 3, 4, 5, 6, 7, 8]).then((v) => {
  console.log(v); // 36
  console.timeEnd("a"); // a: <耗时>
});

export default {};

12,typescript的主要特点是什么?

  • 跨平台:ts编译器可以安装在任何平台上
  • es6特性:包含es6的大部分特性,如箭头函数
  • 是一种面向对象的语言:如类,接口,模块
  • 可选的静态类型
  • DOM操作

13,使用ts有什么好处

  • 代码阅读性更好
  • 调试简单:高级调试器专注于在编译之前捕获逻辑错误。
  • 跨平台

14,ts的基本类型

  • Number:let num1:number = 1;
  • string:let str = “字符串”
  • 布尔型:true||false
  • null型:表示未定义的值
  • any:任意类型
  • unknown:类型安全的any
  • [] || Array :数组类型
  • 元组:元组类型用来表示已知元素数量和类型的数组。各个元素类型可以不同,但是位置必须相同
  • enum:枚举类型用于定义数值集合 enum Color {“red”,“green”,“Blue"}
  • void:用于表示方法的返回值类型,
  • undefined:表示值未定义
  • never:表示从不会出现的值

15,什么是any类型?在什么时候使用?

  • any表示任何值,只要沾上了any就代表ts将不会对这个值进行类型检查。
  • 当一个变量需要赋值的数据类型不确定时,可以使用any类型,他可以赋值任何类型

16,什么是void?适用于什么场景

  • 以函数举例,当函数没有返回值的时候,可以适用void。注意不能将null 返回给void

17,在ts中,声明变量用哪些关键字

  • type:只能声明一次
  • interface:可以声明多次
  • enum:声明一个枚举变量
  • let const var

18,如何在ts中创建一个对象?

let obj:{x:number,y:string}={
	x:1,
	y:"字符串"
}

19,如何在ts中指定可选属性?

​ 使用变量名+?:类型即可

20,说说枚举

enum枚举用来定义一组常量

21,说说ts中for循环的几种变体

  • for(let i = 0;i
  • array.forEach()
  • for…of

22,接口(interface)和类型别名(type)的区别

  • 接口基本使用

    • 接口可以重名,可以合并,
    • 用接口约束的对象 或者 类 要和接口里的一样,不能多 不能少。
    interface yourType{
    	name:string,
    	age:number
    }
    iterface yourType{
    	height:number
    }
    let you:yourType = {
    	name:"***",
    	age:12,
    	height:175
    }
    
  • 类型别名基本使用

    • 描述一个对象的类型
    • 特点是:名称唯一 ,不能重复,实例化出来的对象属性不能多不能少。
  • 区别:

    • 接口名称可以重复,而type不可以
    • 接口可以重复定义
    • type可以使用in关键字生成映射类型,而接口不行
  • 使用建议:优先使用interface,公用的使用interface,其次再用type

23,谈谈泛型和any的区别

  • 相同点:都是用来定义一个未知类型的变量
  • 不同点:
    • any:ts将跳过对此变量的类型检查
    • 泛型:不预先指定具体的类型,而是在使用的时候再使用来指定指定具体类型。

24,泛型的使用

  • 在函数中使用

    function echo<T>(arg:T){
    	return arg;
    }
    
  • 在类中使用

    class Animal<T>{
    	name:T;
    	constructor(name:T){
    		this.name = name;
    	}
    	action<T>(say:T){
    		console.log(say);
    	}
    }
    
  • 在接口中使用

    interface Animall<T,U>{
    	key:T,
    	value:U
    }
    

25,ts中的类型断言是什么?

  • 语法:值 as 类型 他的意思是说,我认为这个值是某个类型,编译器 请跳过检查。
  • 特点:联合类型可以断言为其中一个类型,父类可以断言为子类,任何类型都可以断言成any。
  • 注意:类型断言只会影响ts编译时的类型,编译结果出来后,类型断言会被删除。

26,如何使用ts将字符串转换为数字,

  • 使用parseInt
  • 使用parseFloat
  • 使用+ 号 +3

27,ts中的类是什么?

  • 类表示一组相关对象的共享行为和属性

28,如何在node环境运行ts文件

安装ts-node, 然后使用命令ts-node fileName

29,解释rest参数和声明rest参数的规则

  • 含义:其余参数允许你将不同数量的参数(零个或多个)传递给函数。
  • 语法:function (arg1:string, ...names:string[]){},表示剩余参数存在了names数组里
  • 注意:rest参数必须是参数定义的最后一个,并且每个函数只能拥有一个rest参数

30,omit是什么?

  • Omit允许你通过传递Type并选择Keys在新类型中省略来构造类型。Omit会构造一个除类型K外具有T性质的类型
  • 语法:Omit; 参数:第一个为继承的type类型,第二个为想要的key的字符串,多个字符串用|分开
  • 简而言之,就是继承一个接口,然后过滤掉不想要的接口属性

31,如何实现函数重载

函数名相同,但参数类型或返回值不同的函数就是重载。两个函数必须接收相同数量的参数

32,如何让接口的所有属性都可选?

使用映射类型

  • 语法:{ readonly [p in K] ?: T} //in 表示遍历,T表示ts中的任意类型

  • 常见的类型语法:

    1,{ [P in K] : T } // 默认不可选
    2, { [P in K] ?: T} //全都是可选的
    3,{ [P in K ] -?: T} //  -号表示移除可选 ,这句的意思是把P都移除可选修饰符
    4,{ readonly [P in K] : T} //全是只读的
    5,{ readonly [P in K] ?: T} //添加只读修饰符
    6,{ -readonly [P in K] ?: T} //移除只读修饰符
    
  • 这题的答案应该是用{ [P in K ] ?: T}

33,ts中的模块指的是什么?

  • 指的是相关变量,函数,类和接口的集合。
  • 模块之间是用import引入,export来导出的。

CSS部分

1,什么叫做伪类,伪元素?都包括什么?

  1. 伪类(使用单冒号:):用来定义元素特殊状态的。如鼠标悬停,焦点样式,链接样式。举例:hover,active,link。
  2. 伪元素(使用双冒号::):新建的一个虚拟元素,他不存在于文档中。判断是否是伪元素就看他是不是新建的元素

2,回流,重绘

  • 回流:元素的大小或者位置发生了改变,触发了 页面重新布局而导致渲染树重新计算布局或者渲染

    • 改变窗口大小,
    • 改变文字大小,
    • 添加/删除样式表
    • 用户输入
    • 激活伪类等等
  • 重绘:元素样式的改变(但宽高,大小,位置不变),只改变自身元素,不改变其他元素。包括:

    • outline(设置元素轮廓),visibility(元素是否可见),color(颜色),background-color(背景色)

3,Animation和Transition 的区别是什么?

都是实现动画效果的,区别是,Animation可以定义动画关键帧,因此可以实现更复杂的动画效果。

4,媒体查询的使用方法:

  • 语法:@media 媒体类型 and (媒体特性){样式规则}
  • 书写顺序:当使用 @media screen (min-width:xxxpx) 时,小分辨率要放在大分辨率上面,如先写768px,再写992,再写1440,如果是用max-width时,要先写大的,再写小的

5,响应式布局有哪些?简述一下这些响应式布局

  • 百分比布局:缺点是需要按照设计稿,换成成百分比单位
  • 媒体查询布局(@media):缺点是css代码量会增加很多,常用断点尺寸:576(small),>=576(sm) ,=>769(md),=>992(lg),=>1200(xl),=>1400(xxl)。实际开发中,使用栅格布局+断点设定实现响应式
  • rem布局:
    • rem是相对于html根元素的字体大小的单位
    • 通过修改html中根元素字体大小,来控制rem的大小
    • flexible.js插件可以实现。
  • vw,vh响应式布局
  • flex布局(不会脱离文档流),常用属性:
    • felx-direction(主轴方向):row/row-reverse/column/column-reverse
    • flex-wrap(是否换行):nowrap/wrap/wrap-reverse
    • flex-flow(direction,wrap的简写):第一个参数是direction,第二个是wrap
    • justify-content(主轴上对齐方式):flex-start/flex-end/center/space-between/space-around
    • align-item(侧轴对齐):flex-start/flex-end/center/baseline(基线对齐)/stretch(拉伸)
    • align-content(多轴对齐):flex-start/flex-end/center/space-between/space-around/stretch
    • 项目属性(flex容器的子元素)
      • order:子元素排序,数值越大越靠后
      • flex-grow:子元素占领空间百分比,自动增长并填满空间
      • flex-shrink:当父元素空间不够时进行缩小,数值越大,缩小的越多,0为不收缩
      • flex-basis:子元素初始占据空间大小。
      • flex(flex-grow,flex-shrink,flex-basis的简写):默认值0,1,auto
      • align-self(单个子元素在侧轴上的对齐方式):auto/flex-start/flex-end/cener/baseline/stretch

6,canvas 常用api以及介绍

  • 简介:canvas标签是一个图形容器,可以用js脚本来绘制图形。主要应用在动画,游戏画面,数据可视化,图片编辑,以及实时视频处理方面。

  • 元素属性

    属性名 含义
    height canvas元素的高度 number
    width canvas元素的宽度 number
    getContext(“2d”) 获取canvas上下文 2d
    toDataURL(type, encoderOptions) 返回一个数据URL,该URL包含由类型参数指定的格式的图像(默认为png) encoderOptions在指定图片格式为 image/jpeg 或 image/webp的情况下,可以从 0 到 1 的区间内选择图片的质量
    toBlob(callback, type, encoderOptions) 回调函数,可获得一个单独的Blob对象参数 其余两个参数含义同上
  • 线条相关(设定线条样式,偏移量,实线虚线的):

    属性 描述
    lineWidth 线的宽度 number
    lineCap 线末端的类型 butt,round,square
    lineJoin 两线相交拐点类型 miter,round,bevel
    miterLimit 斜切面限制比例 10
    setLineDash([]) 设置当前的线段样式 数组里的值依次对应虚线的线段和空白的长度,依次重复
    lineDashOffset(offset) 从哪里开始绘制线
  • 绘制矩形

    属性 描述
    clearRect(x,y,width,height) 清除指定区域矩形
    fillRect(x,y,width,height) 填充指定区域矩形
    strokeRect(x, y, width, height) 使用当前的绘画样式(包括颜色等),描绘一个矩形
  • 路径

    属性 描述
    beginPath() 开始一条路径,或重置当前的路径。
    closePath() 使笔点返回到当前自路径的起始点
    moveTo(x, y) 将一个新的子路径的起始点移动到指定坐标
    lineTo(x, y) 链接到指定坐标,可以理解为画到哪里
    arc(x, y, r, startAngle, endAngle, 是否逆时针) 绘制一段圆弧
    arcTo(x1, y1, x2, y2, r) 绘制两个点之间半径为r的圆弧
    rect(x, y, width, height) 绘制一个矩形,可以通过fill或者stroke来填充或描边
    bezierCurveTo() 贝塞尔曲线
  • 绘制路径

    属性 描述
    fill() 填充路径
    stroke() 描边路径
    clip() 将当前创建的路径设置为当前剪切路径的方法
  • 填充和描边

    属性名 作用 默认值
    fillStyle 设置或返回用于填充绘画的颜色、渐变或模式。
    strokeStyle 属性设置或返回用于笔触的颜色、渐变或模式。
  • 渐变:返回的CanvasGradient对象的addColorStop(offset, color)添加渐变颜色

    属性名 作用 默认值
    createLinearGradient(x0, y0, x1, y1) 创建一个沿参数坐标指定的直线的渐变。该方法返回一个线性 对象 返回值可以作为描边或者填充的值使用
    createRadialGradient(x0, y0, r0, x1, y1, r1) 确定两个圆的坐标,放射性渐变
  • 图案:返回CanvasPattern对象,可以把此模式赋值给当前的fillStyle等,在 canvas 上绘制出效果

    属性名 作用 默认值
    createPattern(image, repetition) 用指定的图片创建图案 image可以是图片,视频,canvas的Element,或者canvas上下文,ImageData,Blob, ImageBitmap; repetition是重复方式,跟css里的背景图片重复参数一样
  • 绘制文本

    属性名 作用 默认值
    fillText(text, x, y,[maxWidth]) 在指定位置填充绘制文本,最大宽度可选
    strokeText(text, x, y,[maxWidth]) 在指定位置描边绘制文本,最大宽度可选
    measureText(text) 返回TextMetrics 对象
  • 文本样式

    属性名 作用 默认值
    font 设置字体 格式跟css的font一样 关于字体的样式都是在这里一起设置的
    textAlign 文本对齐方式 start, end , left, right, center
    textBaseline 基线对齐方式 top, hanging, middle, alphabetic (默认),ideographic, bottom.
    direction 文本方向 ltr, rtl, inherit (默认)
  • 阴影

    属性名 作用 默认值
    shadowColor 阴影颜色
    shadowBlur 阴影模糊程度
    shadowOffsetX 阴影水平偏移量
    shadowOffsetY 阴影垂直方向偏移量
  • 变换

    属性名 作用 默认值
    rotate(deg) 坐标系顺势转旋转指定角度
    scale(x, y) canvas每个单位添加缩放变换
    translate(x, y) 对当前坐标系平移
    transform()
    setTransform()
    resetTransform()
  • 合成

    属性名 作用 默认值
    globalAlpha 合成到canvas之前,设置图形和图像的透明度
    globalCompositeOperation 设置如何在已经存在的位图上绘制图形和图像 详细用法
  • 绘制图像

    属性名 作用 默认值
    drawImage() 绘制图像 ctx.drawImage(image, dx, dy); 或者ctx.drawImage(image, dx, dy, dWidth, dHeight); 或者 ctx.drawImage(image, sx, sy, sWidth, sHeight, dx, dy, dWidth, dHeight);
  • 像素控制

    属性名 作用 默认值
    createImageData(width, height 或者 imagedata) 创建一个新的、空白的、指定大小的imageData对象 从现有的 ImageData 对象中,复制一个和其宽度和高度相同的对象。图像自身不允许被复制。
    getImageData(sx, sy, sw, sh) 用来描述canvas区域隐含的像素数据,这个区域通过矩形表示,起始点为(sx, sy)、宽为sw、高为sh
    putImageData() ctx.putImageData(imagedata, dx, dy);或 ctx.putImageData(imagedata, dx, dy, dirtyX, dirtyY, dirtyWidth, dirtyHeight);
  • canvas状态

    属性名 作用 默认值
    save() 使用栈保存当前的绘画样式状态,你可以使用 restore() 恢复任何改变
    restore() 恢复到最近的绘制样式状态,此状态是通过 save() 保存到”状态栈“中最新的元素
    canvas

你可能感兴趣的:(前端,javascript,前端,vue.js)