阿八博客
  • 100000+

    文章

  • 23

    评论

  • 20

    友链

  • 最近新加了很多技术文章,大家多来逛逛吧~~~~
  • 喜欢这个网站的朋友可以加一下QQ群,我们一起交流技术。

React实战-为什么需要组件化(1)

欢迎来到阿八个人博客网站。本 阿八个人博客 网站提供最新的站长新闻,各种互联网资讯。 喜欢本站的朋友可以收藏本站,或者加QQ:我们大家一起来交流技术! URL链接:https://www.abboke.com/jsh/2019/1010/116720.html

为什么需要组件化?

1.web的发展因为HTML CSS Javascript分工造成了协作,所以需要标准和接口,所以需要组件化

2.追求效率,重复使用

怎么实现复用?

我们总不能把同事的代码拷贝过来,拷贝css,拷贝js,最后改里面文字
这样也忒费劲了,而且不可持续化
接下来我们就说下怎么组件化
我们先不用react
先说原生

为什么说原生

1.简单

2.我们能够从原生js中真的会用react组件化,不懂原理只会react组件化语法,遇到实际项目也棘手

1.我们遇到这么一个实际问题

你同事写了一个星星评分,你想复用,原始代码如下,怎么办?我们这里简化一下,说五个星星部分

<!DOCTYPE html><html lang="en"><head>    <meta charset="UTF-8">    <title>星星评分</title>    <style type="text/css">        .starbox span {            width: 27px;            height: 28px;            display: inline-block;            background: url(images/star.gif) no-repeat 0px 0px;            cursor: pointer;            float: left;        }        .starbox strong {            float: left;            padding-top: 6px;            padding-left: 10px;        }        .starbox .on {            background-position: 0px -29px;        }    </style>    <script>        window.onload = function(){            var aStar = document.querySelectorAll('.starbox span');            var oS = document.querySelector('.starbox .score');            for(let i =0;i<aStar.length;i++){                aStar[i].onclick = function(){                    for(let j =0;j<aStar.length;j++){                        aStar[j].className = '';                    }                    for(let j =0;j<=i;j++){                        aStar[j].className = 'on';                     }                    oS.innerHTML = (i+1)+'分';                };            }        };    </script></head><body>    <div class='starbox'>        <span data-index="0"></span>        <span data-index="1"></span>        <span data-index="2"></span>        <span data-index="3"></span>        <span data-index="4"></span>        <strong class='score'>0分</strong>    </div></body></html>

2.组件化结构

我们先让这个组件能够显示我们的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>Document</title>    <style>        .starbox span {            width: 27px;            height: 28px;            display: inline-block;            background: url(images/star.gif) no-repeat 0px 0px;            cursor: pointer;            float: left;        }        .starbox strong {            float: left;            padding-top: 6px;            padding-left: 10px;        }        .starbox .on {            background-position: 0px -29px;        }    </style>    <script>        window.onload = function () {            //2.但是没有,所以我们搞一个 Class            class RatingStar {                //  render专门用来决定显示什么东西的                render() {                    return `                        <div class='starbox'>                            <span data-index="0"></span>                            <span data-index="1"></span>                            <span data-index="2"></span>                            <span data-index="3"></span>                            <span data-index="4"></span>                            <strong class='score'>0分</strong>                        </div>                    `;                }            }            var oBox = document.getElementById('box');            //1.假设有一个Class RatingStar  它就是一个组件,包含所有组件信息            var oStar = new RatingStar();            oBox.innerHTML = oStar.render();        };    </script></head><body>    <div id="box">    </div></body></html>

我们先按照注释思路走,但是有个问题:事件不好用

return `    <div class='starbox'>        <span data-index="0"></span>        <span data-index="1"></span>        <span data-index="2"></span>        <span data-index="3"></span>        <span data-index="4"></span>        <strong class='score'>0分</strong>    </div>`;

因为上面是return的字符串不好加事件,我们直接在外面包一层div,再添加事件

3.添加事件

外面包一个div

//创建一个元素const createDOMFromString = (domString) => {  const div = document.createElement('div')  div.innerHTML = domString  return div}

我们现在到原来的例子里面加事件

<!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>Document</title>    <style>        .starbox span {            width: 27px;            height: 28px;            display: inline-block;            background: url(images/star.gif) no-repeat 0px 0px;            cursor: pointer;            float: left;        }        .starbox strong {            float: left;            padding-top: 6px;            padding-left: 10px;        }        .starbox .on {            background-position: 0px -29px;        }    </style>    <script>        window.onload = function () {            const createDOMFromString = (domString) => {                const div = document.createElement('div')                div.innerHTML = domString                return div;            }            class RatingStar {                //  render专门用来决定显示什么东西的                render() {                    this.el = createDOMFromString(`                        <div class='starbox'>                            <span data-index="0"></span>                            <span data-index="1"></span>                            <span data-index="2"></span>                            <span data-index="3"></span>                            <span data-index="4"></span>                            <strong class='score'>0分</strong>                        </div>                    `);                    this.el.addEventListener('click', ()=>{                        console.log(this);                    }, false);                    return this.el;                }            }            var oBox = document.getElementById('box');            var oStar = new RatingStar();            oBox.appendChild(oStar.render());        };    </script></head><body>    <div id="box">    </div></body></html>

重点是加事件

this.el.addEventListener('click', ()=>{     console.log(this);}, false)

4.添加数据与逻辑

<!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>Document</title>    <style>        .starbox span {            float: left;            width: 27px;            height: 28px;            display: inline-block;            background: url(images/star.gif) no-repeat 0px 0px;            cursor: pointer;        }        .starbox strong {            float: left;            padding-top: 6px;            padding-left: 10px;        }        .starbox .on {            background-position: 0px -29px;        }    </style>    <script>        window.onload = function () {            const createDOMFromString = (domString) => {                const div = document.createElement('div')                div.innerHTML = domString                return div;            }            class RatingStar {                constructor() {                    this.state = { score: 0 }                }                changeScore(ev) {                    const aStar = document.querySelectorAll('.starbox span');                    const oS = document.querySelector('.starbox .score');                    this.state.score = Number(ev.target.dataset.index) + 1;                    for (let i = 0; i < aStar.length; i++) {                        aStar[i].className = '';                    }                    for (let i = 0; i <= Number(ev.target.dataset.index); i++) {                        aStar[i].className = 'on';                    }                    oS.innerHTML = this.state.score + '分';                }                //  render专门用来决定显示什么东西的                render() {                    this.el = createDOMFromString(`                        <div class='starbox'>                            <span data-index="0"></span>                            <span data-index="1"></span>                            <span data-index="2"></span>                            <span data-index="3"></span>                            <span data-index="4"></span>                            <strong class='score'>0分</strong>                        </div>                    `);                    this.el.addEventListener('click', this.changeScore.bind(this), false);                    return this.el;                }            }            var oBox = document.getElementById('box');            var oStar = new RatingStar();            oBox.appendChild(oStar.render());        };    </script></head><body>    <div id="box">    </div></body></html>

注意,请不要陷入细节:

this.el.addEventListener('click', this.changeScore.bind(this), false);

先注意明白这里调用了changeScore就行了,先别考虑什么矫正this,或者事件对象什么的,我们先了解react原理

这里修改DOM方法很暴力,react是用virtualDOM 和diff算法优化了这块, 现在我们实现了组件化

总结:

1.我们从实际问题出发,用class封装了一个初始的类

2.添加事件;

3.我们在事件里面加了具体逻辑,虽然数据和DOM操作一起写,但是完成了组件化

下一篇我们就组件化与复用进行优化

相关文章

暂住......别动,不想说点什么吗?
  • 全部评论(0
    还没有评论,快来抢沙发吧!