原生JS实现组件

Vanilla JS Realize Component

Posted by yellowDog on 2018-05-08

写着写着感觉挺像小程序里的状态管理…但是比这更方便,不用 DOM 啦…

原生实现点赞和取消功能

1
2
3
4
5
6
<div class='wrapper'>
<button class='like-btn'>
<span class='like-text'>点赞</span>
<span> </span>
</button>
</div>
1
2
3
4
5
6
7
8
9
10
11
const button = document.querySelector(`.like-btn`);
const buttonText = button.querySelector(`.like-text`);
let isLike = false;
button.addEventListener(
`click`,
() => {
isLike = !isLike;
isLike ? (buttonText.innerHTML = `取消`) : (buttonText.innerHTML = `点赞`);
},
false
);

实现复用性(class 和 export)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
class likeButton {
render() {
return `
<button class='like-btn'>
<span class='like-text'>赞</span>
<span> </span>
</button>
`;
}
}

const wrapper = document.querySelector(`.wrapper`);
const btn1 = new likeButton();
wrapper.innerHTML = btn1.render();

const btn2 = new likeButton();
wrapper.innerHTML += btn2.render();

生成 DOM 和添加事件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
const createDOMFromString = domString => {
const div = document.createElement("div");
div.innerHTML = domString;
return div;
};
class likeButton {
render() {
this.el = createDOMFromString(`
<button class='like-btn'>
<span class='like-text'>点赞</span>
<span> </span>
</button>
`);
this.el.addEventListener(`click`, () => console.log(``));
return this.el;
}
}

DOM API replace innerHTML

1
2
3
4
5
6
const wrapper = document.querySelector(`.wrapper`);

const btn1 = new likeButton();
wrapper.appendChild(btn1.render());
const btn2 = new likeButton();
wrapper.appendChild(btn2.render());

add clickEvent

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
class likeButton {
constructor() {
this.state = {
isLiked: false
};
}
changeText() {
const likeText = this.el.querySelector(`.like-text`);
this.state.isLiked = !this.state.isLiked;
if (this.data.isLiked) {
likeText.innerHTML = `取消`;
}
}
render() {
this.el = createDomString(`
<button class='like-btn'>
<span class='like-text'>点赞</span>
<span> </span>
</button>
`);
this.el.addEventListener(`click`, this.changeText.bind(this), false);
}
}

状态管理代替 DOM 操作(越来越像 data 和 view 绑定了)

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
class likeButton {
constructor(){
this.state = {
isLiked: false
}
}
setData(state){
this.state = state;
this.el = this.render();
}
changeText(){
this.setData({
isLiked: !this.state.isLiked;
});
}
render(){
this.el = createDomString(`
<button class='like-btn'>
<span class='like-text'>${this.state.isLiked ? "取消" : "点赞"}</span>
<span> </span>
</button>
`);
this.el.addEventListener(`click`,this.changeText.bind(this),false)
}
}