步骤 2 : 局部组件 步骤 3 : 全局组件 步骤 4 : 参数 步骤 5 : 动态参数 步骤 6 : 自定义事件 步骤 7 : 遍历 json 数组 步骤 8 : 最开始效果步骤里的代码
如效果所示,每个产品展示,就是一个模板。 只用做一个模板,然后照着这个模板,传递不同的参数就可以看到不同的产品展示了。
这个模板,就是组件。 当前看到的这个效果比较复杂,接下来会由浅入深,慢慢地把这个效果做出来。 注: 点击产品,还可以增加销售数量。 虽然业务上不会真的增加销售数量,但是这里是演示组件也有自定义事件的效果。 <script src="https://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>
接下来就由浅入深地展开组件的学习。 先看最简单的局部组件。
在 Vue对象里增加 components: components:{ 'product':{ template:'<div class="product" >MAXFEEL休闲男士手包真皮手拿包大容量信封包手抓包夹包软韩版潮</div>' } 然后在视图里,通过如下方式就可以调用了 <product></product> 如果想重复使用,则多写几次就行了 <product></product> <product></product> <product></product> <script src="https://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>
和vue.js 里的过滤器一样,有的组件会在不同页面使用,这个时候就可以考虑用全局组件。
Vue.component('product', { template: '<div class="product" >MAXFEEL休闲男士手包真皮手拿包大容量信封包手抓包夹包软韩版潮</div>' }) 写法其实跟局部差不多,只是提出来了。 这样到处都可以用了。 <script src="https://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>
像前面的例子,产品名称都是固定的,这样肯定不行,所以就要能够传递参数给组件。
设置参数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="https://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>
所谓的动态参数,就是指组件内的参数可以和组件外的值关联起来
如效果所示,在组件外的input输入数据,就可以传递到组件内了 关键是这一行,name表示组件内的属性name, outName就是组件外的 <product v-bind:name="outName"></product> <script src="https://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>
增加自定义事件和在一个Vue对象上增加 methods 是一样的做法
先来个methods: methods:{ increaseSale:function(){ this.sale++ } } 然后在组件里: v-on:click="increaseSale" 注,这里是在组件上增加的,而不是在视图上增加的。 测试: 点击产品,就会增销量 <script src="https://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>
大部分时候是拿到一个 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="https://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>
最开始效果步骤里的代码其实就是在前面的基础上,增加了一些样式,增加了一些字段而已。
另外 template 部分因为比较复杂,就不好写在一个 单引号 ' ' 里维护起来,所以就直接写在html里,然后通过html dom 获取出来,这样编写起来略微容易一点。 var tempalateDiv=document.getElementById("tempalate").innerHTML; 其他的就没有什么新东西啦 <script src="https://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>
HOW2J公众号,关注后实时获知最新的教程和优惠活动,谢谢。
问答区域
2023-12-07
并没有观察到在步骤3里提到的可以“在不同页面使用”
回答已经提交成功,正在审核。 请于 我的回答 处查看回答记录,谢谢
2022-11-22
那个组件里的props['name'] 是干嘛的
1 个答案
endeavour_tsx 跳转到问题位置 答案时间:2023-07-02 肯定不能删啊,这个是往你定义的组件内传递数据,相当于从vue对象中每次遍历出的item传递到product中,v-bind:product="item"
回答已经提交成功,正在审核。 请于 我的回答 处查看回答记录,谢谢
2022-03-30
没看懂局部和全局区别
2020-08-16
谢谢站长!网页的演示部分,被调得太窄了
2020-04-13
this.$emit('increment') 这个是干啥的?
提问太多,页面渲染太慢,为了加快渲染速度,本页最多只显示几条提问。还有 11 条以前的提问,请 点击查看
提问之前请登陆
提问已经提交成功,正在审核。 请于 我的提问 处查看提问记录,谢谢
|