APICloud AVM框架 封装SKU(商品规格选择)组件

简介: 该SKU组件可实现商品图片与颜色属性进行联动,通过颜色、版本来控制价格,总价通过购买数量与所选商品价格进行自动计算;可进行缺货设定。

 AVM(Application-View-Model)前端组件化开发模式基于标准Web Components组件化思想,提供包含虚拟DOM和Runtime的编程框架avm.js以及多端统一编译工具,完全兼容Web Components标准,同时兼容Vue和React语法糖编写代码,编译工具将Vue和React相关语法糖编译转换为avm.js代码。

基于标准 Web Components 组件化思想,兼容 Vue / React 语法特性,通过一次编码,分别编译为 App、小程序代码,实现多端开发。

 

组件功能介绍

该SKU组件可实现商品图片与颜色属性进行联动,通过颜色、版本来控制价格,总价通过购买数量与所选商品价格进行自动计算;可进行缺货设定。

image.gif编辑

上述功能点是通过商品数据结构和代码逻辑进行配合来实现的。

商品数据结构如下:

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}
        ]}
      ]

image.gif

每个商品的版本有多条数据,每条数据都对应不同的价格,同时会有字段标识是否有货。

每一个商品也会有字段标识是否有货。

当切换商品属性时,需要通过函数进行判断,以保证在商品缺货的情况下,不能被选中。

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;
      }
    }
  }
},

image.gif

示例展示

image.gif编辑

组件开发

组件文件

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>

image.gif

组件使用说明

本组件是基于AVM.js开发的多端组件,通常同时适配Android、iOS、小程序、H5 , 具体支持情况还要看每个组件的说明文档。

首先需要登录开发平台,http://www.apicloud.com。 通过控制平台右上方的模块Store进入,然后选择AVM组件。

image.gif编辑

image.gif编辑

找到对应模块进入,也可通过搜索栏,通过组件名称关键字进行检索。

image.gif编辑

进入模块详情,点击立即下载下载完整的组件安装包。  

image.gif编辑

组件压缩包的文件目录如下

image.gif编辑

也可通过查看模块文档 来了解模块的具体参数,引用的原生模块,注意事项等。

image.gif编辑 具体在项目中的使用步骤是,第一步将压缩文件中的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>

image.gif

如果在AVM组件库中,没有找到实际项目中需要的组件,可以自己尝试封装组件。

这是组件化开发的在线文档地址

image.gif编辑


相关文章
|
4月前
|
SQL 数据采集 人工智能
从结构化样本到品牌指标:提及率、推荐率与解释能力的计算流程
本文详解从AI回答样本到品牌指标的完整数据工程流程,涵盖分母定义、分子识别、权重配置、综合得分计算及质量保障五大环节,聚焦提及率、推荐率与解释能力等核心指标构建逻辑,并提供基于阿里云DataWorks+MaxCompute的可复用落地方案。
|
druid 安全 Java
数据库如何加密连接
数据库如何加密连接
数据库如何加密连接
|
8月前
Copaw browser_use 功能异常 - Playwright 浏览器未正确安装
【Bug报告】Copaw的browser_use功能异常:Playwright Chromium二进制缺失,报错“Executable doesn&#39;t exist”,导致网页抓取、交互、截图及文件操作等功能全部失效,需执行`playwright install`修复。
953 4
|
8月前
|
存储 人工智能 安全
科技云报到:“龙虾”OpenClaw狂欢之下,需要一针清醒剂
《科技云报到》原创深度观察:国产AI智能体OpenClaw(“龙虾”)爆火出圈,国内话题播放超数十亿,成“国民级”现象;但海外却反响寥寥——本质是市场阶段错位:国内填补“能落地AI”空白,硅谷已处红海。其“一键提效”背后实则门槛不低、安全隐忧突出。热潮之下,更需理性审视能力边界与数据风险。(239字)
415 1
|
8月前
|
人工智能 安全 Java
给“氛围编程”系上安全带:阿里集团 AI 代码评审实践与 Benchmark 开源
阿里集团历时一年半、经数万亿Token真实场景打磨,推出AI代码评审助手,实现人机协作新范式:AI接管基础评审,人类聚焦核心风险。联合南京大学开源业界首个支持10语言、具备仓库级上下文感知的CodeReview Benchmark(AACR-Bench),由80+资深工程师多轮交叉标注,显著提升隐性缺陷检出率。
给“氛围编程”系上安全带:阿里集团 AI 代码评审实践与 Benchmark 开源
|
11月前
|
人工智能 安全 搜索推荐
钉钉发布全球首个工作智能操作系统Agent OS,专为AI打造
2025年12月23日,钉钉在杭州发布AI钉钉1.1“木兰”版本,推出全球首个为AI打造的工作智能操作系统——Agent OS,开启“人与AI协同”新范式。通过钉钉ONE、DingTalk Real、AI搜问、悟空Agent及DEAP平台等构建完整AI协作体系,实现AI直连物理世界。发布会推出超20款AI产品,涵盖制造、差旅、客服等场景,全面升级AI表格、AI听记、DingTalk A1,助力企业零门槛迈向AI原生办公。
8368 10
|
12月前
|
新能源 5G 芯片
Ansys Electronics 全流程电磁仿真降本增效,附安装包
Ansys Electronics Suite是Ansys推出的电磁仿真与电子系统设计平台,覆盖芯片、组件到系统级的电磁、热、电路及多物理场耦合仿真,广泛应用于5G、汽车、航天等领域,助力工程师优化设计、提升性能,缩短研发周期,降低开发成本。
984 2
|
6月前
|
机器学习/深度学习 人工智能 芯片
从理论突破到全面应用——迈向通用智能的深度观察
本报告由灵砚智能发布,系统梳理AI从深度学习到通用智能的技术演进,剖析大模型、多模态、智能体等突破;评估其在医疗、金融、制造等行业的深度应用;并直面算力、数据、伦理与全球治理挑战,提供前瞻性的社会适应路径。(239字)
|
9月前
|
JSON 人工智能 机器人
什么是数据集 —— 大模型微调的 “燃料” 核心解析
本文系统解析大模型微调数据集的核心要点:从定义分类(分类/生成/对话/知识/混合类)、标准格式(JSON/JSONL/CSV),到质量五大要求(准确、相关、多样、无冗余、无偏见),再到构建清洗五步法与电商客服实操案例,助开发者夯实微调基础。(239字)
|
11月前
|
Java Maven 数据安全/隐私保护
Nexus仓库
本文介绍Nexus Repository Manager OSS在Linux环境下的安装与配置,包括JDK8安装、Nexus部署、仓库管理、用户权限设置及密码重置方法。支持通过Docker快速部署,并实现数据持久化。同时涵盖Maven、NPM、Docker等组件的私服搭建与资源上传下载配置,助力企业构建高效私有仓库体系。(239字)
887 0