vue.js进阶之组件

来源:互联网 发布:淘宝举报店铺 编辑:程序博客网 时间:2024/05/19 21:59
<div id="article_details" class="details">
    <div class="article_title">   
         <span class="ico ico_type_Original"></span>




    <h1>
        <span class="link_title"><a href="/sinat_25127047/article/details/53032430">
        vue.js进阶之组件            
        </a></span>
    </h1>
</div>


   


        <div class="article_manage clearfix">
        <div class="article_l">
            <span class="link_categories">
            标签:
              <a href="http://www.csdn.net/tag/vue" target="_blank" onclick="_gaq.push(['_trackEvent','function', 'onclick', 'blog_articles_tag']);">vue</a><a href="http://www.csdn.net/tag/vue%e7%bb%84%e4%bb%b6" target="_blank" onclick="_gaq.push(['_trackEvent','function', 'onclick', 'blog_articles_tag']);">vue组件</a>
            </span>
        </div>
        <div class="article_r">
            <span class="link_postdate">2016-11-09 16:52</span>
            <span class="link_view" title="阅读次数">978人阅读</span>
            <span class="link_comments" title="评论次数"> <a href="#comments" onclick="_gaq.push(['_trackEvent','function', 'onclick', 'blog_articles_pinglun'])">评论</a>(0)</span>
            <span class="link_collect tracking-ad" data-mod="popu_171"> <a href="javascript:void(0);" onclick="javascript:collectArticle('vue.js%e8%bf%9b%e9%98%b6%e4%b9%8b%e7%bb%84%e4%bb%b6','53032430');return false;" title="收藏" target="_blank">收藏</a></span>
             <span class="link_report"> <a href="#report" onclick="javascript:report(53032430,2);return false;" title="举报">举报</a></span>


        </div>
    </div>
    <div class="embody" style="display:none" id="embody">
        <span class="embody_t">本文章已收录于:</span>
        <div class="embody_c" id="lib" value="{&quot;err&quot;:0,&quot;msg&quot;:&quot;ok&quot;,&quot;data&quot;:[]}"></div>
    </div>
    <style type="text/css">        
            .embody{
                padding:10px 10px 10px;
                margin:0 -20px;
                border-bottom:solid 1px #ededed;                
            }
            .embody_b{
                margin:0 ;
                padding:10px 0;
            }
            .embody .embody_t,.embody .embody_c{
                display: inline-block;
                margin-right:10px;
            }
            .embody_t{
                font-size: 12px;
                color:#999;
            }
            .embody_c{
                font-size: 12px;
            }
            .embody_c img,.embody_c em{
                display: inline-block;
                vertical-align: middle;               
            }
             .embody_c img{               
                width:30px;
                height:30px;
            }
            .embody_c em{
                margin: 0 20px 0 10px;
                color:#333;
                font-style: normal;
            }
    </style>
    <script type="text/javascript">
        $(function () {
            try
            {
                var lib = eval("("+$("#lib").attr("value")+")");
                var html = "";
                if (lib.err == 0) {
                    $.each(lib.data, function (i) {
                        var obj = lib.data[i];
                        //html += '<img src="' + obj.logo + '"/>' + obj.name + "&nbsp;&nbsp;";
                        html += ' <a href="' + obj.url + '" target="_blank">';
                        html += ' <img src="' + obj.logo + '">';
                        html += ' <em><b>' + obj.name + '</b></em>';
                        html += ' </a>';
                    });
                    if (html != "") {
                        setTimeout(function () {
                            $("#lib").html(html);                      
                            $("#embody").show();
                        }, 100);
                    }
                }      
            } catch (err)
            { }
            
        });
    </script>
      <div class="category clearfix">
        <div class="category_l">
           <img src="http://static.blog.csdn.net/images/category_icon.jpg">
            <span>分类:</span>
        </div>
        <div class="category_r">
                    <label onclick="GetCategoryArticles('6077298','sinat_25127047','top','53032430');">
                        <span onclick="_gaq.push(['_trackEvent','function', 'onclick', 'blog_articles_fenlei']);">javascript<em>(29)</em></span>
                      <img class="arrow-down" src="http://static.blog.csdn.net/images/arrow_triangle _down.jpg" style="display:inline;">
                      <img class="arrow-up" src="http://static.blog.csdn.net/images/arrow_triangle_up.jpg" style="display:none;">
                        <div class="subItem">
                            <div class="subItem_t"><a href="http://blog.csdn.net/sinat_25127047/article/category/6077298" target="_blank">作者同类文章</a><i class="J_close">X</i></div>
                            <ul class="subItem_l" id="top_6077298">                            
                            </ul>
                        </div>
                    </label>                    
                    <label onclick="GetCategoryArticles('6439780','sinat_25127047','top','53032430');">
                        <span onclick="_gaq.push(['_trackEvent','function', 'onclick', 'blog_articles_fenlei']);">vue<em>(6)</em></span>
                      <img class="arrow-down" src="http://static.blog.csdn.net/images/arrow_triangle _down.jpg" style="display:inline;">
                      <img class="arrow-up" src="http://static.blog.csdn.net/images/arrow_triangle_up.jpg" style="display:none;">
                        <div class="subItem">
                            <div class="subItem_t"><a href="http://blog.csdn.net/sinat_25127047/article/category/6439780" target="_blank">作者同类文章</a><i class="J_close">X</i></div>
                            <ul class="subItem_l" id="top_6439780">                            
                            </ul>
                        </div>
                    </label>                    
        </div>
    </div>
    <script type="text/javascript" src="http://static.blog.csdn.net/scripts/category.js"></script>  
        <div class="bog_copyright">         
            <p class="copyright_p">版权声明:本文为博主原创文章,未经博主允许不得转载。</p>
        </div>


  


  
  
     


<div style="clear:both"></div><div style="border:solid 1px #ccc; background:#eee; float:left; min-width:200px;padding:4px 10px;"><p style="text-align:right;margin:0;"><span style="float:left;">目录<a href="#" title="系统根据文章中H1到H6标签自动生成文章目录">(?)</a></span><a href="#" onclick="javascript:return openct(this);" title="展开">[+]</a></p><ol style="display:none;margin-left:14px;padding-left:14px;line-height:160%;"><li><a href="#t0">vue组件基本步骤</a></li><ol><li><a href="#t1">理解</a></li></ol><li><a href="#t2">属性值的传递</a></li><ol><li><a href="#t3">data和props</a></li><ol><li><a href="#t4">data</a></li><li><a href="#t5">关于组件的作用域</a></li><li><a href="#t6">父组件和子组件通信</a></li><ol><li><a href="#t7">a 父元素向子元素通信props</a></li><li><a href="#t8">a 子元素向父元素传递信息自定义事件</a></li></ol></ol></ol><li><a href="#t9">使用slot</a></li></ol></div><div style="clear:both"></div><div id="article_content" class="article_content">
        <div class="markdown_views"><p>因为之前的项目用了vue,但是是边学边用,很多细节都不熟悉,比如vue-router,之前也写过vue+browserify构建大型应用。这次写一个vue最强大的功能,就是vue的组件。 <br>
首先推荐一个博客,真的写得非常好,当然官方API也写得很好。 <br>
<a href="http://www.cnblogs.com/keepfool/p/5625583.html">http://www.cnblogs.com/keepfool/p/5625583.html</a></p>






<h1 id="vue组件基本步骤"><a name="t0"></a><strong>vue组件基本步骤</strong></h1>


<p>这个图也是盗用这个博客的,所以先声明一下,我算是转载吧,哈哈。 <br>
步骤: <br>
 1 、创建组件构造器 <br>
 2、 注册组件 <br>
 3、在Vue实例中使用组件 <br>
<img src="http://img.blog.csdn.net/20161104103141470" alt="这里写图片描述" title=""> <br>
一个小小的demo来说明一下,这个就是官方的例子:</p>






<pre class="prettyprint" name="code"><code class="hljs applescript has-numbering">&lt;<span class="hljs-keyword">div</span> <span class="hljs-property">id</span>=<span class="hljs-string">"example"</span>&gt;
  &lt;<span class="hljs-keyword">my</span>-component&gt;&lt;/<span class="hljs-keyword">my</span>-component&gt;
&lt;/<span class="hljs-keyword">div</span>&gt;</code><ul class="pre-numbering"><li>1</li><li>2</li><li>3</li></ul><div class="save_code tracking-ad" data-mod="popu_249" style="display: none;"><a href="javascript:;" target="_blank"><img src="http://static.blog.csdn.net/images/save_snippets_01.png"></a></div><ul class="pre-numbering"><li>1</li><li>2</li><li>3</li></ul></pre>






<pre class="prettyprint" name="code"><code class="hljs cs has-numbering"><span class="hljs-comment">// 定义</span>
<span class="hljs-keyword">var</span> MyComponent = Vue.extend({
  template: <span class="hljs-string">'&lt;div&gt;A custom component!&lt;/div&gt;'</span>
})


<span class="hljs-comment">// 注册</span>
Vue.component(<span class="hljs-string">'my-component'</span>, MyComponent)


<span class="hljs-comment">// 创建根实例</span>
<span class="hljs-keyword">new</span> Vue({
  el: <span class="hljs-string">'#example'</span>
})</code><ul class="pre-numbering"><li>1</li><li>2</li><li>3</li><li>4</li><li>5</li><li>6</li><li>7</li><li>8</li><li>9</li><li>10</li><li>11</li><li>12</li></ul><div class="save_code tracking-ad" data-mod="popu_249" style="display: none;"><a href="javascript:;" target="_blank"><img src="http://static.blog.csdn.net/images/save_snippets.png"></a></div><ul class="pre-numbering"><li>1</li><li>2</li><li>3</li><li>4</li><li>5</li><li>6</li><li>7</li><li>8</li><li>9</li><li>10</li><li>11</li><li>12</li></ul></pre>






<pre class="prettyprint" name="code"><code class="hljs applescript has-numbering">&lt;<span class="hljs-keyword">div</span> <span class="hljs-property">id</span>=<span class="hljs-string">"example"</span>&gt;
  &lt;<span class="hljs-keyword">div</span>&gt;A custom component!&lt;/<span class="hljs-keyword">div</span>&gt;
&lt;/<span class="hljs-keyword">div</span>&gt;</code><ul class="pre-numbering"><li>1</li><li>2</li><li>3</li></ul><div class="save_code tracking-ad" data-mod="popu_249"><a href="javascript:;" target="_blank"><img src="http://static.blog.csdn.net/images/save_snippets.png"></a></div><ul class="pre-numbering"><li>1</li><li>2</li><li>3</li></ul></pre>






<h2 id="理解"><a name="t1"></a>理解</h2>


<ol>
<li>Vue.extend()是Vue构造器的扩展,调用Vue.extend()创建的是一个组件构造器。 </li>
<li>Vue.extend()构造器有一个选项对象,选项对象的template属性用于定义组件要渲染的HTML。 </li>
<li>使用Vue.component()注册组件时,需要提供2个参数,第1个参数时组件的标签,第2个参数是组件构造器。 </li>
<li>组件应该挂载到某个Vue实例下,否则它不会生效。</li>
</ol>






<h1 id="属性值的传递"><a name="t2"></a><strong>属性值的传递</strong></h1>


<p>组件实例的作用域是孤立的。这意味着不能并且不应该在子组件的模板内直接引用父组件的数据。可以使用 props 把数据传给子组件。</p>






<pre class="prettyprint" name="code"><code class="hljs cs has-numbering">Vue.component(<span class="hljs-string">'child'</span>, {
  <span class="hljs-comment">// 声明 props</span>
  props: [<span class="hljs-string">'message'</span>],
  <span class="hljs-comment">// 就像 data 一样,prop 可以用在模板内</span>
  <span class="hljs-comment">// 同样也可以在 vm 实例中像 “this.message” 这样使用</span>
  template: <span class="hljs-string">'&lt;span&gt;{{ message }}&lt;/span&gt;'</span>
})</code><ul class="pre-numbering"><li>1</li><li>2</li><li>3</li><li>4</li><li>5</li><li>6</li><li>7</li></ul><div class="save_code tracking-ad" data-mod="popu_249"><a href="javascript:;" target="_blank"><img src="http://static.blog.csdn.net/images/save_snippets.png"></a></div><ul class="pre-numbering"><li>1</li><li>2</li><li>3</li><li>4</li><li>5</li><li>6</li><li>7</li></ul></pre>






<pre class="prettyprint" name="code"><code class="hljs xml has-numbering"><span class="hljs-tag">&lt;<span class="hljs-title">child</span> <span class="hljs-attribute">message</span>=<span class="hljs-value">"hello!"</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-title">child</span>&gt;</span></code><ul class="pre-numbering"><li>1</li></ul><div class="save_code tracking-ad" data-mod="popu_249"><a href="javascript:;" target="_blank"><img src="http://static.blog.csdn.net/images/save_snippets.png"></a></div><ul class="pre-numbering"><li>1</li></ul></pre>


<p>官网的例子。 <br>
然而如何绑定到style和id呢?</p>






<h2 id="data和props"><a name="t3"></a><strong>data和props</strong></h2>






<h3 id="1data"><a name="t4"></a><strong>1、data</strong></h3>


<p>使用组件Components时,大多数选项可以被传入到 Vue 构造器中,有一个例外: data 必须是函数。因为如果不是函数的,声明多个组件的时候,他们共享的就是同一个data,这样就会乱掉。如果通过函数返回,那么每个组件维持自己的data作用域。该data属性只在其component中可见。</p>






<pre class="prettyprint" name="code"><code class="hljs handlebars has-numbering"><span class="xml"><span class="hljs-tag">&lt;<span class="hljs-title">body</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-title">div</span> <span class="hljs-attribute">id</span>=<span class="hljs-value">"app"</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-title">my-component</span>&gt;</span>
        <span class="hljs-tag">&lt;/<span class="hljs-title">my-component</span>&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-title">div</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-title">template</span> <span class="hljs-attribute">id</span>=<span class="hljs-value">"myComponent"</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-title">div</span>&gt;</span>
            <span class="hljs-tag">&lt;<span class="hljs-title">h2</span>&gt;</span></span><span class="hljs-expression">{{<span class="hljs-variable">msg</span>}}</span><span class="xml"><span class="hljs-tag">&lt;/<span class="hljs-title">h2</span>&gt;</span>
            <span class="hljs-tag">&lt;<span class="hljs-title">button</span> @<span class="hljs-attribute">click</span>=<span class="hljs-value">"showMsg"</span>&gt;</span>Show Message<span class="hljs-tag">&lt;/<span class="hljs-title">button</span>&gt;</span>
        <span class="hljs-tag">&lt;/<span class="hljs-title">div</span>&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-title">template</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-title">body</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-title">script</span> <span class="hljs-attribute">type</span>=<span class="hljs-value">"text/javascript"</span> <span class="hljs-attribute">src</span>=<span class="hljs-value">"../dist/vue.js"</span>&gt;</span><span class="javascript"></span><span class="hljs-tag">&lt;/<span class="hljs-title">script</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-title">script</span> <span class="hljs-attribute">type</span>=<span class="hljs-value">"text/javascript"</span> <span class="hljs-attribute">src</span>=<span class="hljs-value">"../dist/vue-router.js"</span>&gt;</span><span class="javascript"></span><span class="hljs-tag">&lt;/<span class="hljs-title">script</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-title">script</span> <span class="hljs-attribute">type</span>=<span class="hljs-value">"text/javascript"</span>&gt;</span><span class="javascript">
<span class="hljs-keyword">new</span> Vue({
    el: <span class="hljs-string">'#app'</span>,
    components: {
        <span class="hljs-string">'my-component'</span>: {
            template: <span class="hljs-string">'#myComponent'</span>,
            data: <span class="hljs-function"><span class="hljs-keyword">function</span><span class="hljs-params">()</span> {</span>
                <span class="hljs-keyword">return</span> {
                    msg: <span class="hljs-string">'This is a Component!'</span> <span class="hljs-comment">//Vue中component的data必须通过function() return</span>
                }
            },
            methods: {
                showMsg: <span class="hljs-function"><span class="hljs-keyword">function</span><span class="hljs-params">()</span> {</span>
                    alert(<span class="hljs-keyword">this</span>.msg);
                }
            }
        }
    }
})
</span><span class="hljs-tag">&lt;/<span class="hljs-title">script</span>&gt;</span></span></code><ul class="pre-numbering"><li>1</li><li>2</li><li>3</li><li>4</li><li>5</li><li>6</li><li>7</li><li>8</li><li>9</li><li>10</li><li>11</li><li>12</li><li>13</li><li>14</li><li>15</li><li>16</li><li>17</li><li>18</li><li>19</li><li>20</li><li>21</li><li>22</li><li>23</li><li>24</li><li>25</li><li>26</li><li>27</li><li>28</li><li>29</li><li>30</li><li>31</li><li>32</li><li>33</li><li>34</li></ul><div class="save_code tracking-ad" data-mod="popu_249"><a href="javascript:;" target="_blank"><img src="http://static.blog.csdn.net/images/save_snippets.png"></a></div><ul class="pre-numbering"><li>1</li><li>2</li><li>3</li><li>4</li><li>5</li><li>6</li><li>7</li><li>8</li><li>9</li><li>10</li><li>11</li><li>12</li><li>13</li><li>14</li><li>15</li><li>16</li><li>17</li><li>18</li><li>19</li><li>20</li><li>21</li><li>22</li><li>23</li><li>24</li><li>25</li><li>26</li><li>27</li><li>28</li><li>29</li><li>30</li><li>31</li><li>32</li><li>33</li><li>34</li></ul></pre>


<p>Component其他感觉和之前用的Vue没什么区别。 <br>
也可以有methods方法,有data,多了props</p>






<h3 id="2关于组件的作用域"><a name="t5"></a><strong>2、关于组件的作用域</strong></h3>


<p>template不是标准的HTML元素,浏览器是不理解这个元素的。 <br>
<img src="http://img.blog.csdn.net/20161109111336619" alt="这里写图片描述" title=""> <br>
这里还可以看到template</p>


<p>那么Vue是如何让浏览器理解template标签的呢: <br>
感觉必须是挂载在Vue中,通过Vue解析出这个标签成为浏览器可以理解的元素。 <br>
就像下面这段代码,必须新new 一个Vue,Vue使用myComponent作为components,然后在Vue绑定的app中,这个component就会被解析成浏览器可以阅读的语言。</p>






<pre class="prettyprint" name="code"><code class="hljs lua has-numbering">new Vue({
    el: <span class="hljs-string">'#app'</span>,
    components: {
        <span class="hljs-string">'my-component'</span>: {
            template: <span class="hljs-string">'#myComponent'</span>,
            data: <span class="hljs-function"><span class="hljs-keyword">function</span><span class="hljs-params">()</span></span> {
                <span class="hljs-keyword">return</span> {
                    msg: <span class="hljs-string">'This is a Component!'</span> //Vue中component的data必须通过<span class="hljs-function"><span class="hljs-keyword">function</span><span class="hljs-params">()</span></span> <span class="hljs-keyword">return</span>
                }
            },
            methods: {
                showMsg: <span class="hljs-function"><span class="hljs-keyword">function</span><span class="hljs-params">()</span></span> {
                    alert(this.msg);
                }
            }
        }
    }
})</code><ul class="pre-numbering"><li>1</li><li>2</li><li>3</li><li>4</li><li>5</li><li>6</li><li>7</li><li>8</li><li>9</li><li>10</li><li>11</li><li>12</li><li>13</li><li>14</li><li>15</li><li>16</li><li>17</li><li>18</li></ul><div class="save_code tracking-ad" data-mod="popu_249"><a href="javascript:;" target="_blank"><img src="http://static.blog.csdn.net/images/save_snippets.png"></a></div><ul class="pre-numbering"><li>1</li><li>2</li><li>3</li><li>4</li><li>5</li><li>6</li><li>7</li><li>8</li><li>9</li><li>10</li><li>11</li><li>12</li><li>13</li><li>14</li><li>15</li><li>16</li><li>17</li><li>18</li></ul></pre>


<p>并且vue实例和component的作用域是独立的</p>






<pre class="prettyprint" name="code"><code class="hljs javascript has-numbering"><span class="hljs-keyword">new</span> Vue({
    el: <span class="hljs-string">'#app'</span>,
    data:{
        display:<span class="hljs-literal">true</span> <span class="hljs-comment">//vue实例的display</span>
    },
    components: {
        <span class="hljs-string">'my-component'</span>: {
            template: <span class="hljs-string">'#myComponent'</span>,
            data: <span class="hljs-function"><span class="hljs-keyword">function</span><span class="hljs-params">()</span> {</span>
                <span class="hljs-keyword">return</span> {
                    msg: <span class="hljs-string">'This is a Component!'</span>,
                    display: <span class="hljs-literal">false</span> <span class="hljs-comment">//component中的display</span>
                }
            },
            methods: {
                showMsg: <span class="hljs-function"><span class="hljs-keyword">function</span><span class="hljs-params">()</span> {</span>
                    alert(<span class="hljs-keyword">this</span>.msg);
                }
            }
        }
    }
})</code><ul class="pre-numbering"><li>1</li><li>2</li><li>3</li><li>4</li><li>5</li><li>6</li><li>7</li><li>8</li><li>9</li><li>10</li><li>11</li><li>12</li><li>13</li><li>14</li><li>15</li><li>16</li><li>17</li><li>18</li><li>19</li><li>20</li><li>21</li><li>22</li></ul><div class="save_code tracking-ad" data-mod="popu_249"><a href="javascript:;" target="_blank"><img src="http://static.blog.csdn.net/images/save_snippets.png"></a></div><ul class="pre-numbering"><li>1</li><li>2</li><li>3</li><li>4</li><li>5</li><li>6</li><li>7</li><li>8</li><li>9</li><li>10</li><li>11</li><li>12</li><li>13</li><li>14</li><li>15</li><li>16</li><li>17</li><li>18</li><li>19</li><li>20</li><li>21</li><li>22</li></ul></pre>






<pre class="prettyprint" name="code"><code class="hljs handlebars has-numbering"><span class="xml"> <span class="hljs-tag">&lt;<span class="hljs-title">div</span> <span class="hljs-attribute">id</span>=<span class="hljs-value">"app"</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-title">my-component</span> <span class="hljs-attribute">v-show</span>=<span class="hljs-value">"display"</span>&gt;</span>
        <span class="hljs-tag">&lt;/<span class="hljs-title">my-component</span>&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-title">div</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-title">template</span> <span class="hljs-attribute">id</span>=<span class="hljs-value">"myComponent"</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-title">div</span>&gt;</span>
            <span class="hljs-tag">&lt;<span class="hljs-title">h2</span> <span class="hljs-attribute">v-show</span>=<span class="hljs-value">"display"</span>&gt;</span></span><span class="hljs-expression">{{<span class="hljs-variable">msg</span>}}</span><span class="xml"><span class="hljs-tag">&lt;/<span class="hljs-title">h2</span>&gt;</span>
            <span class="hljs-tag">&lt;<span class="hljs-title">button</span> @<span class="hljs-attribute">click</span>=<span class="hljs-value">"showMsg"</span>&gt;</span>Show Message<span class="hljs-tag">&lt;/<span class="hljs-title">button</span>&gt;</span>
        <span class="hljs-tag">&lt;/<span class="hljs-title">div</span>&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-title">template</span>&gt;</span></span></code><ul class="pre-numbering"><li>1</li><li>2</li><li>3</li><li>4</li><li>5</li><li>6</li><li>7</li><li>8</li><li>9</li><li>10</li></ul><div class="save_code tracking-ad" data-mod="popu_249"><a href="javascript:;" target="_blank"><img src="http://static.blog.csdn.net/images/save_snippets.png"></a></div><ul class="pre-numbering"><li>1</li><li>2</li><li>3</li><li>4</li><li>5</li><li>6</li><li>7</li><li>8</li><li>9</li><li>10</li></ul></pre>


<p>运行结果:</p>


<p><img src="http://img.blog.csdn.net/20161109143552785" alt="这里写图片描述" title=""> <br>
h2被隐藏了, <br>
但是my-component没有被隐藏。 <br>
也就是说:<strong>父组件模板的内容在父组件作用域内编译;子组件模板的内容在子组件作用域内编译</strong> <br>
那么父子组件如何进行通信呢? <br>
答案是props</p>






<h3 id="3父组件和子组件通信"><a name="t6"></a><strong>3、父组件和子组件通信</strong></h3>


<p>官网的一张图 <br>
<img src="http://img.blog.csdn.net/20161109145600397" alt="这里写图片描述" title=""> <br>
父组件通过<em>* props*</em> 向下传递数据给子组件,子组件通过 <strong>events</strong> 给父组件发送消息。看看它们是怎么工作的。</p>






<h4 id="a-父元素向子元素通信props"><a name="t7"></a><strong>a. 父元素向子元素通信:props</strong></h4>


<p>还是刚刚的例子,我们在component中添加了props <br>
<strong>例子1:静态props</strong></p>






<pre class="prettyprint" name="code"><code class="hljs javascript has-numbering"><span class="hljs-keyword">new</span> Vue({
    el: <span class="hljs-string">'#app'</span>,
    data:{
        display:<span class="hljs-literal">true</span>
    },
    components: {
        <span class="hljs-string">'my-component'</span>: {
            template: <span class="hljs-string">'#myComponent'</span>,
            props:[<span class="hljs-string">'parentmsg'</span>], <span class="hljs-comment">//声明props</span>
            data: <span class="hljs-function"><span class="hljs-keyword">function</span><span class="hljs-params">()</span> {</span>
                <span class="hljs-keyword">return</span> {
                    msg: <span class="hljs-string">'This is a Component!'</span>,
                    display: <span class="hljs-literal">false</span> <span class="hljs-comment">//Vue中component的data必须通过function() return</span>
                }
            },
            methods: {
                showMsg: <span class="hljs-function"><span class="hljs-keyword">function</span><span class="hljs-params">()</span> {</span>
                    alert(<span class="hljs-keyword">this</span>.msg);
                }
            }
        }
    }
})</code><ul class="pre-numbering"><li>1</li><li>2</li><li>3</li><li>4</li><li>5</li><li>6</li><li>7</li><li>8</li><li>9</li><li>10</li><li>11</li><li>12</li><li>13</li><li>14</li><li>15</li><li>16</li><li>17</li><li>18</li><li>19</li><li>20</li><li>21</li><li>22</li><li>23</li></ul><div class="save_code tracking-ad" data-mod="popu_249"><a href="javascript:;" target="_blank"><img src="http://static.blog.csdn.net/images/save_snippets.png"></a></div><ul class="pre-numbering"><li>1</li><li>2</li><li>3</li><li>4</li><li>5</li><li>6</li><li>7</li><li>8</li><li>9</li><li>10</li><li>11</li><li>12</li><li>13</li><li>14</li><li>15</li><li>16</li><li>17</li><li>18</li><li>19</li><li>20</li><li>21</li><li>22</li><li>23</li></ul></pre>


<p>我们在template中加了一个p,这个p引用父元素的msg,另外说一声Vue中属性绑定这个不识别大小写</p>






<pre class="prettyprint" name="code"><code class="hljs lasso has-numbering"><span class="hljs-subst">&lt;</span>my<span class="hljs-attribute">-component</span> v<span class="hljs-attribute">-show</span><span class="hljs-subst">=</span><span class="hljs-string">"display"</span> parentMsg<span class="hljs-subst">=</span><span class="hljs-string">"ParentMsg"</span><span class="hljs-subst">&gt;</span></code><ul class="pre-numbering"><li>1</li></ul><div class="save_code tracking-ad" data-mod="popu_249"><a href="javascript:;" target="_blank"><img src="http://static.blog.csdn.net/images/save_snippets.png"></a></div><ul class="pre-numbering"><li>1</li></ul></pre>


<p>在浏览器看到就是</p>






<pre class="prettyprint" name="code"><code class="hljs lasso has-numbering"><span class="hljs-subst">&lt;</span>my<span class="hljs-attribute">-component</span> v<span class="hljs-attribute">-show</span><span class="hljs-subst">=</span><span class="hljs-string">"display"</span> parentmsg<span class="hljs-subst">=</span><span class="hljs-string">"ParentMsg"</span><span class="hljs-subst">&gt;</span></code><ul class="pre-numbering"><li>1</li></ul><div class="save_code tracking-ad" data-mod="popu_249"><a href="javascript:;" target="_blank"><img src="http://static.blog.csdn.net/images/save_snippets.png"></a></div><ul class="pre-numbering"><li>1</li></ul></pre>


<p>所以即使你声明了props:[‘parentMsg’]也显示不出来。我的代码是这样</p>


<p>后来看到官方的解释是这样的:</p>


<blockquote>
  <p>HTML 特性不区分大小写。当使用非字符串模版时,prop的名字形式会从 camelCase 转为 <br>
  kebab-case(短横线隔开)</p>
</blockquote>






<pre class="prettyprint" name="code"><code class="hljs handlebars has-numbering"><span class="xml"> <span class="hljs-tag">&lt;<span class="hljs-title">div</span> <span class="hljs-attribute">id</span>=<span class="hljs-value">"app"</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-title">my-component</span> <span class="hljs-attribute">v-show</span>=<span class="hljs-value">"display"</span> <span class="hljs-attribute">parentmsg</span>=<span class="hljs-value">"ParentMsg"</span>&gt;</span>
        <span class="hljs-tag">&lt;/<span class="hljs-title">my-component</span>&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-title">div</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-title">template</span> <span class="hljs-attribute">id</span>=<span class="hljs-value">"myComponent"</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-title">div</span>&gt;</span>
            <span class="hljs-tag">&lt;<span class="hljs-title">h2</span> <span class="hljs-attribute">v-show</span>=<span class="hljs-value">"display"</span>&gt;</span></span><span class="hljs-expression">{{<span class="hljs-variable">msg</span>}}</span><span class="xml"><span class="hljs-tag">&lt;/<span class="hljs-title">h2</span>&gt;</span>
            <span class="hljs-tag">&lt;<span class="hljs-title">p</span>&gt;</span></span><span class="hljs-expression">{{<span class="hljs-variable">parentmsg</span>}}</span><span class="xml"><span class="hljs-tag">&lt;/<span class="hljs-title">p</span>&gt;</span> 
            <span class="hljs-tag">&lt;<span class="hljs-title">button</span> @<span class="hljs-attribute">click</span>=<span class="hljs-value">"showMsg"</span>&gt;</span>Show Message<span class="hljs-tag">&lt;/<span class="hljs-title">button</span>&gt;</span>
        <span class="hljs-tag">&lt;/<span class="hljs-title">div</span>&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-title">template</span>&gt;</span></span></code><ul class="pre-numbering"><li>1</li><li>2</li><li>3</li><li>4</li><li>5</li><li>6</li><li>7</li><li>8</li><li>9</li><li>10</li><li>11</li></ul><div class="save_code tracking-ad" data-mod="popu_249"><a href="javascript:;" target="_blank"><img src="http://static.blog.csdn.net/images/save_snippets.png"></a></div><ul class="pre-numbering"><li>1</li><li>2</li><li>3</li><li>4</li><li>5</li><li>6</li><li>7</li><li>8</li><li>9</li><li>10</li><li>11</li></ul></pre>


<p>运行结果 <br>
<img src="http://img.blog.csdn.net/20161109150326938" alt="这里写图片描述" title=""> <br>
这里就是父元素的ParentMsg传递给了component</p>


<p><strong>例子2:动态props</strong> <br>
感觉神奇之处就在这里,用v-bind把刚刚的props绑定起来</p>






<pre class="prettyprint" name="code"><code class="hljs lasso has-numbering"><span class="hljs-subst">&lt;</span>input <span class="hljs-keyword">type</span><span class="hljs-subst">=</span><span class="hljs-string">""</span> name<span class="hljs-subst">=</span><span class="hljs-string">""</span> v<span class="hljs-attribute">-model</span><span class="hljs-subst">=</span><span class="hljs-string">"ParentMsg"</span><span class="hljs-subst">&gt;</span>
        <span class="hljs-subst">&lt;</span>my<span class="hljs-attribute">-component</span> v<span class="hljs-attribute">-show</span><span class="hljs-subst">=</span><span class="hljs-string">"display"</span> v<span class="hljs-attribute">-bind</span>:parentmsg<span class="hljs-subst">=</span><span class="hljs-string">"ParentMsg"</span><span class="hljs-subst">&gt;</span>
        <span class="hljs-subst">&lt;</span>/my<span class="hljs-attribute">-component</span><span class="hljs-subst">&gt;</span>
    <span class="hljs-subst">&lt;</span>/div<span class="hljs-subst">&gt;</span></code><ul class="pre-numbering"><li>1</li><li>2</li><li>3</li><li>4</li></ul><div class="save_code tracking-ad" data-mod="popu_249"><a href="javascript:;" target="_blank"><img src="http://static.blog.csdn.net/images/save_snippets.png"></a></div><ul class="pre-numbering"><li>1</li><li>2</li><li>3</li><li>4</li></ul></pre>


<p>这样ParentMsg就根据输入框中的ParentMsg动态变化了。</p>






<pre class="prettyprint" name="code"><code class="hljs lua has-numbering">new Vue({
    el: <span class="hljs-string">'#app'</span>,
    data:{
        display:<span class="hljs-keyword">true</span>,
        ParentMsg:<span class="hljs-string">"Hello This is Parent"</span>
    },
    components: {
        <span class="hljs-string">'my-component'</span>: {
            template: <span class="hljs-string">'#myComponent'</span>,
            props:[<span class="hljs-string">'parentmsg'</span>],
            data: <span class="hljs-function"><span class="hljs-keyword">function</span><span class="hljs-params">()</span></span> {
                <span class="hljs-keyword">return</span> {
                    msg: <span class="hljs-string">'This is a Component!'</span>,
                    display: <span class="hljs-keyword">false</span> //Vue中component的data必须通过<span class="hljs-function"><span class="hljs-keyword">function</span><span class="hljs-params">()</span></span> <span class="hljs-keyword">return</span>
                }
            },
            methods: {
                showMsg: <span class="hljs-function"><span class="hljs-keyword">function</span><span class="hljs-params">()</span></span> {
                    alert(this.msg);
                }
            }
        }
    }
})</code><ul class="pre-numbering"><li>1</li><li>2</li><li>3</li><li>4</li><li>5</li><li>6</li><li>7</li><li>8</li><li>9</li><li>10</li><li>11</li><li>12</li><li>13</li><li>14</li><li>15</li><li>16</li><li>17</li><li>18</li><li>19</li><li>20</li><li>21</li><li>22</li><li>23</li><li>24</li></ul><div class="save_code tracking-ad" data-mod="popu_249"><a href="javascript:;" target="_blank"><img src="http://static.blog.csdn.net/images/save_snippets.png"></a></div><ul class="pre-numbering"><li>1</li><li>2</li><li>3</li><li>4</li><li>5</li><li>6</li><li>7</li><li>8</li><li>9</li><li>10</li><li>11</li><li>12</li><li>13</li><li>14</li><li>15</li><li>16</li><li>17</li><li>18</li><li>19</li><li>20</li><li>21</li><li>22</li><li>23</li><li>24</li></ul></pre>


<p>prop 是单向绑定的:当父组件的属性变化时,将传导给子组件,但是不会反过来。这是为了防止子组件无意修改了父组件的状态——这会让应用的数据流难以理解。</p>


<p>另外,每次父组件更新时,子组件的所有 prop 都会更新为最新值。这意味着你不应该在子组件内部改变 prop 。如果你这么做了,Vue 会在控制台给出警告。</p>


<p>通常有两种改变 prop 的情况:</p>


<ol>
<li><p>prop 作为初始值传入,子组件之后只是将它的初始值作为本地数据的初始值使用;</p></li>
<li><p>prop 作为需要被转变的原始值传入。</p></li>
</ol>






<pre class="prettyprint" name="code"><code class="hljs handlebars has-numbering"><span class="xml"> <span class="hljs-tag">&lt;<span class="hljs-title">div</span> <span class="hljs-attribute">id</span>=<span class="hljs-value">"app"</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-title">input</span> <span class="hljs-attribute">type</span>=<span class="hljs-value">""</span> <span class="hljs-attribute">name</span>=<span class="hljs-value">""</span> <span class="hljs-attribute">v-model</span>=<span class="hljs-value">"ParentMsg"</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-title">my-component</span> <span class="hljs-attribute">v-show</span>=<span class="hljs-value">"display"</span> <span class="hljs-attribute">v-bind:parentmsg</span>=<span class="hljs-value">"ParentMsg"</span>&gt;</span>
        <span class="hljs-tag">&lt;/<span class="hljs-title">my-component</span>&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-title">div</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-title">template</span> <span class="hljs-attribute">id</span>=<span class="hljs-value">"myComponent"</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-title">div</span>&gt;</span>
            <span class="hljs-tag">&lt;<span class="hljs-title">h2</span> <span class="hljs-attribute">v-show</span>=<span class="hljs-value">"display"</span>&gt;</span></span><span class="hljs-expression">{{<span class="hljs-variable">msg</span>}}</span><span class="xml"><span class="hljs-tag">&lt;/<span class="hljs-title">h2</span>&gt;</span>
            <span class="hljs-tag">&lt;<span class="hljs-title">p</span>&gt;</span></span><span class="hljs-expression">{{<span class="hljs-variable">parentmsg</span>}}</span><span class="xml"><span class="hljs-tag">&lt;/<span class="hljs-title">p</span>&gt;</span>
            <span class="hljs-tag">&lt;<span class="hljs-title">p</span>&gt;</span></span><span class="hljs-expression">{{<span class="hljs-variable">childprops</span>}}</span><span class="xml"><span class="hljs-tag">&lt;/<span class="hljs-title">p</span>&gt;</span>
            <span class="hljs-tag">&lt;<span class="hljs-title">button</span> @<span class="hljs-attribute">click</span>=<span class="hljs-value">"showMsg"</span>&gt;</span>Show Message<span class="hljs-tag">&lt;/<span class="hljs-title">button</span>&gt;</span>
        <span class="hljs-tag">&lt;/<span class="hljs-title">div</span>&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-title">template</span>&gt;</span></span></code><ul class="pre-numbering"><li>1</li><li>2</li><li>3</li><li>4</li><li>5</li><li>6</li><li>7</li><li>8</li><li>9</li><li>10</li><li>11</li><li>12</li><li>13</li></ul><div class="save_code tracking-ad" data-mod="popu_249"><a href="javascript:;" target="_blank"><img src="http://static.blog.csdn.net/images/save_snippets.png"></a></div><ul class="pre-numbering"><li>1</li><li>2</li><li>3</li><li>4</li><li>5</li><li>6</li><li>7</li><li>8</li><li>9</li><li>10</li><li>11</li><li>12</li><li>13</li></ul></pre>






<pre class="prettyprint" name="code"><code class="hljs javascript has-numbering"><span class="hljs-keyword">new</span> Vue({
    el: <span class="hljs-string">'#app'</span>,
    data:{
        display:<span class="hljs-literal">true</span>,
        ParentMsg:<span class="hljs-string">"Hello This is Parent"</span>
    },
    components: {
        <span class="hljs-string">'my-component'</span>: {
            template: <span class="hljs-string">'#myComponent'</span>,
            props:[<span class="hljs-string">'parentmsg'</span>],
            data: <span class="hljs-function"><span class="hljs-keyword">function</span><span class="hljs-params">()</span> {</span>
                <span class="hljs-keyword">return</span> {
                    msg: <span class="hljs-string">'This is a Component!'</span>,
                    childprops:<span class="hljs-string">"child:"</span>+<span class="hljs-keyword">this</span>.parentmsg, <span class="hljs-comment">//可以在data中获取props,并生成新的data</span>
                    display: <span class="hljs-literal">false</span> <span class="hljs-comment">//Vue中component的data必须通过function() return</span>
                }
            },
            methods: {
                showMsg: <span class="hljs-function"><span class="hljs-keyword">function</span><span class="hljs-params">()</span> {</span>
                    alert(<span class="hljs-keyword">this</span>.msg);
                }
            }
        }
    }
})</code><ul class="pre-numbering"><li>1</li><li>2</li><li>3</li><li>4</li><li>5</li><li>6</li><li>7</li><li>8</li><li>9</li><li>10</li><li>11</li><li>12</li><li>13</li><li>14</li><li>15</li><li>16</li><li>17</li><li>18</li><li>19</li><li>20</li><li>21</li><li>22</li><li>23</li><li>24</li><li>25</li></ul><div class="save_code tracking-ad" data-mod="popu_249"><a href="javascript:;" target="_blank"><img src="http://static.blog.csdn.net/images/save_snippets.png"></a></div><ul class="pre-numbering"><li>1</li><li>2</li><li>3</li><li>4</li><li>5</li><li>6</li><li>7</li><li>8</li><li>9</li><li>10</li><li>11</li><li>12</li><li>13</li><li>14</li><li>15</li><li>16</li><li>17</li><li>18</li><li>19</li><li>20</li><li>21</li><li>22</li><li>23</li><li>24</li><li>25</li></ul></pre>






<h4 id="a-子元素向父元素传递信息自定义事件"><a name="t8"></a><strong>a. 子元素向父元素传递信息:自定义事件</strong></h4>


<p>我们知道,父组件是使用 props 传递数据给子组件,但如果子组件要把数据传递回去,应该怎样做?那就是自定义事件!</p>






<pre class="prettyprint" name="code"><code class="hljs applescript has-numbering">使用 $<span class="hljs-function_start"><span class="hljs-keyword">on</span><span class="hljs-params">(eventName)</span></span> 监听事件 
使用 $emit(eventName) 触发事件</code><ul class="pre-numbering"><li>1</li><li>2</li></ul><div class="save_code tracking-ad" data-mod="popu_249"><a href="javascript:;" target="_blank"><img src="http://static.blog.csdn.net/images/save_snippets.png"></a></div><ul class="pre-numbering"><li>1</li><li>2</li></ul></pre>






<pre class="prettyprint" name="code"><code class="hljs lasso has-numbering"> <span class="hljs-subst">&lt;</span>button<span class="hljs-attribute">-counter</span> v<span class="hljs-attribute">-on</span>:increment<span class="hljs-subst">=</span><span class="hljs-string">"incrementTotal"</span><span class="hljs-subst">&gt;&lt;</span>/button<span class="hljs-attribute">-counter</span><span class="hljs-subst">&gt;</span></code><ul class="pre-numbering"><li>1</li></ul><div class="save_code tracking-ad" data-mod="popu_249"><a href="javascript:;" target="_blank"><img src="http://static.blog.csdn.net/images/save_snippets.png"></a></div><ul class="pre-numbering"><li>1</li></ul></pre>






<pre class="prettyprint" name="code"><code class="hljs javascript has-numbering">Vue.component(<span class="hljs-string">'button-counter'</span>, {
    template: <span class="hljs-string">'&lt;button v-on:click="increment"&gt;{{counter}}&lt;/button&gt;'</span>,
    data: <span class="hljs-function"><span class="hljs-keyword">function</span><span class="hljs-params">()</span> {</span>
        <span class="hljs-keyword">return</span> {
            counter: <span class="hljs-number">0</span>
        }
    },
    methods: {
        increment: <span class="hljs-function"><span class="hljs-keyword">function</span><span class="hljs-params">()</span> {</span>
            alert(<span class="hljs-string">"increment"</span>)
            <span class="hljs-keyword">this</span>.counter += <span class="hljs-number">1</span>;
            <span class="hljs-keyword">this</span>.$emit(<span class="hljs-string">'increment'</span>);
        }
    }
})</code><ul class="pre-numbering"><li>1</li><li>2</li><li>3</li><li>4</li><li>5</li><li>6</li><li>7</li><li>8</li><li>9</li><li>10</li><li>11</li><li>12</li><li>13</li><li>14</li><li>15</li></ul><div class="save_code tracking-ad" data-mod="popu_249"><a href="javascript:;" target="_blank"><img src="http://static.blog.csdn.net/images/save_snippets.png"></a></div><ul class="pre-numbering"><li>1</li><li>2</li><li>3</li><li>4</li><li>5</li><li>6</li><li>7</li><li>8</li><li>9</li><li>10</li><li>11</li><li>12</li><li>13</li><li>14</li><li>15</li></ul></pre>






<pre class="prettyprint" name="code"><code class="hljs css has-numbering"><span class="hljs-tag">new</span> <span class="hljs-tag">Vue</span>(<span class="hljs-rules">{
    <span class="hljs-rule"><span class="hljs-attribute">el</span>:<span class="hljs-value"> <span class="hljs-string">'#app'</span>,
    data: {
        display: true,
        ParentMsg: <span class="hljs-string">"Hello This is Parent"</span>,
        total: <span class="hljs-number">0</span>
    </span></span></span>},
    <span class="hljs-tag">methods</span>: <span class="hljs-rules">{
        <span class="hljs-rule"><span class="hljs-attribute">incrementTotal</span>:<span class="hljs-value"> <span class="hljs-function">function()</span> {
            <span class="hljs-function">alert(<span class="hljs-string">"incrementTotal"</span>)</span>
            this.total += <span class="hljs-number">1</span></span></span>;
        <span class="hljs-rule">}</span></span>
    },
})</code><ul class="pre-numbering"><li>1</li><li>2</li><li>3</li><li>4</li><li>5</li><li>6</li><li>7</li><li>8</li><li>9</li><li>10</li><li>11</li><li>12</li><li>13</li><li>14</li></ul><div class="save_code tracking-ad" data-mod="popu_249"><a href="javascript:;" target="_blank"><img src="http://static.blog.csdn.net/images/save_snippets.png"></a></div><ul class="pre-numbering"><li>1</li><li>2</li><li>3</li><li>4</li><li>5</li><li>6</li><li>7</li><li>8</li><li>9</li><li>10</li><li>11</li><li>12</li><li>13</li><li>14</li></ul></pre>


<p>先运行increment,再运行incrementTotal <br>
感觉这两句是非常重要的:</p>






<pre class="prettyprint" name="code"><code class="hljs lasso has-numbering">v<span class="hljs-attribute">-on</span>:increment<span class="hljs-subst">=</span><span class="hljs-string">"incrementTotal"</span>
this<span class="hljs-built_in">.</span><span class="hljs-variable">$emit</span>(<span class="hljs-string">'increment'</span>);</code><ul class="pre-numbering"><li>1</li><li>2</li></ul><div class="save_code tracking-ad" data-mod="popu_249"><a href="javascript:;" target="_blank"><img src="http://static.blog.csdn.net/images/save_snippets.png"></a></div><ul class="pre-numbering"><li>1</li><li>2</li></ul></pre>


<p>分析,button上面绑定了v-on:click=”increment”,当点击按钮触发increment事件,当increment函数执行完毕,触发incrementTotal函数。全在于 this.$emit(‘increment’); 不然执行完毕increment就完毕了。 <br>
官网的例子:</p>






<pre class="prettyprint" name="code"><code class="hljs handlebars has-numbering"><span class="xml"><span class="hljs-tag">&lt;<span class="hljs-title">div</span> <span class="hljs-attribute">id</span>=<span class="hljs-value">"counter-event-example"</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-title">p</span>&gt;</span></span><span class="hljs-expression">{{ <span class="hljs-variable">total</span> }}</span><span class="xml"><span class="hljs-tag">&lt;/<span class="hljs-title">p</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-title">button-counter</span> <span class="hljs-attribute">v-on:increment</span>=<span class="hljs-value">"incrementTotal"</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-title">button-counter</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-title">button-counter</span> <span class="hljs-attribute">v-on:increment</span>=<span class="hljs-value">"incrementTotal"</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-title">button-counter</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-title">div</span>&gt;</span></span></code><ul class="pre-numbering"><li>1</li><li>2</li><li>3</li><li>4</li><li>5</li></ul><div class="save_code tracking-ad" data-mod="popu_249"><a href="javascript:;" target="_blank"><img src="http://static.blog.csdn.net/images/save_snippets.png"></a></div><ul class="pre-numbering"><li>1</li><li>2</li><li>3</li><li>4</li><li>5</li></ul></pre>






<pre class="prettyprint" name="code"><code class="hljs javascript has-numbering">Vue.component(<span class="hljs-string">'button-counter'</span>, {
  template: <span class="hljs-string">'&lt;button v-on:click="increment"&gt;{{ counter }}&lt;/button&gt;'</span>,
  data: <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-params">()</span> {</span>
    <span class="hljs-keyword">return</span> {
      counter: <span class="hljs-number">0</span>
    }
  },
  methods: {
    increment: <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-params">()</span> {</span>
      <span class="hljs-keyword">this</span>.counter += <span class="hljs-number">1</span>
      <span class="hljs-keyword">this</span>.$emit(<span class="hljs-string">'increment'</span>)
    }
  },
})
<span class="hljs-keyword">new</span> Vue({
  el: <span class="hljs-string">'#counter-event-example'</span>,
  data: {
    total: <span class="hljs-number">0</span>
  },
  methods: {
    incrementTotal: <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-params">()</span> {</span>
      <span class="hljs-keyword">this</span>.total += <span class="hljs-number">1</span>
    }
  }
})</code><ul class="pre-numbering"><li>1</li><li>2</li><li>3</li><li>4</li><li>5</li><li>6</li><li>7</li><li>8</li><li>9</li><li>10</li><li>11</li><li>12</li><li>13</li><li>14</li><li>15</li><li>16</li><li>17</li><li>18</li><li>19</li><li>20</li><li>21</li><li>22</li><li>23</li><li>24</li><li>25</li></ul><div class="save_code tracking-ad" data-mod="popu_249"><a href="javascript:;" target="_blank"><img src="http://static.blog.csdn.net/images/save_snippets.png"></a></div><ul class="pre-numbering"><li>1</li><li>2</li><li>3</li><li>4</li><li>5</li><li>6</li><li>7</li><li>8</li><li>9</li><li>10</li><li>11</li><li>12</li><li>13</li><li>14</li><li>15</li><li>16</li><li>17</li><li>18</li><li>19</li><li>20</li><li>21</li><li>22</li><li>23</li><li>24</li><li>25</li></ul></pre>


<p><img src="http://img.blog.csdn.net/20161109161434438" alt="这里写图片描述" title=""> <br>
这样点击任意一个button都会调用 incrementTotal。</p>






<pre class="prettyprint" name="code"><code class="hljs lasso has-numbering">input v<span class="hljs-attribute">-model</span><span class="hljs-subst">=</span><span class="hljs-string">"something"</span><span class="hljs-subst">&gt;</span></code><ul class="pre-numbering"><li>1</li></ul><div class="save_code tracking-ad" data-mod="popu_249"><a href="javascript:;" target="_blank"><img src="http://static.blog.csdn.net/images/save_snippets.png"></a></div><ul class="pre-numbering"><li>1</li></ul></pre>


<p>其实v-model仅仅是一颗语法糖</p>


<pre class="prettyprint" name="code"><code class="hljs livecodeserver has-numbering">&lt;input v-bind:<span class="hljs-built_in">value</span>=<span class="hljs-string">"something"</span> v-<span class="hljs-command"><span class="hljs-keyword">on</span>:<span class="hljs-title">input</span>=<span class="hljs-string">"something = $event.target.value"</span>&gt;</span>
</code><ul class="pre-numbering"><li>1</li><li>2</li></ul><div class="save_code tracking-ad" data-mod="popu_249"><a href="javascript:;" target="_blank"><img src="http://static.blog.csdn.net/images/save_snippets.png"></a></div><ul class="pre-numbering"><li>1</li><li>2</li></ul></pre>


<p>所以要让组件的 v-model 生效,它必须:</p>


<p>1.接受一个 value 属性 <br>
 2. 在有新的 value 时触发 input 事件</p>






<pre class="prettyprint" name="code"><code class="hljs handlebars has-numbering"><span class="xml"><span class="hljs-tag">&lt;<span class="hljs-title">div</span> <span class="hljs-attribute">id</span>=<span class="hljs-value">"app2"</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-title">currency-input</span> <span class="hljs-attribute">label</span>=<span class="hljs-value">"Price"</span> <span class="hljs-attribute">v-model</span>=<span class="hljs-value">"price"</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-title">currency-input</span>&gt;</span>  
        <span class="hljs-tag">&lt;<span class="hljs-title">currency-input</span> <span class="hljs-attribute">label</span>=<span class="hljs-value">"Shipping"</span> <span class="hljs-attribute">v-model</span>=<span class="hljs-value">"shipping"</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-title">currency-input</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-title">currency-input</span> <span class="hljs-attribute">label</span>=<span class="hljs-value">"Handling"</span> <span class="hljs-attribute">v-model</span>=<span class="hljs-value">"handling"</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-title">currency-input</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-title">currency-input</span> <span class="hljs-attribute">label</span>=<span class="hljs-value">"Discount"</span> <span class="hljs-attribute">v-model</span>=<span class="hljs-value">"discount"</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-title">currency-input</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-title">p</span>&gt;</span>Total: $</span><span class="hljs-expression">{{ <span class="hljs-variable">total</span> }}</span><span class="xml"><span class="hljs-tag">&lt;/<span class="hljs-title">p</span>&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-title">div</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-title">template</span> <span class="hljs-attribute">id</span>=<span class="hljs-value">"myComponent"</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-title">div</span>&gt;</span>
            <span class="hljs-tag">&lt;<span class="hljs-title">h2</span> <span class="hljs-attribute">v-show</span>=<span class="hljs-value">"display"</span>&gt;</span></span><span class="hljs-expression">{{<span class="hljs-variable">msg</span>}}</span><span class="xml"><span class="hljs-tag">&lt;/<span class="hljs-title">h2</span>&gt;</span>
            <span class="hljs-tag">&lt;<span class="hljs-title">p</span>&gt;</span></span><span class="hljs-expression">{{<span class="hljs-variable">parentmsg</span>}}</span><span class="xml"><span class="hljs-tag">&lt;/<span class="hljs-title">p</span>&gt;</span>
            <span class="hljs-tag">&lt;<span class="hljs-title">p</span>&gt;</span></span><span class="hljs-expression">{{<span class="hljs-variable">childprops</span>}}</span><span class="xml"><span class="hljs-tag">&lt;/<span class="hljs-title">p</span>&gt;</span>
            <span class="hljs-tag">&lt;<span class="hljs-title">button</span> @<span class="hljs-attribute">click</span>=<span class="hljs-value">"showMsg"</span>&gt;</span>Show Message<span class="hljs-tag">&lt;/<span class="hljs-title">button</span>&gt;</span>
        <span class="hljs-tag">&lt;/<span class="hljs-title">div</span>&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-title">template</span>&gt;</span></span></code><ul class="pre-numbering"><li>1</li><li>2</li><li>3</li><li>4</li><li>5</li><li>6</li><li>7</li><li>8</li><li>9</li><li>10</li><li>11</li><li>12</li><li>13</li><li>14</li><li>15</li></ul><div class="save_code tracking-ad" data-mod="popu_249"><a href="javascript:;" target="_blank"><img src="http://static.blog.csdn.net/images/save_snippets.png"></a></div><ul class="pre-numbering"><li>1</li><li>2</li><li>3</li><li>4</li><li>5</li><li>6</li><li>7</li><li>8</li><li>9</li><li>10</li><li>11</li><li>12</li><li>13</li><li>14</li><li>15</li></ul></pre>


<pre class="prettyprint" name="code"><code class="hljs javascript has-numbering">Vue.component(<span class="hljs-string">'currency-input'</span>, {
  template: <span class="hljs-string">'\
    &lt;div&gt;\
      &lt;label v-if="label"&gt;{{ label }}&lt;/label&gt;\
      $\
      &lt;input\
        ref="input"\
        v-bind:value="value"\
        v-on:input="updateValue($event.target.value)"\
        v-on:focus="selectAll"\
      &gt;\
    &lt;/div&gt;\
  '</span>,
  props: {
    value: {
      <span class="hljs-comment">// type: Number,</span>
      <span class="hljs-keyword">default</span>: <span class="hljs-number">0</span>
    },
    label: {
      <span class="hljs-comment">// type: String,</span>
      <span class="hljs-keyword">default</span>: <span class="hljs-string">''</span>
    }
  },
  methods: {
    updateValue: <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-params">(value)</span> {</span>
      <span class="hljs-keyword">this</span>.$emit(<span class="hljs-string">'input'</span>, value) <span class="hljs-comment">//触发input事件</span>
    },
    selectAll: <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-params">(event)</span> {</span>
      setTimeout(<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-params">()</span> {</span>
        event.target.select()
      }, <span class="hljs-number">0</span>)
    }
  }
})


<span class="hljs-keyword">new</span> Vue({
  el: <span class="hljs-string">'#app2'</span>,
  data: {
    price: <span class="hljs-number">0</span>,
    shipping: <span class="hljs-number">0</span>,
    handling: <span class="hljs-number">0</span>,
    discount: <span class="hljs-number">0</span>
  },
  computed: {
    total: <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-params">()</span> {</span>
      <span class="hljs-keyword">return</span> ((
        <span class="hljs-keyword">this</span>.price * <span class="hljs-number">100</span> + 
        <span class="hljs-keyword">this</span>.shipping * <span class="hljs-number">100</span> + 
        <span class="hljs-keyword">this</span>.handling * <span class="hljs-number">100</span> - 
        <span class="hljs-keyword">this</span>.discount * <span class="hljs-number">100</span>
      ) / <span class="hljs-number">100</span>).toFixed(<span class="hljs-number">2</span>)
    }
  }
})</code><ul class="pre-numbering"><li>1</li><li>2</li><li>3</li><li>4</li><li>5</li><li>6</li><li>7</li><li>8</li><li>9</li><li>10</li><li>11</li><li>12</li><li>13</li><li>14</li><li>15</li><li>16</li><li>17</li><li>18</li><li>19</li><li>20</li><li>21</li><li>22</li><li>23</li><li>24</li><li>25</li><li>26</li><li>27</li><li>28</li><li>29</li><li>30</li><li>31</li><li>32</li><li>33</li><li>34</li><li>35</li><li>36</li><li>37</li><li>38</li><li>39</li><li>40</li><li>41</li><li>42</li><li>43</li><li>44</li><li>45</li><li>46</li><li>47</li><li>48</li><li>49</li><li>50</li><li>51</li><li>52</li><li>53</li><li>54</li></ul><div class="save_code tracking-ad" data-mod="popu_249"><a href="javascript:;" target="_blank"><img src="http://static.blog.csdn.net/images/save_snippets.png"></a></div><ul class="pre-numbering"><li>1</li><li>2</li><li>3</li><li>4</li><li>5</li><li>6</li><li>7</li><li>8</li><li>9</li><li>10</li><li>11</li><li>12</li><li>13</li><li>14</li><li>15</li><li>16</li><li>17</li><li>18</li><li>19</li><li>20</li><li>21</li><li>22</li><li>23</li><li>24</li><li>25</li><li>26</li><li>27</li><li>28</li><li>29</li><li>30</li><li>31</li><li>32</li><li>33</li><li>34</li><li>35</li><li>36</li><li>37</li><li>38</li><li>39</li><li>40</li><li>41</li><li>42</li><li>43</li><li>44</li><li>45</li><li>46</li><li>47</li><li>48</li><li>49</li><li>50</li><li>51</li><li>52</li><li>53</li><li>54</li></ul></pre>


<h1 id="使用slot"><a name="t9"></a>使用slot</h1></div>
        <script type="text/javascript">
            $(function () {
                $('pre.prettyprint code').each(function () {
                    var lines = $(this).text().split('\n').length;
                    var $numbering = $('<ul></ul>').addClass('pre-numbering').hide();
                    $(this).addClass('has-numbering').parent().append($numbering);
                    for (i = 1; i <= lines; i++) {
                        $numbering.append($('<li></li>').text(i));
                    };
                    $numbering.fadeIn(1700);
                });
            });
        </script>
   
</div>








<!-- Baidu Button BEGIN -->








<div class="bdsharebuttonbox tracking-ad bdshare-button-style0-16" style="float: right;" data-mod="popu_172" data-bd-bind="1482839958064">
<a href="#" class="bds_more" data-cmd="more" style="background-position:0 0 !important; background-image: url(http://bdimg.share.baidu.com/static/api/img/share/icons_0_16.png?v=d754dcc0.png) !important" target="_blank"></a>
<a href="#" class="bds_qzone" data-cmd="qzone" title="分享到QQ空间" style="background-position:0 -52px !important" target="_blank"></a>
<a href="#" class="bds_tsina" data-cmd="tsina" title="分享到新浪微博" style="background-position:0 -104px !important" target="_blank"></a>
<a href="#" class="bds_tqq" data-cmd="tqq" title="分享到腾讯微博" style="background-position:0 -260px !important" target="_blank"></a>
<a href="#" class="bds_renren" data-cmd="renren" title="分享到人人网" style="background-position:0 -208px !important" target="_blank"></a>
<a href="#" class="bds_weixin" data-cmd="weixin" title="分享到微信" style="background-position:0 -1612px !important" target="_blank"></a>
</div>
<script>window._bd_share_config = { "common": { "bdSnsKey": {}, "bdText": "", "bdMini": "1", "bdMiniList": false, "bdPic": "", "bdStyle": "0", "bdSize": "16" }, "share": {} }; with (document) 0[(getElementsByTagName('head')[0] || body).appendChild(createElement('script')).src = 'http://bdimg.share.baidu.com/static/api/js/share.js?v=89860593.js?cdnversion=' + ~(-new Date() / 36e5)];</script>
<!-- Baidu Button END -->


   <link rel="stylesheet" href="http://static.blog.csdn.net/css/blog_detail.css">


    
<!--172.16.140.12-->


<!-- Baidu Button BEGIN -->
<script type="text/javascript" id="bdshare_js" data="type=tools&amp;uid=1536434" src="http://bdimg.share.baidu.com/static/js/bds_s_v2.js?cdnversion=411900"></script>


<script type="text/javascript">
    document.getElementById("bdshell_js").src = "http://bdimg.share.baidu.com/static/js/shell_v2.js?cdnversion=" + Math.ceil(new Date()/3600000)
</script>
<!-- Baidu Button END -->


 


        <div id="digg" articleid="53032430">
            <dl id="btnDigg" class="digg digg_disable" onclick="btndigga();">
               
                 <dt>顶</dt>
                <dd>0</dd>
            </dl>
           
              
            <dl id="btnBury" class="digg digg_disable" onclick="btnburya();">
              
                  <dt>踩</dt>
                <dd>0</dd>               
            </dl>
            
        </div>
     <div class="tracking-ad" data-mod="popu_222"><a href="javascript:void(0);" target="_blank">&nbsp;</a>   </div>
    <div class="tracking-ad" data-mod="popu_223"> <a href="javascript:void(0);" target="_blank">&nbsp;</a></div>
    <script type="text/javascript">
                function btndigga() {
                    $(".tracking-ad[data-mod='popu_222'] a").click();
                }
                function btnburya() {
                    $(".tracking-ad[data-mod='popu_223'] a").click();
                }
            </script>


   <ul class="article_next_prev">
                <li class="prev_article"><span onclick="_gaq.push(['_trackEvent','function', 'onclick', 'blog_articles_shangyipian']);location.href='/sinat_25127047/article/details/53018497';">上一篇</span><a href="/sinat_25127047/article/details/53018497" onclick="_gaq.push(['_trackEvent','function', 'onclick', 'blog_articles_shangyipian'])">《javascript设计模式与开发实践》阅读笔记(三)</a></li>
                <li class="next_article"><span onclick="_gaq.push(['_trackEvent','function', 'onclick', 'blog_articles_xiayipian']);location.href='/sinat_25127047/article/details/53126599';">下一篇</span><a href="/sinat_25127047/article/details/53126599" onclick="_gaq.push(['_trackEvent','function', 'onclick', 'blog_articles_xiayipian'])">Vue进阶之组件(二)</a></li>
    </ul>


    <div style="clear:both; height:10px;"></div>




        <div class="similar_article" style="">
                <h4>我的同类文章</h4>
                <div class="similar_c" style="margin:20px 0px 0px 0px">
                    <div class="similar_c_t">
                                <label class="similar_cur">
                                    <span style="cursor:pointer" onclick="GetCategoryArticles('6077298','sinat_25127047','foot','53032430');">javascript<em>(29)</em></span>
                                </label>
                                <label class="">
                                    <span style="cursor:pointer" onclick="GetCategoryArticles('6439780','sinat_25127047','foot','53032430');">vue<em>(6)</em></span>
                                </label>
                    </div>
                   
                    <div class="similar_wrap tracking-ad" data-mod="popu_141" style="max-height:195px;">
                        <a href="http://blog.csdn.net" style="display:none" target="_blank">http://blog.csdn.net</a>
                        <ul class="similar_list fl"><li><em>•</em><a href="http://blog.csdn.net/sinat_25127047/article/details/53589685" id="foot_aritcle_53589685undefined6596082940907746" target="_blank" title="Vue+webpack构建单页router应用(二)">Vue+webpack构建单页router应用(二)</a><span>2016-12-13</span><label><i>阅读</i><b>37</b></label></li> <li><em>•</em><a href="http://blog.csdn.net/sinat_25127047/article/details/53363504" id="foot_aritcle_53363504undefined9646460238646986" target="_blank" title="bootstrap源码阅读(一)——modal原理">bootstrap源码阅读(一)——modal原理</a><span>2016-12-12</span><label><i>阅读</i><b>82</b></label></li> <li><em>•</em><a href="http://blog.csdn.net/sinat_25127047/article/details/53018497" id="foot_aritcle_53018497undefined4736525485986096" target="_blank" title="《javascript设计模式与开发实践》阅读笔记(三)">《javascript设计模式与开发实践》阅读笔记(三)</a><span>2016-11-03</span><label><i>阅读</i><b>52</b></label></li> <li><em>•</em><a href="http://blog.csdn.net/sinat_25127047/article/details/52860179" id="foot_aritcle_52860179undefined40135401996824127" target="_blank" title="《javascript设计模式与开发实践》阅读笔记(一)">《javascript设计模式与开发实践》阅读笔记(一)</a><span>2016-10-19</span><label><i>阅读</i><b>107</b></label></li> <li><em>•</em><a href="http://blog.csdn.net/sinat_25127047/article/details/52502800" id="foot_aritcle_52502800undefined3063901741797639" target="_blank" title="Javascript模块化编程——使用AMD,CommonJS,ES Harmony">Javascript模块化编程——使用AMD,CommonJS,ES Harmony</a><span>2016-09-11</span><label><i>阅读</i><b>130</b></label></li> </ul>


                        <ul class="similar_list fr"><li><em>•</em><a href="http://blog.csdn.net/sinat_25127047/article/details/53535171" id="foot_aritcle_53535171undefined028273206894362746" target="_blank" title="项目中的积累——HTTP跨域问题方案CORS">项目中的积累——HTTP跨域问题方案CORS</a><span>2016-12-09</span><label><i>阅读</i><b>121</b></label></li> <li><em>•</em><a href="http://blog.csdn.net/sinat_25127047/article/details/53126599" id="foot_aritcle_53126599undefined9798819967736283" target="_blank" title="Vue进阶之组件(二)">Vue进阶之组件(二)</a><span>2016-11-13</span><label><i>阅读</i><b>351</b></label></li> <li><em>•</em><a href="http://blog.csdn.net/sinat_25127047/article/details/52874532" id="foot_aritcle_52874532undefined3502825940167127" target="_blank" title="《javascript设计模式与开发实践》阅读笔记(二)">《javascript设计模式与开发实践》阅读笔记(二)</a><span>2016-10-21</span><label><i>阅读</i><b>54</b></label></li> <li><em>•</em><a href="http://blog.csdn.net/sinat_25127047/article/details/52806796" id="foot_aritcle_52806796undefined2777023446939899" target="_blank" title="RequireJS入门指南(二)-vue分页模块抽离">RequireJS入门指南(二)-vue分页模块抽离</a><span>2016-10-14</span><label><i>阅读</i><b>231</b></label></li> <li><em>•</em><a href="http://blog.csdn.net/sinat_25127047/article/details/52460782" id="foot_aritcle_52460782undefined7093957293948758" target="_blank" title="javascript模块化编程">javascript模块化编程</a><span>2016-09-07</span><label><i>阅读</i><b>128</b></label></li> </ul>
                    <a href="http://blog.csdn.net/sinat_25127047/article/category/6077298" class="MoreArticle">更多文章</a></div>
                </div>
            </div>    
    <script type="text/javascript">
        $(function () {
            GetCategoryArticles('6077298', 'sinat_25127047','foot','53032430');
        });
    </script>
      
</div>
0 0