how2j.cn

步骤 1 : 组件是什么   
步骤 2 : 局部组件   
步骤 3 : 全局组件   
步骤 4 : 参数   
步骤 5 : 动态参数   
步骤 6 : 自定义事件   
步骤 7 : 遍历 json 数组   
步骤 8 : 最开始效果步骤里的代码   

步骤 1 :

组件是什么

如效果所示,每个产品展示,就是一个模板。 只用做一个模板,然后照着这个模板,传递不同的参数就可以看到不同的产品展示了。

这个模板,就是组件。

当前看到的这个效果比较复杂,接下来会由浅入深,慢慢地把这个效果做出来。

注: 点击产品,还可以增加销售数量。 虽然业务上不会真的增加销售数量,但是这里是演示组件也有自定义事件的效果。
<script src="http://how2j.cn/study/vue.min.js"></script> <style> div.product{ float:left; border:1px solid lightGray; width:200px; margin:10px; cursor: pointer; } div.product:hover{ border:1px solid #c40000; } div.price{ color:#c40000; font-weight:bold; font-size:1.2em; margin:10px; } div.productName{ color:gray; font-size:0.8em; margin:10px; } div.sale{ float:left; width:100px; border:1px solid lightgray; border-width:1px 0px 0px 0px; color:gray; font-size:0.8em; padding-left:10px; } div.review{ overflow:hidden; border:1px solid lightgray; border-width:1px 0px 0px 1px; color:gray; font-size:0.8em; padding-left:10px; } </style> <div id="tempalate" style="display:none"> <div class="product" v-on:click="increaseSales"> <div class="price"> ¥ {{product.price}} </div> <div class="productName"> {{product.name}} </div> <div class="sale"> 月成交 {{product.sale}} 笔</div> <div class="review"> 评价 {{product.review}} </div> </div> </div> <div id="div1"> <product v-for="item in products" v-bind:product="item"></product> </div> <script> var tempalateDiv=document.getElementById("tempalate").innerHTML; var templateObject = { props: ['product'], template: tempalateDiv, methods: { increaseSales: function () { this.product.sale = parseInt(this.product.sale); this.product.sale += 1 this.$emit('increment') } } } Vue.component('product', templateObject) new Vue({ el: '#div1', data:{ products:[ {"name":"MAXFEEL休闲男士手包真皮手拿包大容量信封包手抓包夹包软韩版潮","price":"889","sale":"18","review":"5"}, {"name":"宾度 男士手包真皮大容量手拿包牛皮个性潮男包手抓包软皮信封包","price":"322","sale":"35","review":"12"}, {"name":"唯美诺新款男士手包男包真皮大容量小羊皮手拿包信封包软皮夹包潮","price":"523","sale":"29","review":"3"}, ] } }) </script>


源代码
1. 双击选中单词 2. 三击选中整行 3. CTRL+F 查找 4. F8 全屏编辑,再次点击恢复
渲染中 渲染完成
效果
步骤 2 :

局部组件

接下来就由浅入深地展开组件的学习。 先看最简单的局部组件。
在 Vue对象里增加 components:

components:{
'product':{
template:'<div class="product" >MAXFEEL休闲男士手包真皮手拿包大容量信封包手抓包夹包软韩版潮</div>'
}

然后在视图里,通过如下方式就可以调用了

<product></product>

如果想重复使用,则多写几次就行了

<product></product>
<product></product>
<product></product>
运行效果
<script src="http://how2j.cn/study/vue.min.js"></script> <style> div.product{ float:left; border:1px solid lightGray; width:200px; margin:10px; cursor: pointer; } </style> <div id="div1"> <product></product> <product></product> <product></product> </div> <script> new Vue({ el: '#div1', components:{ 'product':{ template:'<div class="product" >MAXFEEL休闲男士手包真皮手拿包大容量信封包手抓包夹包软韩版潮</div>' } } }) </script>


源代码
1. 双击选中单词 2. 三击选中整行 3. CTRL+F 查找 4. F8 全屏编辑,再次点击恢复
渲染中 渲染完成
效果
步骤 3 :

全局组件

和vue.js 里的过滤器一样,有的组件会在不同页面使用,这个时候就可以考虑用全局组件。

Vue.component('product', {
template: '<div class="product" >MAXFEEL休闲男士手包真皮手拿包大容量信封包手抓包夹包软韩版潮</div>'
})

写法其实跟局部差不多,只是提出来了。 这样到处都可以用了。
运行效果
<script src="http://how2j.cn/study/vue.min.js"></script> <style> div.product{ float:left; border:1px solid lightGray; width:200px; margin:10px; cursor: pointer; } </style> <div id="div1"> <product></product> <product></product> <product></product> </div> <script> Vue.component('product', { template: '<div class="product" >MAXFEEL休闲男士手包真皮手拿包大容量信封包手抓包夹包软韩版潮</div>' }) new Vue({ el: '#div1' }) </script>


源代码
1. 双击选中单词 2. 三击选中整行 3. CTRL+F 查找 4. F8 全屏编辑,再次点击恢复
渲染中 渲染完成
效果
步骤 4 :

参数

像前面的例子,产品名称都是固定的,这样肯定不行,所以就要能够传递参数给组件。
设置参数name, 并且在组件里使用这个name:

Vue.component('product', {
props:['name'],
template: '<div class="product" >{{name}}</div>'
})

调用的时候,就当作是一个自定义属性传进去就可以了

<product name="MAXFEEL休闲男士手包真皮手拿包大容量信封包手抓包夹包软韩版潮"></product>
<product name="宾度 男士手包真皮大容量手拿包牛皮个性潮男包手抓包软皮信封包"></product>
<product name="唯美诺新款男士手包男包真皮大容量小羊皮手拿包信封包软皮夹包潮"></product>
运行效果
<script src="http://how2j.cn/study/vue.min.js"></script> <style> div.product{ float:left; border:1px solid lightGray; width:200px; margin:10px; cursor: pointer; } </style> <div id="div1"> <product name="MAXFEEL休闲男士手包真皮手拿包大容量信封包手抓包夹包软韩版潮"></product> <product name="宾度 男士手包真皮大容量手拿包牛皮个性潮男包手抓包软皮信封包"></product> <product name="唯美诺新款男士手包男包真皮大容量小羊皮手拿包信封包软皮夹包潮"></product> </div> <script> Vue.component('product', { props:['name'], template: '<div class="product" >{{name}}</div>' }) new Vue({ el: '#div1' }) </script>


源代码
1. 双击选中单词 2. 三击选中整行 3. CTRL+F 查找 4. F8 全屏编辑,再次点击恢复
渲染中 渲染完成
效果
步骤 5 :

动态参数

所谓的动态参数,就是指组件内的参数可以和组件外的值关联起来
如效果所示,在组件外的input输入数据,就可以传递到组件内了
关键是这一行,name表示组件内的属性name, outName就是组件外的

<product v-bind:name="outName"></product>
运行效果
<script src="http://how2j.cn/study/vue.min.js"></script> <style> div.product{ float:left; border:1px solid lightGray; width:200px; margin:10px; cursor: pointer; } </style> <div id="div1"> 组件外的值:<input v-model="outName" ><br> <product v-bind:name="outName"></product> </div> <script> Vue.component('product', { props:['name'], template: '<div class="product" >{{name}}</div>' }) new Vue({ el: '#div1', data:{ outName:'产品名称' } }) </script>


源代码
1. 双击选中单词 2. 三击选中整行 3. CTRL+F 查找 4. F8 全屏编辑,再次点击恢复
渲染中 渲染完成
效果
步骤 6 :

自定义事件

增加自定义事件和在一个Vue对象上增加 methods 是一样的做法
先来个methods:

methods:{
increaseSale:function(){
this.sale++
}
}

然后在组件里:

v-on:click="increaseSale"

,这里是在组件上增加的,而不是在视图上增加的。
测试: 点击产品,就会增销量
运行效果
<script src="http://how2j.cn/study/vue.min.js"></script> <style> div.product{ float:left; border:1px solid lightGray; width:200px; margin:10px; cursor: pointer; } </style> <div id="div1"> <product name="MAXFEEL休闲男士手包真皮手拿包大容量信封包手抓包夹包软韩版潮" sale="10" ></product> <product name="宾度 男士手包真皮大容量手拿包牛皮个性潮男包手抓包软皮信封包" sale="20" ></product> <product name="唯美诺新款男士手包男包真皮大容量小羊皮手拿包信封包软皮夹包潮" sale="30" ></product> </div> <script> Vue.component('product', { props:['name','sale'], template: '<div class="product" v-on:click="increaseSale">{{name}} 销量: {{sale}} </div>', methods:{ increaseSale:function(){ this.sale++ } } }) new Vue({ el: '#div1' }) </script>


源代码
1. 双击选中单词 2. 三击选中整行 3. CTRL+F 查找 4. F8 全屏编辑,再次点击恢复
渲染中 渲染完成
效果
步骤 7 :

遍历 json 数组

大部分时候是拿到一个 json 数组,然后遍历这个 json 数组为多个组件实例。
1. 首先准备产品数组

products:[
{"name":"MAXFEEL休闲男士手包真皮手拿包大容量信封包手抓包夹包软韩版潮","sale":"18"},
{"name":"宾度 男士手包真皮大容量手拿包牛皮个性潮男包手抓包软皮信封包","sale":"35"},
{"name":"唯美诺新款男士手包男包真皮大容量小羊皮手拿包信封包软皮夹包潮","sale":"29"}
]

2. 然后在视图里通过 v-for 遍历 products

<product v-for="item in products" v-bind:product="item"></product>

3. 接着修改组件,让接受的参数为 v-bind:product 里的这个 product,显示和方法里也通过 product.xxx 来调用。

Vue.component('product', {
props:['product'],
template: '<div class="product" v-on:click="increaseSale">{{product.name}} 销量: {{product.sale}} </div>',
methods:{
increaseSale:function(){
this.product.sale++
}
}
})
运行效果
<script src="http://how2j.cn/study/vue.min.js"></script> <style> div.product{ float:left; border:1px solid lightGray; width:200px; margin:10px; cursor: pointer; } </style> <div id="div1"> <product v-for="item in products" v-bind:product="item"></product> </div> <script> Vue.component('product', { props:['product'], template: '<div class="product" v-on:click="increaseSale">{{product.name}} 销量: {{product.sale}} </div>', methods:{ increaseSale:function(){ this.product.sale++ } } }) new Vue({ el: '#div1', data:{ products:[ {"name":"MAXFEEL休闲男士手包真皮手拿包大容量信封包手抓包夹包软韩版潮","sale":"18"}, {"name":"宾度 男士手包真皮大容量手拿包牛皮个性潮男包手抓包软皮信封包","sale":"35"}, {"name":"唯美诺新款男士手包男包真皮大容量小羊皮手拿包信封包软皮夹包潮","sale":"29"} ] } }) </script>


源代码
1. 双击选中单词 2. 三击选中整行 3. CTRL+F 查找 4. F8 全屏编辑,再次点击恢复
渲染中 渲染完成
效果
步骤 8 :

最开始效果步骤里的代码

最开始效果步骤里的代码其实就是在前面的基础上,增加了一些样式,增加了一些字段而已。
另外 template 部分因为比较复杂,就不好写在一个 单引号 ' ' 里维护起来,所以就直接写在html里,然后通过html dom 获取出来,这样编写起来略微容易一点。

var tempalateDiv=document.getElementById("tempalate").innerHTML;

其他的就没有什么新东西啦
运行效果
<script src="http://how2j.cn/study/vue.min.js"></script> <style> div.product{ float:left; border:1px solid lightGray; width:200px; margin:10px; cursor: pointer; } div.product:hover{ border:1px solid #c40000; } div.price{ color:#c40000; font-weight:bold; font-size:1.2em; margin:10px; } div.productName{ color:gray; font-size:0.8em; margin:10px; } div.sale{ float:left; width:100px; border:1px solid lightgray; border-width:1px 0px 0px 0px; color:gray; font-size:0.8em; padding-left:10px; } div.review{ overflow:hidden; border:1px solid lightgray; border-width:1px 0px 0px 1px; color:gray; font-size:0.8em; padding-left:10px; } </style> <div id="tempalate" style="display:none"> <div class="product" v-on:click="increaseSales"> <div class="price"> ¥ {{product.price}} </div> <div class="productName"> {{product.name}} </div> <div class="sale"> 月成交 {{product.sale}} 笔</div> <div class="review"> 评价 {{product.review}} </div> </div> </div> <div id="div1"> <product v-for="item in products" v-bind:product="item"></product> </div> <script> var tempalateDiv=document.getElementById("tempalate").innerHTML; var templateObject = { props: ['product'], template: tempalateDiv, methods: { increaseSales: function () { this.product.sale = parseInt(this.product.sale); this.product.sale += 1 this.$emit('increment') } } } Vue.component('product', templateObject) new Vue({ el: '#div1', data:{ products:[ {"name":"MAXFEEL休闲男士手包真皮手拿包大容量信封包手抓包夹包软韩版潮","price":"889","sale":"18","review":"5"}, {"name":"宾度 男士手包真皮大容量手拿包牛皮个性潮男包手抓包软皮信封包","price":"322","sale":"35","review":"12"}, {"name":"唯美诺新款男士手包男包真皮大容量小羊皮手拿包信封包软皮夹包潮","price":"523","sale":"29","review":"3"}, ] } }) </script>


源代码
1. 双击选中单词 2. 三击选中整行 3. CTRL+F 查找 4. F8 全屏编辑,再次点击恢复
渲染中 渲染完成
效果


HOW2J公众号,关注后实时获知布最新的教程和优惠活动,谢谢。


问答区域    
2018-11-20 步骤4-参数,局部组件可以使用参数吗?
唏嘘不已
局部组件可以使用参数吗?如果可以,如何表示








答案 或者 代码至少填写一项, 如果是自己有问题,请重新提问,否则站长有可能看不到




2018-10-02 组件标签命名和属性命名 好像都有规范 会影响结果
lee乐乐乐
组件标签命名和属性命名 好像都有规范 会影响结果




2 个答案

hubspring 答案时间:2018-11-29
我认为是所有的只要指定了监听的对象,那么这个vue对象就仅仅对这个对象有效果,里面的命名也要尽量规范,自己的学习看fa---

lee乐乐乐 答案时间:2018-10-02
https://cn.vuejs.org/v2/style-guide/ vue官方的风格指南




答案 或者 代码至少填写一项, 如果是自己有问题,请重新提问,否则站长有可能看不到




2018-07-20 步骤8中第71行“this.$emit('increment')”有什么用?




提问之前请登陆
关于 前端部分-Vue.js-组件 的提问

尽量提供截图代码异常信息,有助于分析和解决问题。 也可进本站QQ群交流: 902680467
提问尽量提供完整的代码,环境描述,越是有利于问题的重现,您的问题越能更快得到解答。
对教程中代码有疑问,请提供是哪个步骤,哪一行有疑问,这样便于快速定位问题,提高问题得到解答的速度
在已经存在的几千个提问里,有相当大的比例,是因为使用了和站长不同版本的开发环境导致的,比如 jdk, eclpise, idea, mysql,tomcat 等等软件的版本不一致。
请使用和站长一样的版本,可以节约自己大量的学习时间。 站长把教学中用的软件版本整理了,都统一放在了这里, 方便大家下载: http://how2j.cn/k/helloworld/helloworld-version/1718.html

上传截图