咕咕咕,咕咕咕

刚有些无聊正打算这今天的每日一摸该写些什么,然后突然想起了前段时间学长在前端组的群里发了一个链接,http://scriptoj.mangojuice.top/点开看了一下,注册了一个账号就开始给我出题了。


见面礼

完成 extname 函数,它会接受一个文件名作为参数,你需要返回它的扩展名。

例如,输入 emoji.png,返回 .png

一开始我寻思着这个比较简单,应该可以写的简短一点

1
const extname = (filename) => `.${filename.split('.').pop()}`

然后…代码写的有点丑,并且:

image-20200201195642863

好吧,考虑不周

这里需要考虑的情况好像有几个

xxxxxx.xxx.xxx。遂:

1
2
3
4
5
6
7
8
9
10
11
12
13
const extname = (filename) => {
let filenameArr = filename.split('.');
if(filenameArr.length === 1){
//xxx类型
return '';
}else{
if(filename[0] === '.'){
return '';
}else{
return '.' + filenameArr.pop();
}
}
}

OK,Accepted。不过如果遇到.xxx.xxx这样的文件扩展名到底是什么呢(x


然后。。就给我跳出了好多道题目啊。。。怎么说呢,很爽!

但是题目好像也不是很多的样子啊。。。那就从头做到尾吧


#0

在 id 为 contentdiv 中只显示 Hello World 字样。(注意不要有多余空白字符)


1
<div id="content">Hello World</div>

唔。。是真的Hello World了(x

#1

在页面上增加一个 idroot元素。然后请你完成一个 `renderContent` 函数,这个函数会把传入的任意字符串都包装到一个 元素中并且渲染到页面上。例如:

1
renderContent('Hello World')

页面上就有相应的内容:

1
2
3
<div id='root'>
<h1>Hello World</h1>
</div>

只能通过 React.js 来实现。


完蛋,React.js我没学过呀 呜呜呜。那咋办呢,只好现学啦(x

大概了解了一下,在React下好像用了一种叫jsx的模板,可以写出这样子的代码:

1
const h1 = <h1>Hello World</h1>;

有一种html和js混在一起了的感觉,然后这种写法应该是等价于:

1
React.createElement("h1", null, "Hello World");

的,有些好奇,那么嵌套的标签会怎么解释呢。试试:

1
2
3
<div id="root">
<h1>Hello World</h1>
</div>

结果是:

1
2
3
React.createElement("div", {
id: "root"
}, React.createElement("h1", null, "Hello World"));

看起来第二个参数传递的是元素的属性,应该是通过对象以键值对的形式传递进去。

然后观察了一下,似乎可以通过这样的方式去实现

1
2
3
4
ReactDOM.render(
<h1>Hello World</h1>,
document.getElementById('root')
);

那么问题又来了,我应该怎么注入变量到里面呢,然后又回到了jsx的特性,通过大括号{},就是,要写成这样

1
2
3
4
ReactDOM.render(
<h1>{ content }</h1>,
document.getElementById('root')
);

所以猜测应该可以这么写:

1
2
3
<div id='root'>

</div>
1
2
3
4
5
6
function renderContent (content) {
ReactDOM.render(
<h1>{content}</h1>,
document.getElementById('root')
);
}

ok,Accepted.

#2

使用 React.js 构建一个未读消息组件 Notification

通过 getNotificationsCount() 来获取未读消息的数量 ,如果有未读消息 N 条,而且 N > 0,那么 Notification 组件渲染显示:
a

1
<span>有(N)条未读消息</span>

否则显示:

1
<span>没有未读消息</span>

(你只需要完成组件部分,不需要调用 ReactDOM

给定了需要的代码的一部分:

1
2
3
4
5
6
7
// 函数 getNotificationsCount 已经可以直接调用

class Notification extends Component {
render () {
// TODO
}
}

了解了一下,extends 的这个Component好像就是React的组件,然后他这个render()方法定义或者说声明了如何渲染这个组件。

既然如此,他如果希望我返回一个<span>有(N)条未读消息</span>或者<span>没有未读消息</span>的样子其实就很简单了,我只需要在返回之前无所不用其极获取到需要的数据,然后给他注入到组件里边,然后return出去、


故猜测应该这么写:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
class Notification extends Component {
render () {
let count = getNotificationsCount();
if(count === 0){
return(
<span>没有未读消息</span>
);
}else{
return(
<span>有({count})条未读消息</span>
)
}
}
}

ok,Accepted.

#3

用 JSX 完成两个变量的定义:

第一个变量 title 为一个具有类名为 title<h1> 元素,其内容为 ScriptOJ

第二个变量 page 为一个具有类名为 content<div> 元素,将之前定义的 title 变量插入其中作为它的内容。


好像比较简单,按照#1的样子,jsx定义变量其实就是直接写上去就完事了,然后模板会帮我把他翻译成React.createElement,所以:

1
2
const title = <h1 class="title">ScriptOJ</h1>;
const page = <div class="content">{title}</div>;

然而提交之后说我wa了,原因是title 中的 'h1.title' 数量应该有 1 个,但你定义的 title 中有 0 个.

嗯?? 看了一眼讨论区,他这个类名,应该是className。

我好像有哪里没弄明白。。然后看了一会儿菜鸟教程,在里面看到了。。。

注意,在添加属性时, class 属性需要写成 className ,for 属性需要写成 htmlFor ,这是因为 class 和 for 是 JavaScript 的保留字。

好吧我知道了,那么答案就是

1
2
const title = <h1 className="title">ScriptOJ</h1>;
const page = <div className="content">{title}</div>;

ok,Accepted.

#4

一个房子里面有一个房间和一个洗手间,房间里面有一个人和两条狗。

请你完成组件:HouseRoomBathroomManDog,它们的最外层都用 div 标签包裹起来,类名分别为:houseroombathroommandog

组件的实现应该具有上述的嵌套关系。

已经给了的代码有

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
// Component 已经可以直接使用

class House extends Component {
// TODO
}

class Room extends Component {
// TODO
}

class Bathroom extends Component {
// TODO
}

class Man extends Component {
// TODO
}

class Dog extends Component {
// TODO
}

看起来,也不是很复杂,就是很简单的嵌套,在别的组件里面也是可以直接调用定义的别的组件的。所以直接写:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
// Component 已经可以直接使用

class House extends Component {
render(){
return (
<div className="house">
<Room />
<Bathroom />
</div>
)
}
}

class Room extends Component {
render(){
return (
<div className="room">
<Man />
<Dog />
<Dog />
</div>
)
}
}

class Bathroom extends Component {
render(){
return <div className="bathroom"></div>
}
}
class Man extends Component {
render(){
return <div className="man"></div>
}
}
class Dog extends Component {
render(){
return <div className="dog"></div>
}
}

ok. Accepted


React挺有意思的,感觉跟vue有点像,但是他们定义组件的方式感觉又有些不同,也不能说不同,唔。。感觉,都还行?感觉学起来比vue轻松那么一丢丢,可能是错觉吧 2333

今天先到这里,明天继续怼,如果有空并且记得的话 嗯。