# 省赛题目
# 第一题
疑问:
- 怎么保持在网页缩放的时候,仍然是每 5 个换一次行的?
通过设置每个 flex 容器中每个 item 的 height 为 20% 的吧
# flex 布局
https://www.runoob.com/w3cnote/flex-grammar.html
align-content 中的多根轴线应该是指换行的时候,就具有多根轴线了
justify-content 和 align-items 分别是针对 单根 横轴 和 纵轴 的
两者的区别是,前者具有 space-between 和 space-around,后者具有 baseline 和 stretch
align-content 具有 justify-content 和 align-items 的 除 baseline 之外所有属性值
css 选择器: https://www.w3school.com.cn/cssref/css_selectors.asp
# 动画
@keyframe https://www.runoob.com/cssref/css3-pr-animation-keyframes.html
https://www.runoob.com/css3/css3-animations.html
translate、transform、scaleX、scale3d
3d 转换: https://www.runoob.com/css3/css3-3dtransforms.html https://developer.mozilla.org/en-US/docs/web/css/transform-function/scale3d
CSS animation-fill-mode 属性: https://www.w3school.com.cn/cssref/pr_animation-fill-mode.asp https://developer.mozilla.org/zh-CN/docs/Web/CSS/animation-fill-mode
# em
https://blog.csdn.net/h_o_l_y/article/details/51852202
# overflow
https://www.w3school.com.cn/cssref/pr_pos_overflow.asp 貌似这里特指文字内容,经测试,也并没有。
当子元素的内容超出父元素的大小的时候,设置子元素在父元素内的显示方式,比如加滚动条、隐藏等等。
这个属性不是和定位、浮动什么的直接联系在一起的。
# 定位
<!DOCTYPE html> | |
<html lang="en"> | |
<head> | |
<meta charset="UTF-8"> | |
<meta http-equiv="X-UA-Compatible" content="IE=edge"> | |
<meta name="viewport" content="width=device-width, initial-scale=1.0"> | |
<title>Document</title> | |
<style> | |
.fa{ | |
background-color: blue; | |
width: 300px; | |
/* height: 300px; */ | |
position: relative; | |
} | |
.son{ | |
background-color: red; | |
width: 200px; | |
height: 200px; | |
position: absolute; | |
/* position: relative; */ | |
left: 50px; | |
top: 50px; | |
} | |
</style> | |
</head> | |
<body> | |
<div class="fa"> | |
<div class="son"> | |
</div> | |
</div> | |
</body> | |
</html> |
在上面的代码中,存在父元素高度塌陷的情况,但是子元素以 px 的形式设置了高度和宽度,最终子元素是有显示的。
但是,如果将上面子元素的高度设置为 height: 100%;
,则将导致子元素的高度为 0,就不能继续显示了。
可见,无论怎么定位,当以百分号的形式设置子元素的高度时,计算是和父元素的高宽度直接相关的。
- 为什么在父元素高度塌陷之后,子元素也不显示了?
- 从父元素到 body,都没有用到定位,且它们的高度均没有设置,子元素设置为绝对定位,高度设置为 100%,且子元素的子元素的高度都是用百分号的形式设置的,最后子元素的高度为浏览器窗口的高度,为什么?
参考这片博客: https://blog.csdn.net/qq_32899575/article/details/82685653?spm=1001.2101.3001.6661.1&utm_medium=distribute.pc_relevant_t0.none-task-blog-2~default~BlogCommendFromBaidu~Rate-1-82685653-blog-114939049.pc_relevant_vip_default&depth_1-utm_source=distribute.pc_relevant_t0.none-task-blog-2~default~BlogCommendFromBaidu~Rate-1-82685653-blog-114939049.pc_relevant_vip_default&utm_relevant_index=1
但是在测试的时候发现的问题是,子元素的高宽度用百分号的形式表示,假如子元素设置了 absolute,往上的父元素只有 static,最后子元素的高宽度是相对浏览器窗口的页面大小的,而不是 html 元素的大小。
当设置了绝对定位之后,html 元素的高度和宽度并不是浏览器页面窗口的高度和宽度。
# 第二题
# transition
https://www.w3school.com.cn/cssref/pr_transition.asp
https://developer.mozilla.org/zh-CN/docs/Web/CSS/CSS_Transitions/Using_CSS_transitions
# transform-origin
https://developer.mozilla.org/zh-CN/docs/Web/CSS/transform-origin
# transform
https://www.w3school.com.cn/cssref/pr_transform.asp
# 伪类
https://www.w3school.com.cn/css/css_pseudo_classes.asp
# hover 父对子、子对父、同级之间的控制
https://blog.csdn.net/coycleipenghui/article/details/108439007
https://www.jianshu.com/p/160dc5750826
# 第三题
# echarts
# 第四题
# promise
在 Promise 的构造函数中,传入的参数是一个函数(设为 func),func 接受两个函数名(一般命名为 resolve 和 reject)作为参数,在 func 中可以调用 resolve 和 reject,并可传入任意参数,在 func 的函数体中可以用到外部变量。
在 Promise 对象的 then 方法中传入两个函数的定义,这两个函数和 resolve 和 reject 调用时的参数要保持一致。
那在什么时候执行呢?在构造 Promise 对象的时候就立刻执行了
var outnum = function (order) { | |
return new Promise(function (resolve, reject) { | |
setTimeout(function () { | |
console.log(order); | |
resolve(); | |
}, 1000); | |
}); | |
}; | |
outnum("1") | |
.then(function () { | |
return outnum("2"); | |
}) | |
.then(function () { | |
return outnum("3"); | |
}) | |
.then(function () { | |
console.log("0"); | |
}); |
观察上面的代码,将 Promise 的构造放在一个函数中,这样 func 中就可以以外部变量的方式使用参数了
function p1(n) { | |
return new Promise(function (resolve, reject) { | |
setTimeout(function () { | |
if (n > 0) { | |
resolve(n); | |
} else { | |
reject("不能小于0"); | |
} | |
}, 1000); | |
}); | |
} | |
Promise.all([p1(5), p1(6), p1(7)]).then( | |
function (v) { | |
console.log(v); | |
}, | |
function (e) { | |
console.log(e); | |
} | |
); |
从上述效果可以看出,如全部任务执行成功,则将各个执行结果保存在数组中,可以通过 then 方法中的成功回调函数返回。
# await、async
async function fn() { | |
return "12345"; | |
} | |
fn().then((val) => { | |
console.log(val); | |
}); |
// 函数 p 返回的是一个 Promise 对象,在对象中,延时 2 秒,执行成功回调函数,相当于模拟一次异步请求 | |
function p(v) { | |
return new Promise(function (resolve) { | |
setTimeout(function () { | |
// 在 p 函数执行时,将函数的实参值 v ,作为执行成功回调函数的返回值。 | |
resolve(v); | |
}, 2000); | |
}); | |
} | |
// 一个用于正常输出内容的函数 | |
function log() { | |
console.log("2.正在操作"); | |
} | |
async function fn() { | |
console.log("1.开始"); | |
await log(); | |
let p1 = await p("3.异步请求"); | |
console.log(p1); | |
console.log("4.结束"); | |
} | |
fn(); |
如果 async 可以自动返回一个 Promise 对象,return 的传参相当于 resolve 的传参,那么是不是可以不用手动构造 Promise 对象了。
const f1 = async (v) => { | |
setTimeout(() => { | |
console.log(v); | |
return v; | |
}, 1000) | |
} | |
const f2 = async () => { | |
let p1 = await f1('p1'); | |
console.log('p1 是', p1); | |
let p2 = await f1(p1 + 'p2'); | |
let p3 = await f1(p2 + 'p3'); | |
console.log(p3); | |
console.log('yyy'); | |
} | |
f2(); |
async 不是这么用的,但是上面代码的具体原理尚不清楚,当时想把上面的代码的运行结果改成和下面的代码的运行结果一样。当时是想着,因为 async 返回一个 Promise 对象,所以能不能利用此机制,简化掉手动构造 Promise 对象的过程,结果没成功,在涉及延迟函数返回时还是要手动构造 Promise 对象。
// 函数 p 返回的是一个 Promise 对象,在对象中,延时 2 秒,执行成功回调函数,相当于模拟一次异步请求 | |
function p(v) { | |
return new Promise(function (resolve) { | |
setTimeout(function () { | |
// 在 p 函数执行时,将函数的实参值 v ,作为执行成功回调函数的返回值。 | |
resolve(v); | |
}, 1000); | |
}); | |
} | |
async function fn() { | |
let p1 = await p("1"); | |
let p2 = await p(p1 + "2"); | |
let p3 = await p(p2 + "3"); | |
console.log(p3); | |
console.log("登录成功!"); | |
} | |
fn(); |
那如果是 reject,该怎么利用 await 接收其参数呢?
Promise 的加入主要是为了解决回调过多的时候的代码可读性问题吧,但是如果不涉及回调的时候,直接在函数中写 setTimeout,函数调用前加 await 可以吗?
const f1 = (v) => { | |
setTimeout(()=>{ | |
console.log(v); | |
}, 2000) | |
} | |
const f2 = async () => { | |
let p1 = await f1('p1'); | |
let p2 = await f1('p2'); | |
console.log('yyy'); | |
} | |
f2(); |
上面的写法不行,虽然 p1 和 p2 等待了 2s,但是两者是同时输出的。下面的写法就可以了
const f1 = (v) => { | |
return new Promise((resolve) => { | |
setTimeout(() => { | |
console.log(v); | |
resolve(); // 得写这个,否则无法返回 | |
}, 1000); | |
}) | |
} | |
const f2 = async () => { | |
let p1 = await f1('p1'); | |
let p2 = await f1('p2'); | |
console.log('yyy'); | |
} | |
f2(); |
对比了一下,还是回调函数的问题,await 在这里觉得可以理解为等待 resolve 函数的调用。
# setTimeout
const f3 = ()=>{ | |
console.log(1); | |
setTimeout(()=>{ | |
}, 2000); | |
console.log(2); | |
} | |
f3(); |
上面的代码运行将同时输出 1 2,并非延迟两秒才输出 2. 这里就产生问题:怎么才能使执行完 setTimeout 中的内容后再执行接下来的代码?这应该只能将 setTimeout 接下来的代码写成它的回调函数,可要可不要借助 Promise 对象了。
const f3 = ()=>{ | |
console.log(1); | |
setTimeout(()=>{ | |
console.log(2); | |
}, 2000); | |
} |
上面的代码延迟 2s 再输出 2
async function fn() { | |
setTimeout(()=>{ | |
return "kkk"; | |
}, 1000); | |
// return "12345"; | |
} | |
fn().then((val) => { | |
console.log(val); | |
}); |
应该不能这么写代码,不能在 setTimeout 中设置调用它的函数的返回值,setTimeout 本来就属于函数调用。
# 第五题
# jq
// 1 | |
$(document).ready(function () { | |
$("body").html("Hello jQuery!"); | |
}); |
one 和 on 在绑定事件上的区别,用 one 绑定的时候,仅会执行一次。
# 其他学习笔记
# 模块化
一个模块就是一个 js 文件
export、import
如 export 的时候不是以对象的形式,在 import 的时候该怎么写呢?
# vue.js
双大括号差值、v-once、
属性和值:在很多时候属性貌似不用双引号(在 json 或者对象中),但是值需要双引号
<p v-once>msg:{\{msg}}</p> |
// 动态参数
<!DOCTYPE html> | |
<html lang="en"> | |
<head> | |
<meta charset="UTF-8" /> | |
<meta name="viewport" content="width=device-width, initial-scale=1.0" /> | |
<meta http-equiv="X-UA-Compatible" content="ie=edge" /> | |
<title>syl-vue</title> | |
<!--引入 vue.js--> | |
<script src="vue.min.js"></script> | |
</head> | |
<body> | |
<!-- 指令 动态参数--> | |
<div id="app"> | |
<p>我叫:{\{name}}</p> | |
<button v-on:[event]="handleClick">点我</button> | |
</div> | |
<script> | |
var app = new Vue({ | |
el: "#app", | |
data: { | |
name: "实验楼", | |
event: "click", | |
}, | |
methods: { | |
handleClick: function () { | |
this.name = this.name.split("").reverse().join(""); | |
}, | |
}, | |
}); | |
</script> | |
</body> | |
</html> |
表单 form 的 action 属性: https://zhuanlan.zhihu.com/p/144318685
<!DOCTYPE html> | |
<html lang="en"> | |
<head> | |
<meta charset="UTF-8" /> | |
<meta name="viewport" content="width=device-width, initial-scale=1.0" /> | |
<meta http-equiv="X-UA-Compatible" content="ie=edge" /> | |
<title>syl-vue-test</title> | |
<!-- 引入 vue.js --> | |
<script src="vue.min.js"></script> | |
</head> | |
<body> | |
<div id="app">{\{now}}</div> | |
<script> | |
var app = new Vue({ | |
el: "#app", | |
data: { | |
myNow: Date.now() | |
}, | |
computed: { | |
now: function () { | |
// return Date.now(); | |
return this.myNow; // 这里要加 this | |
/* 上面两种写法都不能实现 now 的自动变化,原因就是加载后变量的值没变 */ | |
}, | |
}, | |
}); | |
</script> | |
</body> | |
</html> |
当侦听属性的函数只设置了一个参数时,这个参数是新值。
侦听属性的对象中,键是 data 中的某个变量;而计算属性的键是自己命名的。
window.onload :https://www.runoob.com/w3cnote/javascript-window-onload.html
这里说的等网页加载完毕,但是 js 代码中有可能会对 dom 产生影响呢?这个需要考虑的吗?
原始的 js 代码中的事件前都是有 on 的,
$("div").mouseover(function () { | |
$(this).css("background-color", "blue"); | |
// 鼠标移除 | |
}) | |
var phone = document.getElementById("phone"); | |
phone.onkeydown = function () { | |
phone.style.color = "#00adb5"; | |
}; | |
<button v-on:click="counter+=1">点击</button> |
addeventlistener 和 上面的 js 原始 增加事件处理方法的比较:
https://www.runoob.com/jsref/met-element-addeventlistener.html
outline css 属性
<button v-on:click="say">点击</button> | |
var app = new Vue({ | |
el: "#app", | |
data: { | |
counter: 0, | |
}, | |
methods: { | |
// 声明事件点击监听 say 方法 | |
say: function (event) { | |
// 监听事件回调处理 event.type 触发事件类型 说明:`${}` 为 es6 模板字符串,拼接字符串的 | |
alert(`小楼提醒:你触发了${event.type}事件`); | |
}, | |
}, | |
}); |
上面的代码中,say 方法的参数设置为了 event 事件对象,那如果在触发事件的时候需要向相应的方法中传入参数呢?
看下面的代码,当没有传入参数的时候, @click='方法名'
,传入参数时, @click='方法名(参数)'
,同时方法的定义中就是该参数,而不再是事件对象
<body> | |
<div id="app"> | |
<!-- 绑定点击监听 共用 say 方法--> | |
<button v-on:click="say('实验楼')">实验楼</button> | |
<button v-on:click="say('小楼')">小楼</button> | |
</div> | |
<script> | |
var app = new Vue({ | |
el: "#app", | |
data: {}, | |
methods: { | |
// 声明事件点击监听 say 方法 | |
say: function (name) { | |
alert(`我是${name}`); | |
}, | |
}, | |
}); | |
</script> | |
</body> |
<!DOCTYPE html> | |
<html lang="en"> | |
<head> | |
<meta charset="UTF-8" /> | |
<meta name="viewport" content="width=device-width, initial-scale=1.0" /> | |
<meta http-equiv="X-UA-Compatible" content="ie=edge" /> | |
<title>syl-vue-test</title> | |
<!-- 引入 vue.js --> | |
<script src="vue.min.js"></script> | |
<style> | |
/* 居中 */ | |
.super, | |
.child { | |
position: absolute; | |
top: 0; | |
left: 0; | |
bottom: 0; | |
right: 0; | |
margin: auto; | |
} | |
.super { | |
width: 300px; | |
height: 300px; | |
background: pink; | |
} | |
.super .child { | |
width: 100px; | |
height: 100px; | |
background: green; | |
} | |
</style> | |
</head> | |
<body> | |
<div id="app"> | |
<div class="super" v-on:click="handleClick('super')"> | |
父 | |
<div class="child" v-on:click="handleClick('child')">子</div> | |
</div> | |
</div> | |
<script> | |
var app = new Vue({ | |
el: "#app", | |
data: {}, | |
methods: { | |
// 声明事件点击监听 handleClick | |
handleClick: function (name) { | |
alert(`我是${name}`); | |
}, | |
}, | |
}); | |
</script> | |
</body> | |
</html> |
在上面的例子中,父元素和子元素都设置为 absolute,那么子元素就还是在父元素的空间内,这样?但是两者都不占用祖先元素的空间了。
数字字符是可以和数字直接进行比较的
let s = '123aaa'; | |
let arr = s.split(''); // 数组 | |
console.log(arr); | |
console.log(2 > arr[0]); // true |
观察下面两者可以看到对于 fontSize 的设置是不同的,前者只需要设置一次,因此用字符串直接写好了;而后者尚且需要变化,因此设置成数字,在内联样式中再进行数字和字符串的拼接。
<!DOCTYPE html> | |
<html lang="en"> | |
<head> | |
<meta charset="UTF-8" /> | |
<meta name="viewport" content="width=device-width, initial-scale=1.0" /> | |
<meta http-equiv="X-UA-Compatible" content="ie=edge" /> | |
<title>syl-vue-test</title> | |
<!-- 引入 vue.js --> | |
<script src="vue.min.js"></script> | |
</head> | |
<body> | |
<div id="app"> | |
<p v-bind:style="[styleObject1,styleObject2]">你好,实验楼</p> | |
</div> | |
<script> | |
var app = new Vue({ | |
el: "#app", | |
data: { | |
// 样式一 | |
styleObject1: { | |
fontSize: "26px", | |
backgroundColor: "pink", | |
}, | |
// 样式二 | |
styleObject2: { | |
marginTop: "200px", | |
textAlign: "center", | |
}, | |
}, | |
}); | |
</script> | |
</body> | |
</html> |
<!DOCTYPE html> | |
<html lang="en"> | |
<head> | |
<meta charset="UTF-8" /> | |
<meta name="viewport" content="width=device-width, initial-scale=1.0" /> | |
<meta http-equiv="X-UA-Compatible" content="ie=edge" /> | |
<title>syl-vue-test</title> | |
<!-- 引入 vue.js --> | |
<script src="vue.min.js"></script> | |
<style> | |
.active { | |
color: red; | |
} | |
</style> | |
</head> | |
<body> | |
<div id="app"> | |
<p | |
v-bind:style="{fontSize:fontSize+'px'}" | |
v-bind:class="{active:isActive}" | |
> | |
你好,实验楼 | |
</p> | |
<button @click="handleClick">变大变色</button> | |
</div> | |
<script> | |
var app = new Vue({ | |
el: "#app", | |
data: { | |
fontSize: 20, | |
isActive: true, | |
}, | |
methods: { | |
handleClick: function () { | |
this.fontSize += 2; | |
this.isActive = !this.isActive; // 取反 | |
}, | |
}, | |
}); | |
</script> | |
</body> | |
</html> |
在下面这个布局下,为什么浏览器的窗口缩小到一定程度后就不能再继续缩小了呢?
<!DOCTYPE html> | |
<html lang="en"> | |
<head> | |
<meta charset="UTF-8" /> | |
<meta name="viewport" content="width=device-width, initial-scale=1.0" /> | |
<meta http-equiv="X-UA-Compatible" content="ie=edge" /> | |
<title>syl-vue-test</title> | |
<!-- 引入 vue.js --> | |
<script src="vue.min.js"></script> | |
<style> | |
* { | |
padding: 0; | |
margin: 0; | |
} | |
ul { | |
width: 100%; | |
height: 40px; | |
list-style: none; | |
display: flex; | |
flex-direction: row; | |
align-items: center; | |
justify-content: center; | |
background: yellowgreen; | |
} | |
ul li { | |
width: 20%; | |
height: 100%; | |
color: white; | |
line-height: 40px; | |
text-align: center; | |
text-transform: uppercase; /* 大写转换 */ | |
} | |
</style> | |
</head> | |
<body> | |
<div id="app"> | |
<ul class="nav"> | |
<li v-for="navItem in nav">{\{navItem}}</li> | |
</ul> | |
</div> | |
<script> | |
var app = new Vue({ | |
el: "#app", | |
data: { | |
nav: ["home", "shop", "contact", "about", "name", "mroe", "histroy"], | |
}, | |
}); | |
</script> | |
</body> | |
</html> |
<!DOCTYPE html> | |
<html lang="en"> | |
<head> | |
<meta charset="UTF-8" /> | |
<meta name="viewport" content="width=device-width, initial-scale=1.0" /> | |
<meta http-equiv="X-UA-Compatible" content="ie=edge" /> | |
<title>syl-vue-test</title> | |
<!-- 引入 vue.js --> | |
<script src="vue.min.js"></script> | |
</head> | |
<body> | |
<div id="app"> | |
<div v-for="val in userInfo"> | |
<p>{\{val}}</p> | |
</div> | |
</div> | |
<script> | |
var app = new Vue({ | |
el: "#app", | |
data: { | |
userInfo: { | |
name: "whh", | |
age: 1, | |
sex: "woman", | |
}, | |
}, | |
}); | |
</script> | |
</body> | |
</html> |
Vue.set (app.userInfo, "height", "170cm"); 这里居然没有使用到 data 属性,
input 标签设置了 id,其后跟着的 label 标签的 for 属性的值为其 id。
<!DOCTYPE html> | |
<html lang="en"> | |
<head> | |
<meta charset="UTF-8" /> | |
<meta name="viewport" content="width=device-width, initial-scale=1.0" /> | |
<meta http-equiv="X-UA-Compatible" content="ie=edge" /> | |
<title>vue</title> | |
<script src="vue.min.js"></script> | |
</head> | |
<body> | |
<div id="app"> | |
<!-- 将单选按钮绑定到同一个 picked --> | |
<input type="radio" id="one" value="One" v-model="picked" /> | |
<label for="one">One</label> | |
<br /> | |
<input type="radio" id="two" value="Two" v-model="picked" /> | |
<label for="two">Two</label> | |
<br /> | |
<span>Picked: {\{ picked }}</span> | |
</div> | |
<script> | |
var vue = new Vue({ | |
el: "#app", | |
data() { | |
return { | |
picked: "", | |
}; | |
}, | |
}); | |
</script> | |
</body> | |
</html> |
如何保证多个单选按钮是针对同一个问题的单选呢?设置 name 属性的值相同。
<form action="/demo/demo_form.asp"> | |
<input type="radio" name="sex" value="male" checked>Male | |
<br> | |
<input type="radio" name="sex" value="female">Female | |
<br><br> | |
<input type="submit"> | |
</form> |
提交的的是 value 属性的值,而不是标签内的文本。
在表单处理一节及以后中,data 使用的均是函数的形式,return 出去一个对象,将数据以键值对的形式定义在此对象中(这是不是意味着一定要给这个变量一个初值呢),而之前的节使用的是对象的形式。
# html 表单
https://www.w3school.com.cn/html/html_forms.asp
<form action="/demo/html/action_page.php"> | |
<label for="fname">First name:</label><br> | |
<input type="text" id="fname" name="fname" value="Bill"><br> | |
<label for="lname">Last name:</label><br> | |
<input type="text" id="lname" name="lname" value="Gates"><br><br> | |
<input type="submit" value="提交"> | |
</form> |
在上面的表单中,在文本框中填入的内容和 value 的值是保持一致的。
在下面的表单中,option 的 value 和标签内的文本并不相同,但是提交的时候,提交的是 value。
<form action="/demo/demo_form.asp"> | |
<select name="cars"> | |
<option value="volvo">Vdfjvo</option> | |
<option value="saab">Saab</option> | |
<option value="fiat">Fiat</option> | |
<option value="audi">Audi</option> | |
</select> | |
<br><br> | |
<input type="submit"> | |
</form> |
textarea 标签没有 value 属性。
<form action="/demo/html/action_page.php"> | |
<textarea name="message" rows="10" cols="30" >The cat was playing in the garden.</textarea> | |
<br><br> | |
<input type="submit"> | |
</form> |
在下面的代码中,两个单选按钮并没有设置 name 属性相同,但可能是因为使用 v-model 绑定了同一个数据,所以也可以实现单选效果。
<body> | |
<div id="app"> | |
<!-- 将单选按钮绑定到同一个 picked --> | |
<input type="radio" id="one" value="One" v-model="picked" /> | |
<label for="one">One</label> | |
<br /> | |
<input type="radio" id="two" value="Two" v-model="picked" /> | |
<label for="two">Two</label> | |
<br /> | |
<span>Picked: {\{ picked }}</span> | |
</div> | |
<script> | |
var vue = new Vue({ | |
el: "#app", | |
data() { | |
return { | |
picked: "", | |
}; | |
}, | |
}); | |
</script> | |
</body> |
在单个复选框时没有设置 value 属性,在多个复选框存在时,每个复选框都要设置 value 属性。
<div id="app"> | |
<input type="checkbox" id="checkbox" v-model="checked" /> | |
<label for="checkbox">{\{ checked }}</label> | |
</div> | |
<script> | |
// 绑定布尔值 | |
var vue = new Vue({ | |
el: "#app", | |
data() { | |
return { | |
checked: false, | |
}; | |
}, | |
}); | |
</script> |
<div id="app"> | |
<input type="checkbox" id="syl1" value="syl1" v-model="checkedNames" /> | |
<label for="syl1">syl1</label> | |
<input type="checkbox" id="syl2" value="syl2" v-model="checkedNames" /> | |
<label for="syl2">syl2</label> | |
<input type="checkbox" id="syl3" value="syl3" v-model="checkedNames" /> | |
<label for="syl3">syl3</label> | |
<br /> | |
<span>Checked names: {\{ checkedNames }}</span> | |
</div> | |
<script> | |
var vue = new Vue({ | |
el: "#app", | |
data() { | |
return { | |
checkedNames: [], | |
}; | |
}, | |
}); | |
</script> |
当 option 没有设置 value 属性时,默认其值为标签内的文本。
<div id="app"> | |
<!-- select 标签是绑定 数据项 selected --> | |
<select v-model="selected"> | |
<option disabled value="">请选择</option> | |
<option>A</option> | |
<option>B</option> | |
<option>C</option> | |
</select> | |
<span>Selected: {\{ selected }}</span> | |
</div> | |
<script> | |
var vue = new Vue({ | |
el: "#app", | |
data() { | |
return { | |
selected: "", | |
}; | |
}, | |
}); | |
</script> |
判断变量类型用 typeof(变量名)
<!DOCTYPE html> | |
<html lang="en"> | |
<head> | |
<meta charset="UTF-8" /> | |
<meta name="viewport" content="width=device-width, initial-scale=1.0" /> | |
<meta http-equiv="X-UA-Compatible" content="ie=edge" /> | |
<title>vue</title> | |
<script src="vue.min.js"></script> | |
</head> | |
<body> | |
<div id="app"> | |
<p>没有使用 .number 修饰符</p> | |
<input v-model="number1" type="number" /> | |
<!-- 使用 typeof 对值类型检测 --> | |
<p>{\{typeof(number1)}}</p> | |
<p>使用 .number 修饰符</p> | |
<input v-model.number="number2" type="number" /> | |
<!-- 使用 typeof 对值类型检测 --> | |
<p>{\{typeof(number2)}}</p> | |
</div> | |
<script> | |
var vue = new Vue({ | |
el: "#app", | |
data: { | |
number1: "", | |
number2: "", | |
}, | |
}); | |
</script> | |
</body> | |
</html> |
上面的代码中当向第二个输入框输入数字后,输出的 number2 的类型是 number,但是在 data 中的类型是字符串
同时由于定义为 number 类型的输入框,是无法输入非数字类型的其他字符的。
# 局部组件和全局组件
<!DOCTYPE html> | |
<html lang="en"> | |
<head> | |
<meta charset="UTF-8" /> | |
<meta name="viewport" content="width=device-width, initial-scale=1.0" /> | |
<meta http-equiv="X-UA-Compatible" content="ie=edge" /> | |
<title>vue</title> | |
<script src="vue.min.js"></script> | |
</head> | |
<body> | |
<div id="app"> | |
<button-counter></button-counter> | |
<button-counter></button-counter> | |
<button-counter></button-counter> | |
<child-counter></child-counter> | |
</div> | |
<script> | |
// 注册一个全局可复用组件 | |
Vue.component("button-counter", { | |
//data 必须是一个函数不然会影响其他组件 | |
data() { | |
return { | |
counter: 0, | |
}; | |
}, | |
template: '<button @click="counter++">{\{counter}}</button>', | |
}); | |
var childComponent = { | |
data() { | |
return { | |
counter: 0, | |
}; | |
}, | |
template: '<button @click="counter++">{\{counter}}</button>', | |
}; | |
var app = new Vue({ | |
el: "#app", | |
// 注意下面要加 s,component 是复数形式 | |
components: { | |
"child-counter": childComponent, | |
} | |
}); | |
</script> | |
</body> | |
</html> |
# 嗯嗯
自定义的事件并不是新的触发方式,而是,本来的原生事件(如 click 等)触发了自定义事件,然后自定义事件进一步引发事件句柄。
在下面的代码中仅仅传入了一个参数,多个参数的时候怎么写呢?
<!DOCTYPE html> | |
<html lang="en"> | |
<head> | |
<meta charset="UTF-8" /> | |
<meta name="viewport" content="width=device-width, initial-scale=1.0" /> | |
<meta http-equiv="X-UA-Compatible" content="ie=edge" /> | |
<title>vue</title> | |
<script src="vue.min.js"></script> | |
</head> | |
<body> | |
<div id="app"> | |
<child-component v-on:send-msg="getMsg"></child-component> | |
</div> | |
<script> | |
// 定义一个子组件,template 绑定 click 事件 | |
// 当 click 事件触发就使用 emit 自定义一个事件 send-msg,传入参数 “我是子组件请求与你通信” | |
// $emit ('send-msg',' 我是子组件请求与你通信 ') | |
// 子组件标签上绑定自定义事件 send-msg,并绑定上父级的方法 getMsg,即可完成了子父组件通信 | |
// <child-component v-on:send-msg="getMsg"></child-component> | |
Vue.component("child-component", { | |
template: ` | |
<button v-on:click="$emit('send-msg','我是子组件请求与你通信')"> | |
Click me | |
</button> | |
`, | |
}); | |
var app = new Vue({ | |
el: "#app", | |
methods: { | |
getMsg: function (msg) { | |
// 弹出子组件传递的信息 | |
alert(msg); | |
}, | |
}, | |
}); | |
</script> | |
</body> | |
</html> |
created() { | |
fetch('url') | |
.then(function(response) { | |
console.log(response) | |
}) | |
} |
上面的 fetch 未完全理解。
前端路由的概念及作用未完全理解。
wget https://labfile.oss.aliyuncs.com/courses/10532/first-vuex.zip && unzip first-vuex.zip && rm first-vuex.zip
cd first-vuex
npm install
npm install vuex@3.6.2
# prototype
为什么说构造函数有 prototype 属性,函数可以有属性的吗?
// 构造函数 | |
function Person() { | |
this.sex = "男"; | |
this.age = 18; | |
} | |
Person.prototype = { | |
a: 1, | |
b: 2, | |
} | |
let zhangsan = new Person(); | |
console.log(zhangsan.a) // 1 | |
console.log(zhangsan.b) // 2 | |
// 属性的寻找,当这个实例中没有这个属性,就到 proto 中寻找,(原型链) | |
console.log(zhangsan.__proto__) // {a:1, b:2} | |
console.log(Person.prototype) // {a:1, b:2} |
构造函数的原型属性有点类似于类的静态函数啥的,但是这里是函数呀,不是类。
另外,js 中好像是通过构造函数来构造出一个对象,而不是通过先定义类,再实例化类来构造对象。
另外,js 中都是对象,没有类似 cpp 那种使用 ->
指针的。
当在一个对象的原型上添加方法的时候,并且涉及到 this 的实例属性,怎么判断这个属性是否存在以及它的类型呢?而且,这种没有代码提示的吧。
let a = { | |
f1() { | |
console.log("a"); | |
} | |
} | |
let a = { | |
f1: function() { | |
console.log("a"); | |
} | |
} | |
// 上面是在对象中定义方法的两种方式 |
let a = 2, b = 3; | |
let obj = { a, b }; | |
console.log(obj); //{"a": 2,"b": 3} |
# Object 中的各种方法
- Object.getPrototypeOf
- Object.create
- Object.assign:
https://juejin.cn/post/6844903984675684366
- Object.keys
jq 的 get 和 post 请求 data 都是一个对象
<!DOCTYPE html> | |
<html lang="en"> | |
<head> | |
<meta charset="UTF-8" /> | |
<meta name="viewport" content="width=device-width, initial-scale=1.0" /> | |
<title>get 和 post 的对比</title> | |
<script src="jquery-3.6.0.min.js"></script> | |
<script> | |
$(function () { | |
$.get( | |
"https://jsonplaceholder.typicode.com/users", | |
{ | |
id: "2", | |
name: "Cici", | |
}, | |
function (data, success) { | |
$("div").text("请求状态:" + success); | |
} | |
); | |
$.post( | |
"https://jsonplaceholder.typicode.com/users", | |
{ | |
id: "3", | |
name: "Lee", | |
}, | |
function (data, success) { | |
$("p").text("请求状态:" + success); | |
} | |
); | |
}); | |
</script> | |
</head> | |
<body> | |
<div></div> | |
<p></p> | |
</body> | |
</html> |
# 寻找小狼人
# 涉及知识点
- prototype
- this
- 数组操作(遍历,元素的增删等)
# 解题
let cardList = [ | |
{ | |
id: 1, | |
category: "werewolf", | |
name: "小狼人", | |
}, | |
{ | |
id: 2, | |
category: "werewolf", | |
name: "小狼人", | |
}, | |
{ | |
id: 3, | |
category: "hunter", | |
name: "猎人", | |
}, | |
{ | |
id: 4, | |
category: "poor", | |
name: "平民", | |
}, | |
{ | |
id: 5, | |
category: "witch", | |
name: "女巫", | |
}, | |
{ | |
id: 6, | |
category: "prophet", | |
name: "预言家", | |
}, | |
{ | |
id: 7, | |
category: "poor", | |
name: "平民", | |
}, | |
{ | |
id: 8, | |
category: "werewolf", | |
name: "黑狼王", | |
}, | |
{ | |
id: 9, | |
category: "poor", | |
name: "平民", | |
}, | |
]; |
在 Array 类的原型中定义了一个方法,然后 Array 类的实例就可以调用这个方法,在调用方法的时候,将一个函数作为参数传入进去,那么我们就可以在方法中调用传入的这个参数。
注意箭头函数和无类型变量的识别。
# 蓝桥知识网
css 属性:
box-sizing:border-box https://www.w3school.com.cn/cssref/pr_box-sizing.asp
background-color 和 color 的区别:
https://blog.csdn.net/drawlessonsfrom/article/details/115256107
为了方便操作设置为 box-sizing:border-box
# 函数闭包
function fun() { | |
var count = 1; | |
return function () { | |
count++; // 自由变量 | |
console.log(count); | |
} | |
} | |
var fun2 = fun(); //fun2 => 返回的匿名函数 | |
fun2(); // 函数在全局作用域调用,创建的时候是在 fun 作用域中创建 | |
var fun3 = fun(); // 这里是另外新建了一个闭包环境 | |
fun3(); //fun2 和 fun3 的 count 是不同的 count,所以这里打印出来的都是 2 | |
fun2(); // 3 说明环境还在 |
let func = () => { | |
console.log("hello world"); | |
}; | |
let temp = null; | |
console.log('前this is temp ',temp); | |
temp = setTimeout(func, 500); | |
clearTimeout(temp); // 这里之后 temp 并不会变成 null,还是之前的值 | |
console.log('this is temp ',temp); | |
console.log('this is temp ',temp); | |
console.log('this is temp ',temp); | |
setTimeout(()=>{ | |
console.log('this is temp ',temp); | |
}, 1000); |
let obj = { | |
1: 'a', | |
'2': 'b', | |
k: 'c' | |
}; | |
console.log(obj['1'], obj.k, obj['k']); | |
//obj.1 报错 |
ES6 新特性 扩展运算符 (...) 详解 https://juejin.cn/post/6975360241508712479
js 函数的 apply:
理解理解下面的对对象使用扩展运算符并传入函数的 rest 参数中。想想就知道酱紫是乱套了
// let func = (...args) => { | |
// console.log(args); | |
// } | |
let func = (args) => { | |
console.log(args); | |
} | |
let obj = { | |
a: 1, | |
b: 2 | |
} | |
// func(...obj); | |
console.log({...obj}); |
# 迭代器
# 对象的遍历
let obj = { | |
a: 1, | |
b: 2, | |
c: 3 | |
} | |
Object.keys(obj).forEach((value) => { | |
console.log(obj[value]); | |
}) |
let obj = { | |
a: 1, | |
c: 3, | |
b: 2, | |
} | |
// 不会自动有序 | |
console.log(obj); // {a: 1, c: 3, b: 2} | |
Object.keys(obj).forEach((value) => { | |
console.log(obj[value]); // 1 3 2 | |
}) |
# 数组的遍历
let arr = [1, 2, 3]; | |
for(let item in arr) { | |
} |
# new Function () 创建函数
https://www.cnblogs.com/xiaokeai0110/p/10029024.html
# 正则表达式
# match
match 是字符串具有的方法,方法的参数是正则表达式
let text = "Is this all there is?"; | |
let pattern = /Is/ig; | |
let result = text.match(pattern); | |
console.log(result); //['Is', 'is', 'is'] | |
console.log(result instanceof Array); // true |
match 方法返回的是一个数组,装着所有匹配的项(即使匹配到 1 个也是返回数组),但是如果没有匹配到返回的就是 null 了。
当使用分组的时候,match 的返回结果如下,数组的下标 0 处是正则的全部匹配,1 和 2 处是分组内的内容
当使用多个命名组的时候,组的名字是不能重复的
String.matchAll () 尚未运行起来。
const match = 'web-doc-a'.match(/-(?<aaa>\w)\w+-(?<bbb>\w)/); | |
console.log(match); |
# exec
let text = "The best things in life are free"; | |
let result = /e/.exec(text); | |
console.log(result.length); // 1 | |
console.log(result[0]); //1 | |
console.log(result[0].index) // undefined | |
console.log(result.index); | |
console.log(result); // | |
console.log(result instanceof Array); // | |
let array = [1, 2, 3]; | |
console.log(array); |
上面代码的输出结果如下:
exec 方法是正则表达式对象具有的,如果可以匹配到,返回的结果是具有一个元素的数组,但是这个数组会有很多附加属性,如 index、input、groups 等。如果没有匹配到,结果返回 null。
# grid 布局
.item1 { | |
grid-column-start: 1; | |
grid-column-end: 4; | |
grid-row-start:1; | |
grid-row-end: 4; | |
} |
上面这样写只有前面两个属性起作用。
CSS Grid 网格布局教程 - 阮一峰的网络日志 (ruanyifeng.com)
CSS 网格布局 | 菜鸟教程 (runoob.com)
justify-content 、justify-self、align-items、align-self
# 数组的 map 方法
# css
text-transform: uppercase; / 大写转换 /
# parseInt
parseInt("223s")
返回 223,当遇到非数字字符时停止解析。
# 最后
tar -cvf 618 活动.tar ./
为什么只能在原型中定义方法呢?或许只是在外面等于的时候才这样,直接定义在里面的时候不一定
jq 选择 children 的时候,如果有多个 children 和单独一个 children 的情况下呢?