组件总练习(bootstrap+vuejs),商品增删改查(主要知识点,组件\slot)

1、功能:列表的增删改查和标签页转换,下拉框,单选框。
在这里插入图片描述
2、代码

CSS:

	 <style type="text/css">
		.tabs-tab{
			display: inline-block;
			padding: 4px 16px;
			margin-right: 6px;
			margin-bottom: 10px;
			background: #fff;
			border: 1px solid #d7dde4;
			cursor: pointer;
			position: relative;
		}

		.tabs-tab-active{
			color: brown;
			border-top: 1px solid #3399ff;
			border-bottom: 1px solid #fff;
		}

		.table thead,tbody tr td,th{
			vertical-align: middle;
			text-align:center;
		}

		input[type=number]{
			width: 80px;
		}

	</style>

HTML:

<body>
<div id="app" class="container" >
	<my-tab>
		<my-pane lable="pane1" name="pane1">
			<div class="row">
				<div class="col-md-12">
					<my-selected :shop-list="shopList">
						<my-radio slot="myRadio"></my-radio>
					</my-selected>
				</div>
			</div>
			<div class="row">
				<div class="col-md-12">
					<my-table class="table table-hover table-condensed" :shop-list="shopList"></my-table>
				</div>
			</div>
			<div class="row">
				<div class="col-md-10"></div>
				<div class="com-md-2">
					<span>总价为:{{total}}</span>
				</div>
			</div>
		</my-pane>

		<my-pane lable="pane2" name="pane2">
			<span>pane2</span>
		</my-pane>
	</my-tab>
</div>
</body>

JS:

var bus=new Vue();

	Vue.component('my-radio',{
		template:'\
			<div style="display:inline-block;">\
				<label>请选择每次增加的个数:</label>\
				<label for="radio1">1</label>\
				<input id="radio1" type="radio" v-model.number="radioVal" value="1"/>\
				<label for="radio2">5</label>\
				<input id="radio2" type="radio" v-model.number="radioVal" value="5"/>\
			</div>\
		',
		data:function () {
			return{
				radioVal:1
			}
		},
		watch:{
			radioVal:function (val) {
				bus.$emit('setRadioVal',val)
			}
		}
	});


	Vue.component('my-selected',{
		template:'\
			<div>\
				<div style="display:inline-block;" class="form-inline">\
					<select v-model="selected" class="form-control">\
						<option v-for="shop in shopList" :value="shop.shopName">{{shop.shopName}}</option>\
					</select>\
					<button class="btn btn-primary" @click="lookup">筛查</button>\
					<button class="btn btn-primary" @click="reset">重置</button>\
				</div>\
				<slot name="myRadio"></slot>\
			</div>\
		',
		props:{
			shopList:{}
		},
		data:function () {
			return {
				selected:''
			}
		},
		methods:{
			lookup:function () {
				bus.$emit('on-selected',this.selected)
			},
			reset:function () {
				bus.$emit('on-reset')
			}
		}

	});


	Vue.component('my-tbody',{
		template:'\
            <tbody>\
                <tr v-if="shop.isDelete==0" v-for="(shop,index) in nowShopList">\
                    <td>{{index}}</td>\
                    <td>{{shop.shopName}}</td>\
                    <td>{{shop.price}}</td>\
                    <td><input type="number" v-model.lazy.number.trim="shop.number"/></td>\
                    <td>{{shop.price*shop.number}}</td>\
                    <td><button class="btn btn-default" @click="add(shop)">+</button>&nbsp<button class="btn btn-default" @click="remove(shop)">-</button></td>\
                </tr>\
            </tbody>\
        ',
		props:{
			shopList:{},
			max:{
				type:Number,
				default:10
			},
			min:{
				type:Number,
				default: 0
			}
		},
		data:function () {
			return{
				nowShopList:this.shopList,
				radioVal:1
			}
		},
		methods:{
			add:function (shop) {
				shop.number=shop.number+this.radioVal;
			},
			remove:function (shop) {
				shop.number=shop.number-this.radioVal;
			}
		},
		watch: {
			nowShopList:{
				handler(val){
					var _this=this;
					val.forEach(function (value,index) {
						if (value.number>_this.max) val[index].number=_this.max;
						if (value.number<_this.min) val[index].number=_this.min;
					});
				},
				deep:true
			}
		},
		mounted:function () {
			var _this=this;
			bus.$on('on-selected',function (val) {
				_this.nowShopList.forEach(function (item,index) {
					item.shopName==val?item.isDelete=0:item.isDelete=1
				})
			})

			bus.$on('on-reset',function (val) {
				_this.nowShopList.forEach(function (item,index) {
					item.isDelete=0
				})
			})

			bus.$on('setRadioVal',function (val) {
				_this.radioVal=val
			})
		}

	});



	Vue.component('my-table',{
		template:'\
            <table>\
                <thead>\
                    <tr>\
                        <th class="col-md-2">序号</th>\
                        <th class="col-md-2">商品</th>\
                        <th class="col-md-2">单价</th>\
                        <th class="col-md-2">数量</th>\
                        <th class="col-md-2">价格</th>\
                        <th class="col-md-2">操作</th>\
                    </tr>\
                </thead>\
                <my-tbody :shop-list="shopList"></my-tbody>\
            </table>\
        ',
		props:{
			shopList:{}
		}
	});



	Vue.component('my-pane',{
		template: '\
            <div class="pane" v-if="show">\
                <slot></slot>\
            </div>\
        ',
		name:'pane',
		props:{
			lable:{},
			name:{}
		},
		data:function(){
			return{
				show:{},
				initial:0
			}
		},
		methods:{
			upDateNav:function () {
				this.$parent.upDateNav();
			}
		},
		mounted:function () {
			this.upDateNav();
		}
	});

	Vue.component('my-tab',{
		template:'\
            <div class="tabClass">\
                <div class="tab-headerClass">\
                    <div :class="tabsClass(item)" v-for="(item,index) in paneList" @click="handerClick(index)">\
                        {{item.lable}}\
                    </div>\
                </div>\
                <div class="tab-contentClass">\
                   <slot></slot>\
                </div>\
            </div>\
        ',
		data:function(){
			return{
				paneList:[],
				currenValue:'',
				initial:0
			}
		},
		methods:{
			getTabs:function(){
				return this.$children.filter(function (item) {
					return item.$options.name==='pane'
				});
			},
			upDateNav:function () {
				var _this=this;
				_this.paneList=[];
				this.getTabs().forEach(function (item,index) {
					_this.paneList.push({
						lable:item.lable,
						name:item.name
					});
					if (index==_this.initial)
						_this.currenValue=item.name;
				});
				this.upDateState();
			},
			upDateState:function () {
				var _this=this;
				this.getTabs().forEach(function (item,index) {
					item.show=_this.currenValue===item.name;
				});
			},
			handerClick:function (index) {
				this.currenValue=this.paneList[index].name;
			},
			tabsClass:function (item) {
				return[
					'tabs-tab',
					{
						'tabs-tab-active': item.name===this.currenValue
					}
				]
			}
		},
		watch:{
			currenValue:function (val) {
				this.upDateState();
			}
		}
	});

	var app=new Vue({
		el:'#app',
		data:{
			shopList:[
				{"shopName":'香蕉',price:10,number:1,isDelete:0},
				{"shopName":'橙子',price:20,number:2,isDelete:0},
				{"shopName":'苹果',price:30,number:3,isDelete:0}
			]
		},
		computed:{
			total:function () {
				var sum=0;
				this.shopList.forEach(function (item,index) {
					if(item.isDelete==0){
						sum+=item.price*item.number
					}
				})
				return sum;
			}
		}
	});
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值