<p><code></p> <p>看了<a href="http://www.js-code.com/tag/vue" title="Vue" target="_blank">Vue</a>的文档,写得很简洁,但是并不简单。在自己学习的过程中踩过不少的坑,学习的时候把官网的例子从头到尾做了一遍,记录在github中<a href="https://github.com/WYseven/vue2-basic-demo/tree/master/vue-demo" rel="nofollow noreferrer" target="_blank">https://github.com/WYseven/vue2-basic-demo/tree/master/vue-demo</a>,学习中也有自己的心得体会,记录下来分享,希望对你的理解有所帮助。</p> <p>组件是vue中很重要,这部分也是最难理解的,先聊一聊vue中的组件。</p> <h2 id="articleHeader0">组件是什么</h2> <blockquote> <p>在vue中组件是一个自定义元素,vue的编译器为它添加特殊功能;组件也可以是原生的html元素,使用特殊的is来扩展。</p> </blockquote> <p>看完之后,比较懵吧?咱们慢慢解开组件的神秘面纱,先从一段布局开始说起。</p> <p>试想在布局中的一个场景,自定义一个下拉框,需要先定义一个基本的结构:</p> <div class="widget-codetool" style="display:none;"> <div class="widget-codetool--inner"> <span class="selectCode code-tool" data-toggle="tooltip" data-placement="top" title="" data-original-title="全选"></span><br /> <span type="button" class="copyCode code-tool" data-toggle="tooltip" data-placement="top" data-clipboard-text=" <div class=&quot;select&quot;> <p>请选择:</p> <ul> <li>北京</li> <li>上海</li> <li>杭州</li> </ul> </div> <p><!--使用时通常是复制上面结构改数据--></p> <div class=&quot;select&quot;> <p>请选择:</p> <ul> <li>博士</li> <li>研究生</li> <li>本科</li> </ul> </div> <p>" title="" data-original-title="复制"></span> </div> </p></div> <pre class="xml hljs"><code class="html"><span class="hljs-tag">&lt;<span class="hljs-name"><a href="http://www.js-code.com/tag/div" title="浏览关于“div”的文章" target="_blank" class="tag_link">div</a></span> <span class="hljs-attr">class</span>=<span class="hljs-string">"select"</span>&gt;</span> <span class="hljs-tag">&lt;<span class="hljs-name">p</span>&gt;</span>请选择:<span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span> <span class="hljs-tag">&lt;<span class="hljs-name">ul</span>&gt;</span> <span class="hljs-tag">&lt;<span class="hljs-name">li</span>&gt;</span>北京<span class="hljs-tag">&lt;/<span class="hljs-name">li</span>&gt;</span> <span class="hljs-tag">&lt;<span class="hljs-name">li</span>&gt;</span>上海<span class="hljs-tag">&lt;/<span class="hljs-name">li</span>&gt;</span> <span class="hljs-tag">&lt;<span class="hljs-name">li</span>&gt;</span>杭州<span class="hljs-tag">&lt;/<span class="hljs-name">li</span>&gt;</span> <span class="hljs-tag">&lt;/<span class="hljs-name">ul</span>&gt;</span> <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span> <span class="hljs-comment">&lt;!--使用时通常是复制上面结构改数据--&gt;</span> <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"select"</span>&gt;</span> <span class="hljs-tag">&lt;<span class="hljs-name">p</span>&gt;</span>请选择:<span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span> <span class="hljs-tag">&lt;<span class="hljs-name">ul</span>&gt;</span> <span class="hljs-tag">&lt;<span class="hljs-name">li</span>&gt;</span>博士<span class="hljs-tag">&lt;/<span class="hljs-name">li</span>&gt;</span> <span class="hljs-tag">&lt;<span class="hljs-name">li</span>&gt;</span>研究生<span class="hljs-tag">&lt;/<span class="hljs-name">li</span>&gt;</span> <span class="hljs-tag">&lt;<span class="hljs-name">li</span>&gt;</span>本科<span class="hljs-tag">&lt;/<span class="hljs-name">li</span>&gt;</span> <span class="hljs-tag">&lt;/<span class="hljs-name">ul</span>&gt;</span> <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></code></pre> <p>定义好一个基本结构后,如果要再次使用,复制一份结构改变数据即可。这样复制粘贴的做法没什么毛病,但忽略一个问题---如果要修改下拉框的结构。就会变得难以维护了。</p> <p>假如我对这个结构不是很满意,我要把p标签改为span标签,使用到下拉框的结构都要改,那可要修改很多地方。如果我要给结构中ul添加一个class,使用给到下拉框的地方都要修改,也要修改很多地方。这样维护起来超级的麻烦。</p> <div class="google-auto-placed ap_container" style="text-align: center; width: 100%; height: auto; clear: none;"><ins data-ad-format="auto" class="adsbygoogle adsbygoogle-noablate" data-ad-client="ca-pub-6330872677300335" data-adsbygoogle-status="done" style="display: block; margin: auto; background-color: transparent;"><ins id="aswift_4_expand" style="display:inline-table;border:none;height:175px;margin:0;padding:0;position:relative;visibility:visible;width:697px;background-color:transparent;"><ins id="aswift_4_anchor" style="display:block;border:none;height:175px;margin:0;padding:0;position:relative;visibility:visible;width:697px;background-color:transparent;"><iframe id="aswift_4" name="aswift_4" width="697" height="175" frameborder="0" src="https://googleads.g.doubleclick.net/pagead/ads?client=ca-pub-6330872677300335&amp;output=html&amp;h=175&amp;adk=1934095149&amp;adf=3696075757&amp;w=697&amp;lmt=1557203273&amp;num_ads=1&amp;sem=mc&amp;pwprc=5909933996&amp;guci=2.2.0.0.2.2.0.0&amp;ad_type=text&amp;format=697x175&amp;url=https%3A%2F%2Fsegmentfault.com%2Fa%2F1190000009236700&amp;flash=0&amp;pra=3&amp;wgl=1&amp;fa=27&amp;adsid=NT&amp;dt=1557203273821&amp;bpp=2&amp;bdt=1058&amp;idt=-M&amp;shv=r20190429&amp;cbv=r20190131&amp;saldr=aa&amp;abxe=1&amp;prev_fmts=0x0%2C970x90&amp;nras=2&amp;correlator=2999466609617&amp;frm=20&amp;pv=1&amp;ga_vid=837977531.1557203273&amp;ga_sid=1557203273&amp;ga_hid=306723643&amp;ga_fc=0&amp;iag=0&amp;icsg=19866462336&amp;dssz=38&amp;mdo=0&amp;mso=8&amp;u_tz=480&amp;u_his=1&amp;u_java=0&amp;u_h=1080&amp;u_w=1920&amp;u_ah=1040&amp;u_aw=1920&amp;u_cd=24&amp;u_nplug=1&amp;u_nmime=1&amp;adx=31&amp;ady=1443&amp;biw=1001&amp;bih=717&amp;scr_x=0&amp;scr_y=0&amp;eid=20040013%2C21060853&amp;oid=3&amp;ref=https%3A%2F%2Fsegmentfault.com%2Fsearch%3Fq%3Dvue%26type%3Darticle%26page%3D129&amp;rx=0&amp;eae=0&amp;fc=1424&amp;brdim=447%2C192%2C447%2C192%2C1920%2C0%2C1018%2C717%2C1018%2C717&amp;vis=1&amp;rsz=%7C%7Cs%7C&amp;abl=NS&amp;fu=8216&amp;bc=13&amp;osw_key=3581259108&amp;ifi=4&amp;uci=4.d56dxpj0z0dg&amp;xpc=GJcdhggukn&amp;p=https%3A//segmentfault.com&amp;dtd=5" marginwidth="0" marginheight="0" vspace="0" hspace="0" allowtransparency="true" scrolling="no" allowfullscreen="true" data-google-container-id="4.d56dxpj0z0dg" data-google-query-id="CJSE4_TKiOICFQ6algodjtYKlA" data-load-complete="true"></iframe></ins></ins></ins></div> <p>能不能只写一套结构,然后复用,类似于JavaScript中要复用多行代码,可以封装成一个函数,在使用时只需要调用函数,无需重复写多行代码?答案是当然可以。</p> <p>在JavaScript中封装的是一个函数,然后调用。那么在html中就不能是函数了,而要定义成标签,但要避开w3c规定的标签,采用自定义标签。</p> <p>如果有一个自定义标签&lt; custom-select&gt;代表的就是自定义的下拉框,那么在需要使用下拉框的时候,只需要这样来写:</p> <div class="widget-codetool" style="display:none;"> <div class="widget-codetool--inner"> <span class="selectCode code-tool" data-toggle="tooltip" data-placement="top" title="" data-original-title="全选"></span><br /> <span type="button" class="copyCode code-tool" data-toggle="tooltip" data-placement="top" data-clipboard-text="<custom-select></custom-select><br /> <custom-select></custom-select><br /> <custom-select></custom-select>" title="" data-original-title="复制"></span> </div> </p></div> <pre class="xml hljs"><code class="html"><span class="hljs-tag">&lt;<span class="hljs-name">custom-select</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">custom-select</span>&gt;</span> <span class="hljs-tag">&lt;<span class="hljs-name">custom-select</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">custom-select</span>&gt;</span> <span class="hljs-tag">&lt;<span class="hljs-name">custom-select</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">custom-select</span>&gt;</span></code></pre> <p>是不是变得精简很多?</p> <blockquote> <p>对于自定义标签名字,可以参考<a href="https://www.w3.org/TR/custom-elements/#concepts" rel="nofollow noreferrer" target="_blank">W3C规定</a></p> </blockquote> <p>这样只是一个自定义标签而已,浏览器并不会解析为自定义的下拉框结构。我们真是的目的是要让&lt; custom-select&gt;自定义标签代表一段<a href="http://www.js-code.com/tag/html" title="HTML" target="_blank">HTML</a>结构,也就是在浏览器中展示的是自定义下拉框结构。</p> <p>写上自定义标签:</p> <div class="widget-codetool" style="display:none;"> <div class="widget-codetool--inner"> <span class="selectCode code-tool" data-toggle="tooltip" data-placement="top" title="" data-original-title="全选"></span><br /> <span type="button" class="copyCode code-tool" data-toggle="tooltip" data-placement="top" data-clipboard-text="<custom-select></custom-select>" title="" data-original-title="复制"></span> </div> </p></div> <pre class="xml hljs"><code class="html" style="word-break: break-word; white-space: initial;"><span class="hljs-tag">&lt;<span class="hljs-name">custom-select</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">custom-select</span>&gt;</span></code></pre> <p>最终会被解析为以下结构才是我们想要的。</p> <div class="widget-codetool" style="display:none;"> <div class="widget-codetool--inner"> <span class="selectCode code-tool" data-toggle="tooltip" data-placement="top" title="" data-original-title="全选"></span><br /> <span type="button" class="copyCode code-tool" data-toggle="tooltip" data-placement="top" data-clipboard-text=" <div class=&quot;select&quot;> <p>请选择:</p> <ul> <li>北京</li> <li>上海</li> <li>杭州</li> </ul> </div> <p>" title="" data-original-title="复制"></span> </div> </p></div> <pre class="xml hljs"><code class="html"><span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"select"</span>&gt;</span> <span class="hljs-tag">&lt;<span class="hljs-name">p</span>&gt;</span>请选择:<span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span> <span class="hljs-tag">&lt;<span class="hljs-name">ul</span>&gt;</span> <span class="hljs-tag">&lt;<span class="hljs-name">li</span>&gt;</span>北京<span class="hljs-tag">&lt;/<span class="hljs-name">li</span>&gt;</span> <span class="hljs-tag">&lt;<span class="hljs-name">li</span>&gt;</span>上海<span class="hljs-tag">&lt;/<span class="hljs-name">li</span>&gt;</span> <span class="hljs-tag">&lt;<span class="hljs-name">li</span>&gt;</span>杭州<span class="hljs-tag">&lt;/<span class="hljs-name">li</span>&gt;</span> <span class="hljs-tag">&lt;/<span class="hljs-name">ul</span>&gt;</span> <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></code></pre> <p>当使用vue时,解析的这个过程就交给<a href="http://www.js-code.com/tag/vue" title="Vue" target="_blank">Vue</a>来做。</p> <p>以上举例中自定义标签&lt; custom-select&gt;其实就是一个组件,vue的编译器为它添加特殊功能,最终会呈现我们定义的结构。</p> <p>我们是从布局结构重复使用引出要使用组件,当然组件还远远不止这些,它还有其他的功能等着去探索。</p> <h2 id="articleHeader1">定义组件</h2> <p>在vue中定义组件非常简单,使用<a href="http://www.js-code.com/tag/vue" title="浏览关于“Vue”的文章" target="_blank" class="tag_link">Vue</a>构造函数下的component函数,即可定义组件。</p> <p>语法:</p> <blockquote> <p>Vue.component(组件名, 选项对象)</p> </blockquote> <p>来定义一个下拉框组件:</p> <div class="widget-codetool" style="display:none;"> <div class="widget-codetool--inner"> <span class="selectCode code-tool" data-toggle="tooltip" data-placement="top" title="" data-original-title="全选"></span><br /> <span type="button" class="copyCode code-tool" data-toggle="tooltip" data-placement="top" data-clipboard-text="Vue.component('custom-select', { template: ` <div class=&quot;select&quot;> <p>请选择:</p> <ul> <li>北京</li> <li>上海</li> <li>杭州</li> </ul></div> <p> `<br /> })" title="" data-original-title="复制"></span> </div> </p></div> <pre class="hljs xml"><code>Vue.component('custom-select', { template: ` <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"select"</span>&gt;</span> <span class="hljs-tag">&lt;<span class="hljs-name">p</span>&gt;</span>请选择:<span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span> <span class="hljs-tag">&lt;<span class="hljs-name">ul</span>&gt;</span> <span class="hljs-tag">&lt;<span class="hljs-name">li</span>&gt;</span>北京<span class="hljs-tag">&lt;/<span class="hljs-name">li</span>&gt;</span> <span class="hljs-tag">&lt;<span class="hljs-name">li</span>&gt;</span>上海<span class="hljs-tag">&lt;/<span class="hljs-name">li</span>&gt;</span> <span class="hljs-tag">&lt;<span class="hljs-name">li</span>&gt;</span>杭州<span class="hljs-tag">&lt;/<span class="hljs-name">li</span>&gt;</span> <span class="hljs-tag">&lt;/<span class="hljs-name">ul</span>&gt;</span> <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span> ` })</code></pre> <p>组件的名字就为custom-select,在模板中使用组件:</p> <div class="widget-codetool" style="display:none;"> <div class="widget-codetool--inner"> <span class="selectCode code-tool" data-toggle="tooltip" data-placement="top" title="" data-original-title="全选"></span><br /> <span type="button" class="copyCode code-tool" data-toggle="tooltip" data-placement="top" data-clipboard-text=" <div id=&quot;app&quot;> <custom-select></custom-select><br /> <custom-select></custom-select> </div> <p><script> Vue.component('custom-select', { template: `</p> <div class=&quot;select&quot;> <p>请选择:</p> <ul> <li>北京</li> <li>上海</li> <li>杭州</li> </ul></div> <p> ` })</p> <p> new Vue({ el: '#app' })</p> <p></script>" title="" data-original-title="复制"></span> </div> </p></div> <pre class="hljs xml"><code><span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"app"</span>&gt;</span> <span class="hljs-tag">&lt;<span class="hljs-name">custom-select</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">custom-select</span>&gt;</span> <span class="hljs-tag">&lt;<span class="hljs-name">custom-select</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">custom-select</span>&gt;</span> <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span> <span class="hljs-tag">&lt;<span class="hljs-name">script</span>&gt;</span><span class="xml"> Vue.component('custom-select', { template: ` <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"select"</span>&gt;</span> <span class="hljs-tag">&lt;<span class="hljs-name">p</span>&gt;</span>请选择:<span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span> <span class="hljs-tag">&lt;<span class="hljs-name">ul</span>&gt;</span> <span class="hljs-tag">&lt;<span class="hljs-name">li</span>&gt;</span>北京<span class="hljs-tag">&lt;/<span class="hljs-name">li</span>&gt;</span> <span class="hljs-tag">&lt;<span class="hljs-name">li</span>&gt;</span>上海<span class="hljs-tag">&lt;/<span class="hljs-name">li</span>&gt;</span> <span class="hljs-tag">&lt;<span class="hljs-name">li</span>&gt;</span>杭州<span class="hljs-tag">&lt;/<span class="hljs-name">li</span>&gt;</span> <span class="hljs-tag">&lt;/<span class="hljs-name">ul</span>&gt;</span> <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span> ` }) new Vue({ el: '#app' }) </span><span class="hljs-tag">&lt;/<span class="hljs-name">script</span>&gt;</span></code></pre> <p>在模板中使用组件和正常标签一样。</p> <p></code></p>

本文固定链接: http://www.js-code.com/vue-js/vue-js_26906.html