AVM(Application-View-Model)前端组件化开发模式基于规范 Web Components 组件化思维,提供蕴含虚构 DOM 和 Runtime 的编程框架 avm.js 以及多端对立编译工具,齐全兼容 Web Components 规范,同时兼容 Vue 和 React 语法糖编写代码,编译工具将 Vue 和 React 相干语法糖编译转换为 avm.js 代码。
基于规范 Web Components 组件化思维,兼容 Vue / React 语法个性,通过一次编码,别离编译为 App、小程序代码,实现多端开发。
组件性能介绍
该 SKU 组件可实现商品图片与色彩属性进行联动,通过色彩、版本来管制价格,总价通过购买数量与所选商品价格进行主动计算;可进行缺货设定。
上述性能点是通过商品数据结构和代码逻辑进行配合来实现的。
商品数据结构如下:
goodsList:[
{id:'100016015112',
image:'https://m.360buyimg.com/mobilecms/s750x750_jfs/t1/210630/17/8651/208682/618a5bd6Eddc8ea0e/b5e55e1a03bc0126.jpg!q80.dpg.web',
color:'亮彩色',
status:true,
guige:[{label:'8G+128G',price:'3999',status:false},
{label:'8G+256G',price:'5999',status:true},
{label:'16G+512G',price:'6999',status:true},
{label:'16G+1024G',price:'9999',status:false}
]},
{id:'100016015113',
image:'https://img14.360buyimg.com/n4/jfs/t1/216079/14/3895/201095/618a5c0cEe0b9e2ba/cf5b98fb6128a09e.jpg',
color:'釉红色',
status:true,
guige:[{label:'8G+128G',price:'3799',status:true},
{label:'8G+256G',price:'5799',status:true},
{label:'16G+512G',price:'6799',status:true},
{label:'16G+1024G',price:'9799',status:false}
]},
{id:'100016015132',
image:'https://img14.360buyimg.com/n4/jfs/t1/215845/12/3788/221990/618a5c4dEc71cb4c7/7bd6eb8d17830991.jpg',
color:'秘银色',
status:true,
guige:[{label:'8G+128G',price:'3599',status:true},
{label:'8G+256G',price:'5599',status:true},
{label:'16G+512G',price:'6599',status:true},
{label:'16G+1024G',price:'9599',status:false}
]},
{id:'200016015117',
image:'https://img14.360buyimg.com/n4/jfs/t1/203247/8/14659/237368/618a5c87Ecc968774/b0bb25331e5e2d1a.jpg',
color:'夏日胡杨',
status:false,
guige:[{label:'8G+128G',price:'3899',status:false},
{label:'8G+256G',price:'5899',status:false},
{label:'16G+512G',price:'6899',status:false},
{label:'16G+1024G',price:'9899',status:false}
]},
{id:'100013415456',
image:'https://img14.360buyimg.com/n4/jfs/t1/160950/40/25098/234168/618a5cb9E65ba975e/7f8f93ea7767a51b.jpg',
color:'冬日暖阳',
status:true,
guige:[{label:'8G+128G',price:'3199',status:true},
{label:'8G+256G',price:'5199',status:true},
{label:'16G+512G',price:'6199',status:true},
{label:'16G+1024G',price:'9199',status:false}
]}
]
每个商品的版本有多条数据,每条数据都对应不同的价格,同时会有字段标识是否有货。
每一个商品也会有字段标识是否有货。
当切换商品属性时,须要通过函数进行判断,以保障在商品缺货的状况下,不能被选中。
setGoods(e){
// console.log(JSON.stringify(e));
let item = e.currentTarget.dataset.item;
if(item.status){
this.data.selectGoods = item;
this.data.guigeList = item.guige;
for (let index = 0; index < item.guige.length; index++) {const element = item.guige[index];
// 保障默认选中的商品是有货的
if(element.status){
this.data.selectGuige = element;
break;
}
}
}
},
示例展现
组件开发
组件文件
easy-sku.stml
<template>
<view class="easy-sku_container">
<view class="easy-sku_box">
<view class="easy-sku_base">
<view class="easy-sku_base-pic-box">
<image class="easy-sku_base-pic" src={selectGoods.image} mode="widthFix"></image>
</view>
<view class="easy-sku_base-info">
<text class="easy-sku_base-info-price">¥{selectGuige.price?selectGuige.price*count:0}</text>
<text class="easy-sku_base-info-num"> 商品编号:{selectGoods.id}</text>
</view>
<view class="easy-sku_close-box" @click="cancel">
<image class="easy-sku_close-ico" src={ico_close} mode="widthFix"></image>
</view>
</view>
<scroll-view class="easy-sku_scroll-box" scroll-y>
<view class="easy-sku_guige-box">
<view class="easy-sku_guige-title">
<text class="easy-sku_guige-title-label"> 色彩 </text>
</view>
<view class="easy-sku_guige-item-box">
<view :class="selectGoods.id==item.id?'easy-sku_guige-item--select':'easy-sku_guige-item--default'"v-for="(item,index) in goodsList"data-item={item} @click="setGoods">
<text :class="selectGoods.id==item.id?'easy-sku_guige-item-label-select':item.status?'easy-sku_guige-item-label--default':'easy-sku_guige-item-label-disable'">{item.color}</text>
</view>
</view>
</view>
<view class="easy-sku_guige-box">
<view class="easy-sku_guige-title">
<text class="easy-sku_guige-title-label"> 版本 </text>
</view>
<view class="easy-sku_guige-item-box">
<view :class="selectGuige.label==item.label?'easy-sku_guige-item--select':'easy-sku_guige-item--default'"v-for="(item,index) in guigeList"data-item={item} @click="setGuige">
<text :class="selectGuige.label==item.label?'easy-sku_guige-item-label-select':item.status?'easy-sku_guige-item-label--default':'easy-sku_guige-item-label-disable'">{item.label}</text>
</view>
</view>
</view>
<view class="easy-sku_count-box">
<text class="easy-sku_count-label"> 购买数量 </text>
<view class="easy-sku_count-result-tool">
<text :class="count>0?'easy-sku_count-result-item':'easy-sku_count-result-item--disable'"@click="countDel">-</text>
<input class="easy-sku_count-result-input" placeholder=""keyboard-type="number"v-model="count"/>
<text class="easy-sku_count-result-item" @click="countAdd">+</text>
</view>
</view>
</scroll-view>
<view class="easy-sku_bottom">
<button class="easy-sku_btn" @click="submit"> 确认 </button>
</view>
<safe-area></safe-area>
</view>
</view>
</template>
<script>
export default {
name: 'easy-sku',
installed(){this.data.selectGoods=this.props.goodsList[0];
// this.data.selectGuige=this.props.goodsList[0].guige[1];
this.data.guigeList = this.props.goodsList[0].guige;
},
props:{goodsList:Array,},
data() {
return{
ico_close:'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAUCAYAAACNiR0NAAAAjUlEQVR42mNgGNlg1qxZbTNnzrxFgvqnQJyLUwHQsKtA/B+InxEyDKjmI0gt0MD9hBQ+ImQozDAgvkyUV/AZSrJh+Awl2zBshlJsGBZDKTcMmjR+Ihn4kVqGHQS5jiJDkQ1D8j55hmIzjGxD8RlGsqFABe8IGYbF0Pv4FAUAXbiIhCS1ac6cOXYjvEwFAL7uy3s7L72GAAAAAElFTkSuQmCC',
selectGoods:{},
selectGuige:{},
count:1,
guigeList:[]}
},
methods: {setGoods(e){// console.log(JSON.stringify(e));
let item = e.currentTarget.dataset.item;
if(item.status){
this.data.selectGoods = item;
this.data.guigeList = item.guige;
for (let index = 0; index < item.guige.length; index++) {const element = item.guige[index];
if(element.status){
this.data.selectGuige = element;
break;
}
}
}
},
setGuige(e){// console.log(JSON.stringify(e));
let item = e.currentTarget.dataset.item;
if(item.status){this.data.selectGuige = item;}
},
countAdd(){this.data.count++;},
countDel(){if(this.data.count>0){this.data.count--;}
},
cancel(){this.fire('cancel','');
},
submit(){this.fire('submit',{goods:this.data.selectGoods,guige:this.data.selectGuige,count:this.data.count});
}
}
}
</script>
<style>
.easy-sku_container {
position: absolute;
height: 100%;
width: 100%;
background-color: rgba(0,0,0,0.1);
}
.easy-sku_box{
align-items: center;
justify-content: space-between;
position: absolute;
bottom: 0;
width: 100%;
height: 70%;
background-color: #ffffff;
border-top-left-radius: 30px;
border-top-right-radius: 30px;
padding: 15px;
}
.easy-sku_base{
width: 100%;
padding: 15px;
}
.easy-sku_base-pic{
width: 80px;
height: 80px;
}
.easy-sku_base{
flex-flow: row nowrap;
justify-content: space-between;
align-items: flex-end;
}
.easy-sku_base-info{
flex: 1;
padding-left: 10px;
}
.easy-sku_base-info-price{
color: #fa2c19;
font-size: 16px;
}
.easy-sku_base-info-num{
color: #666666;
font-size: 12px;
}
.easy-sku_close-box{height: 100%;}
.easy-sku_close-ico{width: 20px;}
.easy-sku_scroll-box{
width: 100%;
flex: 1;
}
.easy-sku_guige-box{width: 100%;}
.easy-sku_guige-title{padding: 10px 0;}
.easy-sku_guige-title-label{
font-size: 16px;
font-weight: bolder;
}
.easy-sku_guige-item-box{
flex-flow: row wrap;
justify-content: flex-start;
align-items: center;
}
.easy-sku_guige-item--default{
background-color: #f2f2f2;
border: 0.5px solid #f2f2f2;
border-radius: 18px;
padding: 8px 18px;
margin-right: 10px;
margin-bottom: 10px;
}
.easy-sku_guige-item-label--default{
font-size: 14px;
color: #333333;
}
.easy-sku_guige-item--select{
background-color: #fee0dd;
border: 0.5px solid #fa2c19;
border-radius: 18px;
padding: 8px 18px;
margin-right: 10px;
margin-bottom: 10px;
}
.easy-sku_guige-item-label-select{
font-size: 14px;
color: #fa2c19;
}
.easy-sku_guige-item-label-disable{
font-size: 14px;
color: #b5b5b5;
/* text-decoration: line-through; */
}
.easy-sku_count-box{
width: 100%;
flex-flow: row nowrap;
justify-content: space-between;
align-items: center;
margin-top: 10px;
}
.easy-sku_count-result-tool{
flex-flow: row nowrap;
justify-content: space-between;
align-items: center;
}
.easy-sku_count-result-item{
font-size: 25px;
padding: 0 5px;
color: #333333;
}
.easy-sku_count-result-item--disable{
font-size: 25px;
padding: 0 5px;
color: #b5b5b5;
}
.easy-sku_count-result-input{
background-color: #f0f0f0;
border: 0;
height: 18px;
width: 40px;
text-align: center;
border-radius: 5px;
}
.easy-sku_count-label{
font-size: 16px;
color: #333333;
}
.easy-sku_bottom{width: 100%;}
.easy-sku_btn{
background-color: #fa2c19;
border-radius: 21px;
font-size: 15px;
color: #fff;
padding: 10px;
}
</style>
组件应用阐明
本组件是基于 AVM.js 开发的多端组件,通常同时适配 Android、iOS、小程序、H5 , 具体反对状况还要看每个组件的阐明文档。
首先须要登录开发平台,http://www.apicloud.com。通过管制平台右上方的模块 Store 进入,而后抉择 AVM 组件。
找到对应模块进入,也可通过搜寻栏,通过组件名称关键字进行检索。
进入模块详情,点击立刻下载下载残缺的组件安装包。
组件压缩包的文件目录如下
也可通过查看模块文档 来理解模块的具体参数,援用的原生模块,注意事项等。
具体在我的项目中的应用步骤是,第一步将压缩文件中的 easy-sku.stml 文件拷贝到我的项目的 components 目录,通过浏览 readme.md 文档和查看 demo 示例文件 demo-easy-sku.stml 在须要开发的 stml 文件中,引入组件文件,实现页面的开发。
demo-easy-sku.stml
<template>
<view class="page">
<safe-area></safe-area>
<view class="item" @click="openSKU">
<text> 抉择商品 </text>
</view>
<easy-sku
oncancel="closeSKU"
onsubmit="getSKU"
:goodsList="goodsList"
v-if="isShow"
>
</easy-sku>
</view>
</template>
<script>
import '../../components/easy-sku.stml'
export default {
name: 'demo-easy-sku',
apiready(){//like created},
data() {
return{
isShow:false,
goodsList:[
{id:'100016015112',
image:'https://m.360buyimg.com/mobilecms/s750x750_jfs/t1/210630/17/8651/208682/618a5bd6Eddc8ea0e/b5e55e1a03bc0126.jpg!q80.dpg.web',
color:'亮彩色',
status:true,
guige:[{label:'8G+128G',price:'3999',status:false},
{label:'8G+256G',price:'5999',status:true},
{label:'16G+512G',price:'6999',status:true},
{label:'16G+1024G',price:'9999',status:false}
]},
{id:'100016015113',
image:'https://img14.360buyimg.com/n4/jfs/t1/216079/14/3895/201095/618a5c0cEe0b9e2ba/cf5b98fb6128a09e.jpg',
color:'釉红色',
status:true,
guige:[{label:'8G+128G',price:'3799',status:true},
{label:'8G+256G',price:'5799',status:true},
{label:'16G+512G',price:'6799',status:true},
{label:'16G+1024G',price:'9799',status:false}
]},
{id:'100016015132',
image:'https://img14.360buyimg.com/n4/jfs/t1/215845/12/3788/221990/618a5c4dEc71cb4c7/7bd6eb8d17830991.jpg',
color:'秘银色',
status:true,guige:[{label:'8G+128G',price:'3599',status:true},
{label:'8G+256G',price:'5599',status:true},
{label:'16G+512G',price:'6599',status:true},
{label:'16G+1024G',price:'9599',status:false}
]},
{id:'200016015117',
image:'https://img14.360buyimg.com/n4/jfs/t1/203247/8/14659/237368/618a5c87Ecc968774/b0bb25331e5e2d1a.jpg',
color:'夏日胡杨',status:false,
guige:[{label:'8G+128G',price:'3899',status:false},
{label:'8G+256G',price:'5899',status:false},
{label:'16G+512G',price:'6899',status:false},
{label:'16G+1024G',price:'9899',status:false}
]},
{id:'100013415456',
image:'https://img14.360buyimg.com/n4/jfs/t1/160950/40/25098/234168/618a5cb9E65ba975e/7f8f93ea7767a51b.jpg',
color:'冬日暖阳',
status:true,guige:[{label:'8G+128G',price:'3199',status:true},
{label:'8G+256G',price:'5199',status:true},
{label:'16G+512G',price:'6199',status:true},
{label:'16G+1024G',price:'9199',status:false}
]}
],
}
},
methods: {openSKU(){this.data.isShow=true;},
closeSKU(){this.data.isShow=false;},
getSKU(e){console.log(JSON.stringify(e));
api.toast({
msg:'色彩:'+e.detail.goods.color+'/ 规格:'+e.detail.guige.label+'/ 数量:'+e.detail.count+'/ 总价:'+e.detail.count*e.detail.guige.price,
location:'middle'
})
this.data.isShow = false;
}
}
}
</script>
<style>
.page {
height: 100%;
background-color: #f6f6f6;
}
.item{
background-color: #ffffff;
margin: 15px;
padding: 15px;
border-radius: 5px;
}
</style>
如果在 AVM 组件库中,没有找到理论我的项目中须要的组件,能够本人尝试封装组件。
这是组件化开发的在线文档地址