zoukankan      html  css  js  c++  java
  • 微信小程序基础 | 自定义组件 | 11

    创建自定义组件

    自定义组件类似一个页面,一个自定义组件由.json .wxml .wxss .js4个文件组成.
    可以在微信开发者工具中快速创建组件的文件结构

    创建组件文件夹componments,然后这里先创建一个组件Tabs

    关于组件如何使用看后面的案例.

    声明引入自定义组件

    在要使用组件的页面中的page.json中进行应用声明

    {
      "usingComponents": {
        "Tabs": "../../components/Tabs/Tabs"
      }
    }
    

    页面中使用自定义组件

    声明了要引用的组件,就可以直接在page.wxml中使用组件了

    <Tabs></Tabs>
    

    案例: Tabs组件

    首先新建一个页面demo05并置顶显示,编辑app.json如下

    {
      "pages": [
        "pages/demo05/demo05",
        ...
    

    创建components/,并创建组件Tabs

    在要使用的页面中引入组件
    pages/demo05/demo05.json中,编辑代码如下

    {
      "usingComponents": {
        "Tabs": "../../components/Tabs/Tabs"
      }
    }
    

    引入自定义组件之后,就可以在.wxml中直接使用Tabs
    编辑demo05.wxml

    <Tabs></Tabs>
    

    可以看到,现在页面一点效果都没有,接下来就开始对Tabs组件添加功能.

    编辑Components/Tab/Tab.wxml,代码如下

    <view class="tabs">
        <view class="tabs_title">
            <view class="title_item">首页</view>
            <view class="title_item">原创</view>
            <view class="title_item">分类</view>
            <view class="title_item">关于</view>
        </view>
        <view class="tabs_content">内容</view>
    </view>
    

    编辑Components/Tab/Tab.wxss,代码如下

    .tabs {
    }
    .tabs_title {
      display: flex;
      padding: 10rpx 0;
    }
    .title_item {
      flex: 1;
      display: flex;
      justify-content: center;
      align-items: center;
    }
    .tabs_content {
    }
    
    .active {
      color: red;
      border-bottom: 5rpx solid currentColor;
    }
    

    现在开始增加点击激活样式.
    编辑components/Tabs/Tabs.js代码如下

    // components/Tabs/Tabs.js
    Component({
      /**
       * 组件的属性列表
       */
      properties: {},
    
      /**
       * 组件的初始数据
       */
      data: {
        tabs: [
          { id: 0, name: "首页", isActive: true },
          { id: 1, name: "原创", isActive: false },
          { id: 2, name: "分类", isActive: false },
          { id: 3, name: "关于", isActive: false },
        ],
      },
    
      /**
       * 组件的方法列表
       */
      methods: {},
    });
    
    

    编辑components/Tabs/Tabs.wxml代码如下

    <view class="tabs">
        <view class="tabs_title">
            <!-- <view class="title_item">首页</view>
            <view class="title_item">原创</view>
            <view class="title_item">分类</view>
            <view class="title_item">关于</view> -->
            
            <view wx:for="{{tabs}}" wx:key="id" class="title_item {{item.isActive?'active':''}}">
                {{item.name}}        
            </view>
              
    
        </view>
        <view class="tabs_content">内容</view>
    </view>
    

    现在选中效果默认是第一个的,然后开始设置激活选中效果.
    首先给标题绑定一个点击事件,编辑Tabs.wxml代码如下

    bindtap="绑定事件"
    data-xxx="{{item.xx}}"
    
    ...
    <view wx:for="{{tabs}}" wx:key="id" class="title_item {{item.isActive?'active':''}}"  bindtap="handleItemTap" data-id="{{item.id}}" >
        {{item.name}}
    </view>
    ...
    

    编辑Tabs.js代码如下

    ...
      methods: {
        handleItemTap: function (e) {
            // console.log(e);
            const id = e.currentTarget.dataset.id; // 获取id
            let tabs = this.data.tabs; // 获取data中的数组
            // [].forEach 遍历数组,修改了v,也会导致原数组的值修改
            tabs.forEach((v,i)=>i===id?v.isActive=true:v.isActive=false);
    
            // 最后还是要将数据给设置回去
            this.setData({
                tabs:tabs
            })
            
        },
      },
    ...
    

    显示效果如下:

    组件-自定义组件传参

    (1) 父组件通过属性的方式给子组件传递参数
    (2) 子组件通过事件的方式向父组件传递参数
    (3) slot自定义组件中占位符

    父组件向子组件传递参数

    一般父组件就是使用自定义组件的page,子组件也就是自定义组件.

    看回刚刚的案例,刚刚自定义组件的数据不应该写死在自定义组件中,而应该从父组件传递而来,这样自定义组件才能更大程度被其他组件复用. 接下来就修改下刚刚的案例代码.
    首先自定义组件中properties属性来接收父组件传递过来的列表.

    properties: {
    	变量名:{
    		type:变量属性,
    		value:变量默认值 
    	}
    },
    

    Tabs.js中的tabs数组剪切到demo05.js当中.
    然后编辑demo05.wxml,通过自定义属性传递参数给子组件,代码如下,

    <Tabs tabs="{{tabs}}"></Tabs>
    

    demo05.js

    // pages/demo05/demo05.js
    Page({
    
      /**
       * 页面的初始数据
       */
      data: {
        tabs: [
          { id: 0, name: "首页", isActive: true },
          { id: 1, name: "原创", isActive: false },
          { id: 2, name: "分类", isActive: false },
          { id: 3, name: "关于", isActive: false },
        ]
      },
      ...
    

    Tabs.js

    // components/Tabs/Tabs.js
    Component({
      /**
       * 组件的属性列表
       */
      properties: {
          tabs:{
              type:Array,
              value:[]
          }
      },
    
      /**
       * 组件的初始数据
       */
      data: {
    
      },
    
      /**
       * 组件的方法列表
       */
      methods: {
        handleItemTap: function (e) {
            // console.log(e);
            const id = e.currentTarget.dataset.id; // 获取id
            let tabs = this.data.tabs; // 获取data中的数组
            // [].forEach 遍历数组,修改了v,也会导致原数组的值修改
            tabs.forEach((v,i)=>i===id?v.isActive=true:v.isActive=false);
    
            // 最后还是要将数据给设置回去
            this.setData({
                tabs:tabs
            })
            
        },
      },
    });
    
    

    显示效果没有变化

    子组件向父组件传递参数

    但是这里有一个问题,就是指修改了子组件的数据,但是没有修改父组件的数据.
    最后的this.setData({})相当于是把tabs这个修改后的数组给到子组件(原本子组件中的data是没有数组的)

    demo05.js代码如下

    ...
      handleItemChange:function(e){
        // console.log(e);
        
        const id = e.detail; // e.detail获得传递过来的参数
        let tabs = this.data.tabs; // 获取data中的数组
        // [].forEach 遍历数组,修改了v,也会导致原数组的值修改
        tabs.forEach((v,i)=>i===id?v.isActive=true:v.isActive=false);
        // 最后还是要将数据给设置回去
        this.setData({
            tabs:tabs
        });
      }
    ...
    

    demo05.wxml代码如下

    <Tabs tabs="{{tabs}}" binditemChange="handleItemChange" ></Tabs>
    

    Tabs.js代码如下

    // components/Tabs/Tabs.js
    Component({
      /**
       * 组件的属性列表
       */
      properties: {
          tabs:{
              type:Array,
              value:[]
          }
      },
    
      /**
       * 组件的初始数据
       */
      data: {
    
      },
    
      /**
       * 组件的方法列表
       */
      methods: {
        handleItemTap: function (e) {
            const id = e.currentTarget.dataset.id; // 获取id
            this.triggerEvent("itemChange",id); // 自定义组件
        },
      },
    });
    

    slot占位符

    对于自定义组件,<slot>就是占位符,父组件传递什么组件就是什么

    Tabs.wxml代码如下

    ...
        <view class="tabs_content">
            <slot></slot>
        </view>
    ...
    

    demo05.wxml代码如下

    <Tabs tabs="{{tabs}}" binditemChange="handleItemChange" >
        <view wx:if="{{tabs[0].isActive}}">0</view>
        <view wx:elif="{{tabs[1].isActive}}">1</view>
        <view wx:elif="{{tabs[2].isActive}}">2</view>
        <view wx:else>3</view>
    </Tabs>
    

    显示效果如下

  • 相关阅读:
    JSP + JavaBean + Servlet实现MVC设计模式
    编译时提示软件包 javax.servlet.http 不存在 import javax.servlet.http.HttpServletRequest;
    SmartUpload控件 中文乱码问题解决办法
    Exception in thread "main" java.lang.ClassNotFoundException: com.mysql.jdbc.Driver
    Java Web 常用在线api汇总(不定时更新)
    EL函数库
    JSTL格式化标签库
    JSTL核心库
    JSTL标签概述
    iText创建一个含有中文的pdf文档
  • 原文地址:https://www.cnblogs.com/Rowry/p/14305002.html
Copyright © 2011-2022 走看看