**微信小程序自定义组件Component及Template模板详解**

小程序交流群:609690978

1.template
关于template模板的话,我就长话短说。简单点讲,如果你有多个页面使用的UI布局都是一样的,又没有什么逻辑,比如首页有一个热销商品,商品列表又有个一样的布局,如下图:
在这里插入图片描述
在这里插入图片描述
像这样的,你点击一下就会进入到商品详情页,没有其他任何逻辑,单纯的为了展示,你就可以使用template。
1.新建一个template文件夹,在里面建子文件夹goodList,然后,你只需要写wxml和wxss即可,wxss略,我只展示wxml代码

	<!-- 这个name要注意了,引用模板的时候要对应 -->
    <template name = 'goodList'> 
      <view class='pubile-title hot-box'>
          <view class='hot-item-box'>
            <navigator url="/pages/join/join?id={{item.id}}&type=self" class='hot-item' wx:if="{{hotRecommend != ''}}" wx:for="{{hotRecommend}}" wx:key="{{hotRecommend.id}}">
              <!-- <view class='tip'>已有50人参团</view> -->
              <image  src='{{item.primary_pic_url}}'></image>
              <text>{{item.name}}</text>
              <text>{{item.store_name}}</text>
              <view class='price-box'>
                <text wx:if="{{item.goods_type == 0}}">{{item.retail_price}}积分</text>
                <text wx:else>¥{{item.retail_price}}</text>
                <view class='team'>去参团</view>
              </view>
            </navigator>
          </view>
      </view>
    </template>
<!-- 子页面-->
import '../../template/goodList/goodList.wxml'
<!-- 看到了吧,这个is跟上面的name是对应的 ,然后data就是你子页面js里存放数据的数组-->
<template is="goodList" data="{{goodList}}"></template>

这样一来,一个模板的创建和引用就ok了。

2.Component,自定义组件
首先,我想说,大家或多或少的可能看到别人的代码上有一些不属于html5里的标签(不管是vue还是微信小程序)。但是却能展示相应的页面内容,这是怎么做到的?——Component,自定义组件!

什么是自定义组件呢?说通俗点吧,如果你用过VUE,肯定知道组件化开发。没错,小程序也有组件化开发的概念。第三方ui组件库vant(有赞)就有小程序的组件,这些都是通过Conponent完成的。
比如cell布局,tabbar,tab标签栏,nav导航栏等等,这些很多地方都能用得到的,就叫组件。那组件化有什么好处呢?当时也是为了简化开发,打个简单的比方,例如导航栏,也就是页面头部。你总不可能我有100个页面就写100个头吧,额……你可以复制粘贴,但是,这不是我们要的效果,可能我导航A上面有张图,导航B上面没有,这样的话你就得改!!!即使都一样,你每个复制粘贴,麻烦不麻烦,代码多不多。看着就很low对吧。怎么让我们的代码变得有逼格一点呢?使用Component自定义组件吧,你可能看过其相关的文档:https://developers.weixin.qq.com/miniprogram/dev/reference/api/Component.html,很无语对吧,腾讯的文档似乎就是为了不让开发者看懂。各种含糊,不管它,下面我将引导大家如何去使用。

first,可能有人要问我了,看了我的描述感觉componet和template一样都是公用的,却要分开讲,有什么区别?这也是我要告诉大家的,我在上文讲template的时候,反复强调了一句话“如果你有多个页面使用的UI布局都是一样的,又没有什么逻辑,你就可以使用template。”而两者的区别在于:component功能更加强大,可以包含几乎任何逻辑操作,也就是说,你要给其某个元素添加点击事件,或者取input的值,都是可以的。而template则不行

好了,唠叨了这么多,正式开始。(CSS略)

1.新建一个components文件夹。用来存放你的自定义组件,我这里写一个自定义的头部导航组件。功能如下:
在这里插入图片描述
效果一:
在这里插入图片描述
效果2:
在这里插入图片描述

2.wxml

<view
  class="custom-class chenqian-nav-bar {{ border ? 'chenqian-hairline--bottom' : '' }} {{ fixed ? 'chenqian-nav-bar--fixed' : '' }}"
  style="z-index: {{ zIndex }}"
>
  <!-- 左侧 -->
  <view class="chenqian-nav-bar__left" bind:tap="onClickLeft"><!-- 左侧点击事件-->
  <!-- 如果leftArrow或leftText 不为空,则显示下面的东西,简单点说就是左侧有东西就展示,没有就不展示
	展示的东西可以是图标,也可以是文字,也可以两个都展示,因为它们都各自做了非空判断
	-->
    <block wx:if="{{ leftArrow || leftText }}">
      <van-icon
        wx:if="{{ leftArrow }}"
        size="16px"
        name="arrow-left"
        custom-class="chenqian-nav-bar__arrow"
      />
      <view
        wx:if="{{ leftText }}"
        class="chenqian-nav-bar__text"
        hover-class="chenqian-nav-bar__text--hover"
        hover-stay-time="70"
      >{{ leftText }}</view>
    </block>
    <slot wx:else name="left" />
  </view>

  <!-- 标题 -->
  <view class="chenqian-nav-bar__title title-class chenqian-ellipsis" bind:tap="onChange">
    <!-- 中间的标题,可以是标题文字,也可以是标题+图标,图标我写死了,是个箭头。这里给图标做了个效果,点击的时候会旋转,
    同时拉起下拉框
	-->
    <block wx:if="{{ title }}" >{{ title }}
      <image src='/static/images/jiantou@2x.png' wx:if="{{titleArrow}}" class="{{ titleArrowRotate?'chenqian-change-icon chenqian-change-icon-rotate':'chenqian-change-icon'}}"></image>
    </block>
    <slot wx:else name="title" />
  </view>

	    <!-- 这个右侧的东西和左侧基本一致,只是它可以展示多个图标而不展示文字,我上面的api文档里有说明
	-->
  <view class="chenqian-nav-bar__right" >
    <block wx:if="{{rightText }}" >
      <view class='chenqian-right-img'><slot name="right-img"/></view>
      <view bind:tap="onClickRight"
        wx:if="{{ rightText }}"
        class="chenqian-nav-bar__text"
        hover-class="chenqian-nav-bar__text--hover"
        hover-stay-time="70"
      >{{ rightText }}</view>
    </block>
    
    <block wx:else>
      <view  class="{{rightText ? 'chenqian-right-img':'chenqian-right-img chenqian-right'}}" >
      	<slot  name="right"></slot>
      </view>
    </block>
  </view>
</view>

<!--代码中除了slot可能大部分代码对于各位都能看懂。关于solt这东西,文档还比较清晰:https://developers.weixin.qq.com/miniprogram/dev/framework/custom-component/wxml-wxss.html#%E7%BB%84%E4%BB%B6wxml%E7%9A%84slot-->

然后是js,和子页面的js不一样,这里是原生的,下面我还会教大家怎么改成类似于vue那样的写法。

原生:


Component({
  options: {
    multipleSlots: true // 在组件定义时的选项中启用多slot支持
  },
  properties: {//类似于子页面的data,都是wxml里需要的数据,也类似于vue的props
    list: Array,
    title: String,
    fixed: Boolean,
    leftText: String,
    rightText: String,
    leftArrow: Boolean,
    titleArrow:Boolean,
    titleArrowRotate:Boolean,
    border: {
       type: Boolean,
       value: true
    },
    zIndex: {
       type: Number,
       value: 1
     }
  },

  /**
   * 组件的方法列表
   */
    methods: { //这个很熟悉吧,vue里有
        onClickLeft: function onClickLeft(event) {
	      this.triggerEvent('onClickLeft',event);   
	    },
	    onClickRight: function onClickRight(event) {
	      this.triggerEvent('onClickRight',event);   
	    },
	    onChange: function onChange(event) {
	      this.triggerEvent('onChange',event);   
	    },
	    //看着很懵逼吧,其实只需要理解一点,triggerEvent括号后面的,是你自定义的事件名,在子页面用bind:事件名=“函数名”的格式去调用它,就能触发组件功能
    }
})

然后,我们在子页面的json文件里,写进组件:

  "usingComponents": {
    "chenqian-nav": "../../components/navBar/navBar"
  },

接着,在wxml里写:

    <chenqian-nav 
	    custom-class="myNav" 
	    wx:if="{{!showSearch}}" 
	    title="{{title}}" 
	    title-arrow 
	    title-arrow-rotate="{{showSelect}}" 
	    bind:click-change="openSelect"     
	    bind:click-left="onClickLeft"  
	    bind:click-scan="scan">
      <view slot="right">
        <image src='/static/images/add.png' catchtap='showMenu'></image>
        <van-icon  name="search"  size="40rpx"  catchtap='openSearch'/>
      </view>
    </chenqian-nav>

标签已自己的名字来命名或者其他方式命名就很有逼格了吧!一般都是拿自己名字命名的,不然联合开发的时候别人不知道这是谁的组件。

至此,一个组件就完成了。

刚才我说了,我还会教大家怎么仿VUE的组件去操作:

import { ChenQianComponent } from '../common/component';
ChenQianComponent({
    classes: ['title-class'],
    props: {
        title: String,
        fixed: Boolean,
        leftText: String,
        rightText: String,
        leftArrow: Boolean,
        titleArrow:Boolean,
        titleArrowRotate:Boolean,
        border: {
            type: Boolean,
            value: true
        },
        zIndex: {
            type: Number,
            value: 1
        }
    },
    methods: {
        onClickLeft() {
            this.$emit('click-left');
        },
        onClickRight() {
            this.$emit('click-right');
        },
        onChange(){
          this.$emit('click-change')
        }
    }
});

看到了吧,props和$emit,使用VUE的同学应该很熟悉。而且Component这个对象也被我改成了ChenQianComponent,但是要引入对应的声明文件。因为东西有点多,我就不发了,需要的同学可以加我的微信群找我要:609690978。谢谢大家支持

小程序交流群:609690978

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值