答:
答:
注意:
区别:
答:
使用 :class 进行绑定
//绑定一个对象
编译后:
//绑定一个数组
编译后:
let isActive = "hello"
let activeClass = "activeValue"
let errorClass = "errorValue"
使用内联样式进行绑定
答
应用场景:如果切换不是太频繁,则应该使用v-if,反之使用v-show
区别:v-if是销毁后在新建,v-show则是通过display:none来控制,v-show的性能比v-if的性能要高一些
答: vue2中v-for优先于v-if,vue3相反。不建议在同一节点同时使用vif,与v-for,如果想过滤一些数据的话,可以这样做
//computedItems是经过处理后的数据列表。
答:push(),pop(),shift(),unshift(),splice(),sort(),reverse()
修饰符 | 说明 |
---|---|
.stop | 事件停止冒泡 |
.prevent(坡蕊温特) | 阻止标签默认行为 |
.capture | 使用事件捕获模式,即元素自身触发的事件先在此处处理,然后才交由内部元素进行处理 |
.self | 只当在event.target 是当前元素自身时触发处理函数 |
.once | 事件将只会触发一次 |
.passive([ˈpæsɪv]) | 不阻止事件默认行为 |
修饰符 | 说明 |
---|---|
.enter | 按回车 |
.tab | TAB键 |
.delete | 删除键 |
.esc | ESC |
.space ([speɪs]) | 空格 |
.up||.down||.left||.right | 上下左右方向键 |
修饰符 | 说明 |
---|---|
.lazy | 在每次 change 事件后更新数据 |
.number | 用户输入自动转换为数字,如果parseFloat()无法解析,那么则返回原始值 |
.trim | 去除用户输入值两端的空格 |
生命周期(页面) | 说明 |
---|---|
beforeCreate | 组件实例被创建之前,此时data还未生成。 |
created | 实例创建后,此时vm已经生成,但是还未挂载到页面上,el还未生成 |
beforeMount | 实例挂载前,此时vm即将要挂载到dom上,el还不生成 |
mounted | 实例挂载后,此时页面已经渲染成功,可以访问到el |
beforeUpdate | 实例数据更新前, |
updataed | 数据更新后 |
beforedestory | 实例销毁前,此时实例还未销毁 |
destoryed | 实例销毁后 |
生命周期(组件) | 说明 |
---|---|
actived | 被 keep-alive 缓存的组件激活时调用。 |
deactivated | 被 keep-alive 缓存的组件失活时调用。 |
生命周期(组合式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 | 在捕获了后代组件传递的错误时调用。 |
全局注册:vue.component
//语法
vue.component(componentName:string,template:components)
局部注册
组合式api:使用defineProps函数
let props = defineProps({
prop1
})
选项式api:props
props:{
prop1,
}
答:因为vue中组件是复用的,如果组件中的data返回的是个对象的话,那么在多个组件同用一个data的时候,往往这个组件中的data发生了改变,那么其他组件也会发生改变。为了避免这个问题,就必须返回一个函数,这就相当于为每个组件开辟了一个私有的data
答:
答:
区别:
watchEffect的触发时机
语法
watch(source, callback, options)
watchEffect(callback, options)
post:能在侦听器回调中访问被 Vue 更新之后的 DOM,他的另一个别名函数叫做:watchPostEffect()
sync:有必要在响应式依赖发生改变时立即触发侦听器的时候 别名:watchSyncEffect()
watch的options
watch (source: WatchSource, callback: WatchCallback, options?: WatchOptions)
watchOptions:{
immediate ( [ɪˈmiːdiət] ):boolean, // 侦听器创建时立即触发回调。第一次调用时旧值是 undefined
deep:boolean,//如果源是对象,强制深度遍历,以便在深层级变更时触发回调
flush:post|sync,//触发时机
onTrack / onTrigger:调试侦听器的依赖。
}
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不推荐用了,可以用组合式函数来代替 |
api | 说明 | 补充 |
---|---|---|
nextTick(callback?: () => void): Promise | 等待下一次 DOM 更新刷新的工具方法。 | 常用来解决同步失效的问题 |
defineComponent(component: ComponentOptions | ComponentOptions[‘setup’]):ComponentConstructor | 在定义 Vue 组件时提供类型推导的辅助函数。 | 最大的用处就是给ts提供更好的类型推导 |
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() ) 提供的值。也可以理解为接收 |
答:
通过路由中的meta对象下的keepAlive(boolean)属性来控制缓存组件是否缓存
语句:this.$route.meta.keepAlive=true||false
分类:
具名插槽:带有名字的插槽
//组件内
//这个name就是插槽的名字
//使用组件
//v-slot后面跟的就是刚才设定的插槽名字
插槽内容
匿名插槽:没有名字的插槽,一个标签只能有一个匿名插槽
作用域插槽:
{{ text }} {{ count }}
动态插槽名:
...
...
缩写形式:#
作用:可以扩展组件,增加组件的灵活性
动态组件
动态组件需要用keep-alive标签
异步组件
异步组件需要使用vue.component(“组件名”,callback():promise),返回一个模板对象
vue2:
使用了Object.defineProperty结合发布者/订阅设计模式,递归遍历对象的每个属性,为每个属性都设置了setter/getter,一旦属性发生了变化,则通知相关的订阅者,订阅者调用setter直接改变对象的属性
vue3:
使用Proxy代理对象来实现。
答:存储在state中,改变state的状态只能通过mutation,或者通过Action使用commit触发mutation来改变状态
答:
答:
可以,因为每一个子模块中都有 state,namespaced,mutations,actions,getters,modules,而且模块中多了一个属性namespace(命名空间),当模块被注册后,它的所有 getter、action 及 mutation 都会自动根据模块注册的路径调整命名,
答:
在组合式api中,需要先引入useStore函数import {userStore} form vuex
答:
vue-router是vue官方指定的路由插件,是单页面应用的核心组成部分,vue-router用于设定访问路径,并将路径和组件映射起来。传统多页面应用中,页面跳转是用超链接来实现页面切换和跳转的,但在单页面应用中,页面跳转则是使用路径的切换,路由的作用是建立url和页面的映射关系
vue-router的实现主要靠url中的hash和history中新增的接口来实现的。
新建一个router文件夹,建立一个index文件,然后引入router,创建一个routers路由表,实例化一个router对象,使用这个路由表,设定mode
全局守卫:
独享守卫:beforeEnter()
组件内守卫
编程式路由
声明式路由
获取路由参数
this. r o u t e . p a r a m s , t h i s . route.params,this. route.params,this.route.query
route是页面路由对象,他里面会有query,params等属性,router是全局路由对象mate路由元数据等
库 | 说明 | 补充 |
---|---|---|
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端运行的下拉刷新和上拉加载插件,主要用于列表分页、刷新等场景。 |
**写法:**以 #ifdef 或 #ifndef 加 %PLATFORM% 开头,以 #endif 结尾。
使用onPageScroll 生命周期函数监听
在onTabItemTap()生命周期中写入代码
可能页面上存在图片,但是没有指定高度。
核心点:
提高加载性能
加载流程:
代码包准备(下载代码包)优化措施:
开发者代码注入
减少启动过程的同步调用
使用懒注入
通常情况下,小程序启动时,启动页面所在分包和主包(独立分包除外)的所有js代码会全部合并注入,包括其他未访问到的页面和未用到的自定义组件。影响注入耗时和内存占用
开启仅注入当前页面需要的自定义组件和当前页面代码,在app.json中配置
{
"lazyCodeLoading":"requiredComponents"
}
初次渲染
提高渲染性能
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-2rO9rkJy-1676604621014)(https://res.wx.qq.com/wxdoc/dist/assets/img/api-login.2fcc9f35.jpg)]
功能:对象A调用对象b的方法。改变this的指向,call的性能会更好一些。
不同的地方:传递参数不同,apply接收数组,call 接收参数1,2,3
==会进行类型隐式转换,===不会
同协议,同域名,同端口
基本类型:number,string ,boolean,null,undefined,symbol,
引用类型:array,object,
共同点:都是键值对的动态集合,支持删除和增加键值对
不同点:
区别 | 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() |
如果一个函数访问了此函数的父级及父级以上的作用域变量,那么这个函数就是一个闭包。
用途:防抖(在指定时间内,用户多次触发事件只触发一次),节流(在指定间隔时间内,请求只发送一次)
例子
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...
闭包的优点:
闭包的缺点
//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'}
// ]
/**
* @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 {}
/**
* @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 {};
/**
* @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 {};
/**
* @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 {};
/**
* @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 {};
/**
* @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 {};
/**
* @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 {};
/**
* @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 {};
/**
* @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 {};
/**
* @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 {};
let obj:{x:number,y:string}={
x:1,
y:"字符串"
}
使用变量名+?:类型即可
enum枚举用来定义一组常量
接口基本使用
interface yourType{
name:string,
age:number
}
iterface yourType{
height:number
}
let you:yourType = {
name:"***",
age:12,
height:175
}
类型别名基本使用
区别:
使用建议:优先使用interface,公用的使用interface,其次再用type
在函数中使用
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
}
值 as 类型
他的意思是说,我认为这个值是某个类型,编译器 请跳过检查。+3
安装ts-node, 然后使用命令ts-node fileName
function (arg1:string, ...names:string[]){}
,表示剩余参数存在了names数组里函数名相同,但参数类型或返回值不同的函数就是重载。两个函数必须接收相同数量的参数
使用映射类型
语法:{ 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}
:
):用来定义元素特殊状态的。如鼠标悬停,焦点样式,链接样式。举例:hover,active,link。::
):新建的一个虚拟元素,他不存在于文档中。判断是否是伪元素就看他是不是新建的元素回流:元素的大小或者位置发生了改变,触发了 页面重新布局而导致渲染树重新计算布局或者渲染
重绘:元素样式的改变(但宽高,大小,位置不变),只改变自身元素,不改变其他元素。包括:
都是实现动画效果的,区别是,Animation可以定义动画关键帧,因此可以实现更复杂的动画效果。
@media 媒体类型 and (媒体特性){样式规则}
@media screen (min-width:xxxpx)
时,小分辨率要放在大分辨率上面,如先写768px,再写992,再写1440,如果是用max-width时,要先写大的,再写小的简介: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 |