第一题:动态tab栏目
这题考察的是css中的粘性定位
第二题:地球漫游
这题主要考察的是css动画的复合属性
第三题:迷惑的this
这题主要是考察this指向的问题,因为箭头函数指向的是外部作用域的this,然后将this.handleInput事件绑定给this.inputEl,此时this.inputEl的input事件处理函数则为this.handleInput这个函数,由于事件处理函数中的内部作用域的this是指向被绑定的元素的,所以我们要使用bind返回一个新的修正过后的函数
第四题:魔法失灵了
这题也可以用toref来做,其实主要是原题中通过解构赋值让value丧失了响应式,重新恢复响应式即可
第五题:燃烧你的卡路里
第一问
js
这里要注意题目中的这个axios.get要删掉一个.才能获取到数据,这是原题出错了
第二问
这里主要考察的是排序和数组的运用
第六题:司龄统计
第一问
第二问
第七题:不翼而飞的余额
第一问
当时忘记createWebHashHistory怎么写了,就直接去VueRouter的包里面ctrl+f找的
第二问和第三问
setup(){
const depositAmount=Vue.ref()//输入框中的的值->存款金额
const store=useMoneyStore()//引入store
//TODO:待补充代码,完善点击存款按钮事件
function deposit(){
store.balance+=depositAmount.value
}
return{
deposit,
store,
depositAmount
}
}
//然后在模板中绑定store.balance即可
第八题:个性化推荐
这题一开始点击完成是去不到customeized页面的
先用node跑起来服务:node ./js/index.js,然后我们进入到8080端口的页面,把页面地址复制粘贴到form表达的action里:
然后再重启服务,这样才能正确监听到customeized页面
这里如果修改了index.js,需要重新跑node服务
第一问
第二问
这个时候如果要提交,是需要回到index.html把form的action重新改回/customized才能通过
第九题:贪吃蛇
// 移动蛇的头部
nextStep() {
// TODO:待补充代码
//这里利用策略模式,创建奔跑引擎
const runEngine = {
right(){
//先创建一个变量保存当前头部位置,需要深拷贝防止引用问题
let lastPos = JSON.parse(JSON.stringify(this.snakeBody[0]))
//头部运动
this.snakeBody[0].left+=this.size
//身体运动
for(let i = 1;i<this.snakeBody.length;i++){
//先创建一个临时变量保存身体运动之后空出来的位置
let _lastPos = JSON.parse(JSON.stringify(this.snakeBody[i]))
//运动身体到上一个身体的位置
this.snakeBody[i] = lastPos
//更新空出来的上一个位置,继续给下一个身体运动
lastPos = _lastPos
}
},
//下面的同理
left(){
let lastPos = JSON.parse(JSON.stringify(this.snakeBody[0]))
this.snakeBody[0].left-=this.size
for(let i = 1;i<this.snakeBody.length;i++){
let _lastPos = JSON.parse(JSON.stringify(this.snakeBody[i]))
this.snakeBody[i] = lastPos
lastPos = _lastPos
}
},
up(){
let lastPos = JSON.parse(JSON.stringify(this.snakeBody[0]))
this.snakeBody[0].top-=this.size
for(let i = 1;i<this.snakeBody.length;i++){
let _lastPos = JSON.parse(JSON.stringify(this.snakeBody[i]))
this.snakeBody[i] = lastPos
lastPos = _lastPos
}
},
down(){
let lastPos = JSON.parse(JSON.stringify(this.snakeBody[0]))
this.snakeBody[0].top+=this.size
for(let i = 1;i<this.snakeBody.length;i++){
let _lastPos = JSON.parse(JSON.stringify(this.snakeBody[i]))
this.snakeBody[i] = lastPos
lastPos = _lastPos
}
}
}
//执行引擎,注意this指向问题
runEngine[this.direction].call(this)
}
第十题:自定义表单验证
第一问
第二问
这里忘记当时具体是怎么写的了,当时不会写这么复杂的邮箱正则,写了很多if判断了多种情况
第三问
const validateForm = () => {
return new Promise((resolve, reject) => {
errors.value = {}; // 清空之前的错误信息
// TODO:目标 3 编写通用的表单验证规则,并将错误信息放置到 errors 对象中
//这里分两个部分,一个是nickname的验证,另外一个是email的验证,这里利用错误捕获的机制来完成
//nickname part
try{
props.rules.nickname.map(item=>{
item?.validator(null,props.formData.nickname,err=>{
if(err){
throw "nickname|"+err.message
}
})
})
}catch(e){
const parseErr = e.split('|'),
errKey = parseErr[0],
errValue = parseErr[1]
errors.value[errKey] = errValue
}
//email part
try{
props.rules.email.map(item=>{
if(item?.required){
if(props.formData.email == '')throw "email|"+item.message
}
if(item?.type){
if(!validateByType(item.type,props.formData.email))throw "email|"+item.message
if(props.formData.email.length < 8)throw "email|"+item.message
if(props.formData.email.length > 20)throw "email|"+item.message
}
})
}catch(e){
const parseErr = e.split('|'),
errKey = parseErr[0],
errValue = parseErr[1]
errors.value[errKey] = errValue
}
// TODO:END
if (hasErrors.value) {
resolve(false); // 存在错误,验证失败
} else {
resolve(true); // 不存在错误,验证通过
}
// 触发 "valid" 事件,并传递错误信息对象
emit("valid", errors.value);
});
};