微信小程序系列(五):通过面向对象改造自定义组件并讲解外部样式类

上一节,通过讲解JS的原生函数来处理数据问题。

http://www.fcors.com/%e6%8a%80%e6%9c%af%e4%b8%8e%e6%a1%86%e6%9e%b6/%e5%be%ae%e4%bf%a1%e5%b0%8f%e7%a8%8b%e5%ba%8f%e7%b3%bb%e5%88%97%ef%bc%88%e5%9b%9b%ef%bc%89%ef%bc%9a%e5%96%84%e4%ba%8e%e5%88%a9%e7%94%a8%e5%8e%9f%e7%94%9fjs%e6%96%b9%e6%b3%95%e5%a4%84%e7%90%86/

下面将通过面向对象的方式,改造之前的model和home.js的数据绑定方式

创建滚动组件流程

  • 新建component文件夹,命名spu-scroll
  • 创建component,命名为index
  • 在theme.js中,增加数据接入
  • 在home.js引入新的数据
  • component的index.js设置参数
  • home.json 设置引入组件
  • home.wxml 插入组件代码
  • 设置component的index.wxml
  • 设置component的index.json,设置引用价格组件
  • 设置component index.wxss设置css

第一步:创建component, 命名spu-scroll (忽略)

第二步:创建component,命名为index(忽略)

第三步:在theme.js中,增加数据接入

import { Http } from "../../utils/http.js"
import {config} from "../comfig/config.js"
export class Theme{
    static locationA = "t-1"
    static locationE = "t-2"
    static locationF = "t-3"
    static locationH = "t-4"
    themes = []
    async GetThemes(){
        const names = `${Theme.locationA},${Theme.locationE},${Theme.locationF},${Theme.locationH}`;
        const themesData =  await Http.request({
            url:"theme/by/names",
            data:{
                names:names
            }
        })
        this.themes = themesData;
    }
    async getHomelocationA(){
      return this.themes.find(t=>t.name===Theme.locationA);
    }
    async getHomelocationE(){
        return this.themes.find(t=>t.name===Theme.locationE);
    }
    async getHomelocationF(){
        return this.themes.find(t=>t.name===Theme.locationF);
    }
    async getHomelocationH(){
        return this.themes.find(t=>t.name===Theme.locationH);
    }

    /* 静态方法 获取theme及spu*/
    static async getHomeLocationESpu(){
        return Theme.getThemeSpuByName(Theme.locationE);
    }
    static async getThemeSpuByName(name){
        return await Http.request({
            url:`theme/name/${name}/with_spu`
        })
    }

    /* 类的对象方法
        为什么这次用静态呢?
        因为这个是一次性的借口,不需要考虑保存状态
    */
   async getHomeLocationESpu2(){
        return this.getThemeSpuByName(Theme.locationE);
    }
   async getThemeSpuByName2(name){
        return await Http.request({
            url:`theme/name/${name}/with_spu`
        })
    }
    /**
     * 在home.js那里
     * const theme = new Theme()
     * const LocationESpu2 = theme.getHomeLocationESpu2()
     */

}
基础技术、小程序、技术与框架微信小程序系列(五):通过面向对象改造自定义组件并讲解外部样式类插图

上述例子中,分别采用了静态和非静态的方式,这个通过另外一篇文章就讲解static关键字

http://www.fcors.com/%e6%8a%80%e6%9c%af%e4%b8%8e%e6%a1%86%e6%9e%b6/%e9%9d%a2%e7%9b%b8%e5%af%b9%e8%b1%a1%e4%b8%ad%e7%9a%84static%e5%85%b3%e9%94%ae%e5%ad%97/

第四步:在home.js引入新的数据

// pages/home/home.js
import { Banner } from "../model/banner.js";
import { category } from "../model/category.js";
import { Theme  } from "../model/theme.js"
import { Activity  } from "../model/activity.js"
Page({
    /**
     * 页面的初始数据
     */
    data: {
        WebTitle:"Fox_Test",
        topTheme: null,
        themeE:null,
        bannerB:null,
        grid:[],
        activity:null,
        themeESpu:null
    },
    /**
     * 生命周期函数--监听页面加载
     */
    onLoad : async function(){
       this.initAllDate();
    },
    initAllDate: async function(){
            const themes = new Theme();
            await themes.GetThemes();
            const themeA = await themes.getHomelocationA();
            const themeE = await themes.getHomelocationE();
            let themeESpu = [];
            if(themeE.online){
                const data = await Theme.getHomeLocationESpu();
                if(data){
                    /*截取数组0~8个 */
                    themeESpu = data.spu_list.slice(0,8);
                }
            }
            const bannerB =  await Banner.getHomeLocationB();
            const grid =  await category.getGridCategory();
            const activityD =await Activity.getHomeLocationD();
            this.setData({
                activityD:activityD,
                topTheme:themeA,
                themeE:themeE,
                bannerB:bannerB,
                grid:grid,
                themeESpu:themeESpu
                
            })
    }
})

第五步:component的index.js设置参数

// components/sup-scroll/index.js
Component({
    /**
     * 组件的属性列表
     */
    properties: {
        theme:Object,
        spuList:Array
    },

    /**
     * 组件的初始数据
     */
    data: {

    },

    /**
     * 组件的方法列表
     */
    methods: {

    }
})
基础技术、小程序、技术与框架微信小程序系列(五):通过面向对象改造自定义组件并讲解外部样式类插图1

第六步:home.json 设置引入组件

{
  "usingComponents": {
      "s-category-grid":"/components/category-gird/index",
      "s-spu-scroll":"/components/spu-scroll/index"
  }
}
基础技术、小程序、技术与框架微信小程序系列(五):通过面向对象改造自定义组件并讲解外部样式类插图2

第七步:home.wxml 插入组件代码

<s-sup-scroll 
        theme="{{topTheme}}"
        spu-list="{{themeESpu}}"
        wx:if="{{topTheme.online}}">
        
</s-sup-scroll>
基础技术、小程序、技术与框架微信小程序系列(五):通过面向对象改造自定义组件并讲解外部样式类插图3

第八步:设置component的index.wxml

8.1 引入lin-ui的价格组件

在app.json中加入引用【设置全局】(本教程是用全局设置)

也可以在组件的index.json中设置局部引用

{
    "pages": [
        "pages/home/home"
    ],
    "window": {
        "backgroundTextStyle": "light",
        "navigationBarBackgroundColor": "#fff",
        "navigationBarTitleText": "Weixin",
        "navigationBarTextStyle": "black"
    },
    "style": "v2",
    "sitemapLocation": "sitemap.json",
    "usingComponents": {
        "l-grid2":"/miniprogram_npm/lin-ui/grid/index",
        "l-price":"/miniprogram_npm/lin-ui/price/index"
      }
}
基础技术、小程序、技术与框架微信小程序系列(五):通过面向对象改造自定义组件并讲解外部样式类插图4

8.2 设置index.wxml

如果想要小程序里有滚动条,则需要在view中添加scroll-view

小程序变量过长,需要截取如何处理,可以通过wxss或者引入lin-ui的wxx

<!-- 解决变量过长需要截取的问题 引入wxs-->
<wxs src="../../miniprogram_npm/lin-ui/filter/string.wxs" module="stringfilter"></wxs>
<view class="container">
    <image class="title" src="{{theme.title_img}}" ></image>
    <scroll-view scroll-x enable-flex="true" class="scroll-view">
        <block wx:for="{{spuList}}">
            <view class="spu-container">
                <image class="spu-img" src="{{item.img}}"></image>
                <!-- 截取 -->
                <text class="scroll-title">{{item.title.length>=8?stringfilter.substring(item.title,0,7)+'...':item.title}}</text>
                <l-price 
                l-value-class="price-vaule"
                color="#157658"
                value="{{item.price}}"></l-price>
               
            </view>
        </block>
    </scroll-view>
</view>
基础技术、小程序、技术与框架微信小程序系列(五):通过面向对象改造自定义组件并讲解外部样式类插图5

扩展学习:通过wxs编写JavaScript来完成所需要的功能

8.2-1在wxml中引入wxs文件,src:wxs的文件路径,module:定义一个名

然后在标签中直接运行代码。因为lin-ui已经存在这个字符串截取的wxs,所以直接引用即可。后续我们将继续讲解如何重新定义一个wxs并引用。

http://www.fcors.com/%e6%8a%80%e6%9c%af%e4%b8%8e%e6%a1%86%e6%9e%b6/%e5%be%ae%e4%bf%a1%e5%b0%8f%e7%a8%8b%e5%ba%8f%e7%b3%bb%e5%88%97%ef%bc%88%e5%8d%81%ef%bc%89%ef%bc%9awxs%e7%9a%84%e4%bd%bf%e7%94%a8/

8.3、设置index.wxss

/* components/sup-scroll/index.wxss */
.container{
    padding:42rpx 0 34rpx 28rpx;

}
.title{
    width:692rpx;
    height: 90rpx;
}

.price-vaule{
    font-size: 28rpx !important;
}
.spu-img{
    width:160rpx;
    height:160rpx;
}

.spu-container{
    display: flex;
    margin-right:30rpx;
    flex-direction: column;
    align-items: center;
}
.scroll-view{
    margin-top:28rpx;
    display: flex;
    flex-direction: row;
    align-items: center;

}
.scroll-title{
    font-size: 28rpx;
    margin-top:20rpx;

    /*css截取代码*/
    /*c
    width:180rpx;
    text-align: center;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    */
}

执行成功。

基础技术、小程序、技术与框架微信小程序系列(五):通过面向对象改造自定义组件并讲解外部样式类插图6

扩展学习:定义外部样式类l-class,让引入组件的wxss可以修改

用途:外部样式类主要用于修改自定义组件的css样式。如上述例子:需要给自定义的s-spu-scroll组件增加外边距。我们可以通过在组件中定义一个外部样式类,然后在引用组件的home.wxss中重新修改css,特别注意:一般需要增加!important

1、在组件index.js中声明引入外部样式类

// components/sup-scroll/index.js
Component({
    /**
     * 组件的属性列表
     */
    externalClasses:['m-scroll-class'],
    properties: {
        theme:Object,
        spuList:Array
    }
})
基础技术、小程序、技术与框架微信小程序系列(五):通过面向对象改造自定义组件并讲解外部样式类插图7

2、在组件的index.wxml中写明外部样式类作用在哪里

<!-- 解决变量过长需要截取的问题 引入wxs-->
<wxs src="../../miniprogram_npm/lin-ui/filter/string.wxs" module="stringfilter"></wxs>
<view class="container m-scroll-class">
    <image class="title" src="{{theme.title_img}}" ></image>
    <scroll-view scroll-x enable-flex="true" class="scroll-view">
        <block wx:for="{{spuList}}">
            <view class="spu-container">
                <image class="spu-img" src="{{item.img}}"></image>
                <!-- 截取 -->
                <text class="scroll-title">{{item.title.length>=8?stringfilter.substring(item.title,0,7)+'...':item.title}}</text>
                <l-price 
                l-value-class="price-vaule"
                color="#157658"
                value="{{item.price}}"></l-price>
               
            </view>
        </block>
    </scroll-view>
</view>
基础技术、小程序、技术与框架微信小程序系列(五):通过面向对象改造自定义组件并讲解外部样式类插图8

3、在引用组件的地方声明使用此外部样式类,并定义css的名称

<!--pages/home/home.wxml-->
<span>{{WebTitle}}</span>
<view>
    <image class="top-theme" src="{{topTheme.entrance_img}}" ></image>
    <swiper class="swiper"
        indicator-dots="{{true}}"
        indicator-active-color="#157658"
        autoplay="{{true}}"
        circular="{{true}}"
    >
        <block wx:for="{{bannerB.items}}">
            <swiper-item>
                <image class="swiper" src="{{item.img}}"></image>>
            </swiper-item>
        </block>
    </swiper>

    <s-category-grid grid="{{grid}}"></s-category-grid>
    <image class="activityD" src="{{activityD.entrance_img}}"></image>

    <s-spu-scroll 
        m-scroll-class="spu-scroll"
        theme="{{themeE}}"
        spu-list="{{themeESpu}}"
        wx:if="{{topTheme.online}}">
    </s-spu-scroll>
</view>
基础技术、小程序、技术与框架微信小程序系列(五):通过面向对象改造自定义组件并讲解外部样式类插图9

4、修改调用组件页面的wxss即可。

注意:此处某些外部样式不生效,因为没有写!important

.spu-scroll{
    margin-top:50px;
}
基础技术、小程序、技术与框架微信小程序系列(五):通过面向对象改造自定义组件并讲解外部样式类插图10
成功添加外部样式类
成功添加外部样式类

下面继续讲解小程序组件中,数据监听事件。通过数据监听事件,我们可以把API返回的json数据通过JS方式修改好再绑定数据

http://www.fcors.com/%e6%8a%80%e6%9c%af%e4%b8%8e%e6%a1%86%e6%9e%b6/%e5%be%ae%e4%bf%a1%e5%b0%8f%e7%a8%8b%e5%ba%8f%e7%b3%bb%e5%88%97%ef%bc%88%e5%85%ad%ef%bc%89%ef%bc%9a%e4%bd%bf%e7%94%a8%e7%bb%84%e4%bb%b6%e7%9b%91%e5%90%ac%e4%ba%8b%e4%bb%b6%e8%bf%87%e6%bb%a4%e6%95%b0/