[training] wechat applet

Custom components

Component(Object object) | wechat open document (qq.com)

Extract some duplicate code

Commodity classification (taobao.com)

Create custom components

Similar to a page, a custom component consists of four files: json, wxml, wxss, and JS

You can quickly create the component structure in the wechat developer tool

Declare component, import component

tabs.json

{
	"component": true
}

demo01.json

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

Simple edit component

Tabs.wxml

<!--components/Tabs/Tabs.wxml-->
<view class="tabs">
  <view class="tabs_title">
    <view class="title_item active">home page</view>
    <view class="title_item">original</view>
    <view class="title_item">classification</view>
    <view class="title_item">about</view>
  </view>
  <view class="tabs_content">

  </view>
</view>

Tabs.wxss

/* components/Tabs/Tabs.wxss */
.tabs {}

.tabs_title {
  display: flex;
  padding: 10rpx 0;
}

.title_item {
  flex: 1;
  display: flex;
  justify-content: center;
  align-items: center;
}

/* Style when selected */
.active {
  color: #b81d24;
  border-bottom: 5rpx solid currentColor;
}

.tabs_content {}

The above data is written in the wxml of the component. Next, we will implement js dynamic data

Fill in initial data

Tabs.js

// components/Tabs/Tabs.js
Component({
  /**
   * List of properties for the component
   */
  properties: {
  },

  /**
   * Initial data of components
   */
  data: {
    tabs: [
      {
        id: 0,
        name: "home page",
        isActive: true
      },
      {
        id: 1,
        name: "original",
        isActive: false
      }
      ,
      {
        id: 2,
        name: "classification",
        isActive: false
      }
      ,
      {
        id: 3,
        name: "about",
        isActive: false
      }
    ]
  },

  /**
   * Component method list
   */
  methods: {
  }
})

Tab.wxml

<view class="tabs">

  <view class="tabs_title">
    <!-- List rendering -->
    <!-- class Ternary expression in, according to item of isActive Property to determine whether it is selected. If it is selected, the class name is added to display the style -->
    <view wx:for="{{tabs}}" wx:key="id" class="title_item {{item.isActive?'active':''}}">
      {{item.name}}
    </view>
  </view>

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

Bind click event

Tab.wxml

<view class="tabs_title">
  <!-- List rendering -->
  <!-- class Ternary expression in, according to item of isActive Property to determine whether it is selected. If it is selected, the class name is added to display the style -->
  <!-- data-index Custom attribute used to pass the current index value -->
  <view wx:for="{{tabs}}" wx:key="id" class="title_item {{item.isActive?'active':''}}" bindtap="handleItemTap"
    data-index="{{index}}">
    {{item.name}}
  </view>
</view>

Note that the methods for customizing components are written in methods

Tabs.js

methods: {
    handleItemTap(e) {
      // View the location of the index
      console.log(e);

      // 1. Get the clicked index
      // ES6 constant const, read-only and immutable
      // ES6 deconstruction assignment: const {index} = e.currenttarget dataset;
      const index = e.currentTarget.dataset.index;

      // 2. Get the original array
      // ES6 variable let, block level scope
      // ES6 deconstruction assignment: let {tabs} = this data;
      let tabs = this.data.tabs;

      // 3. Circular array: set isActive: true for the current index entry, and false for the rest
      // ES6 arrow function
      tabs.forEach((v, i) => {
        i === index ? v.isActive = true : v.isActive = false
      });

      // Modify data
      this.setData({
        tabs
      })
    }
}

All the above data are written in the component. Next, let's pass the data from the parent to the child

Pass data from parent to child

demo01.wxml

<!-- 
  Parent component demo01,Subcomponents Tabs
  The parent component passes data through label properties
  Subcomponents in properties Medium receiving
-->
<Tabs abc="Data to be transferred"></Tabs>

Tabs.js

properties: {
  // Attribute name
  abc: {
    // Type of data received
    type: String,
    // Default value
    value: ""
  }
},

Tabs.wxml

<!-- amount to data Data in, using{{}}Render -->
<view>{{abc}}</view>

Next, modify the case code

  1. Put the data to be transferred in the data of the parent component, that is, it was originally written in tabs The data in JS data is placed in Demo01 JS in data

    data: {
        tabs: [
          {
            id: 0,
            name: "home page",
            isActive: true
          },
          {
            id: 1,
            name: "original",
            isActive: false
          }
          ,
          {
            id: 2,
            name: "classification",
            isActive: false
          }
          ,
          {
            id: 3,
            name: "about",
            isActive: false
          }
        ]
    },
    
  2. The parent component passes data through label properties

    demo01.wxml

    <Tabs tabs="{{tabs}}"></Tabs>
    
  3. The sub components are received in properties, and the final effect is the same as before

    Tabs.js

    properties: {
      tabs: {
        type: Array,
        value: []
      }
    },
    

Tabs You can modify the parent data component in the app tab window instead of the child data component in the JS window

// this. If no data is found in data, look in properties
let tabs = this.data.tabs;
// Put tabs into data
this.setData({
  tabs
})

Therefore, the processing data needs to be placed in the parent component, and the required index value is passed from the child component to the parent component (the child passes data to the parent)

Transfer data from child to parent

Tabs.js

methods: {
  handleItemTap(e) {
    // 1. Get the clicked index
    const index = e.currentTarget.dataset.index;
    // 2. Trigger custom events in the parent component and transfer data
    this.triggerEvent("itemChange", { index }); //Trigger event ("custom event name", data to be passed)
  }
}

demo01.wxml

<!-- 
  Subcomponents Tabs -> Parent component demo01
  Add a custom event to the label of the subcomponent
  Write parent component js Event method
-->
<Tabs tabs="{{tabs}}" binditemChange="handleItemChange"></Tabs>

demo01.js

// Custom event method
handleItemChange(e) {
  console.log(e);
  // Receive transmitted data
  const index = e.detail.index;
  // The following codes are the same
  let tabs = this.data.tabs;
  tabs.forEach((v, i) => {
    i === index ? v.isActive = true : v.isActive = false
  });
  this.setData({
    tabs
  })
},

You can view it in the AppData window

slot tag

Slot placeholder (slot). The parent component calls the child component to pass some labels to replace the position of the slot

Tabs.wxml

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

demo01.wxml

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

life cycle

application

// app.js
App({
  // Triggered when the application starts for the first time, which can be used to obtain the user's personal information at the beginning
  onLaunch() {
    console.log("onLaunch");
  },

  // Triggered during application display, which can be used to reset page data and page effect
  onShow() {
    console.log("onShow");
    // Can be called multiple times
  },

  // Triggered when hidden is applied, which can be used to pause or clear the timer
  onHide() {
    console.log("onHide");
  },

  // Triggered when the application code reports an error, which can be used to collect error information and send it to the background
  onError(error) {
    console.log("onError");
    console.log(error);
  },

  // Triggered when the application cannot find the entry page for the first time. It can be used for jump
  onPageNotFound() {
    console.log("onPageNotFound");
    wx.navigateTo({
      url: '/pages/demo01/demo01',
    })
  }

})

page

// pages/demo02/demo02.js
Page({

  /**
   * Initial data of the page
   */
  data: {

  },

  /**
   * Life cycle function -- listening for page loading
   * Send asynchronous request initialization page data
   */
  onLoad: function (options) {
    console.log("onLoad");
  },

  /**
   * Life cycle function -- monitor page display
   */
  onShow: function () {
    console.log("onShow");
  },

  /**
   * Life cycle function -- monitor the completion of the first rendering of the page
   */
  onReady: function () {
    console.log("onReady");
  },

  /**
   * Life cycle function -- listening for page hiding
   */
  onHide: function () {
    console.log("onHide");
  },

  /**
   * Life cycle function -- listen for page unloading
   */
  onUnload: function () {
    console.log("onUnload");
  },

  /**
   * Page related event handler -- listen to user drop-down actions
   * Initialize page
   */
  onPullDownRefresh: function () {
    console.log("onPullDownRefresh");
  },

  /**
   * Handler for bottom pull event on page
   * Touch bottom to load more data
   */
  onReachBottom: function () {
    console.log("onReachBottom");
  },

  /**
   * Users click the upper right corner to share
   */
  onShareAppMessage: function () {
    console.log("onShareAppMessage");
  },

  /**
   * Page scrolling
   */
  onPageScroll() {
    console.log("onPageScroll");
  },

  /**
   * Page size change
   */
  onResize() {
    console.log("onResize");
  },

  /**
   * It is currently a tab page. It will be triggered when you click the tab of the current page
   */
  onTabItemTap() {
    console.log("onTabItemTap");
  }
})

},

/**

  • Handler for bottom pull event on page
  • Touch bottom to load more data
    */
    onReachBottom: function () {
    console.log("onReachBottom");
    },

/**

  • Users click the upper right corner to share
    */
    onShareAppMessage: function () {
    console.log("onShareAppMessage");
    },

/**

  • Page scrolling
    */
    onPageScroll() {
    console.log("onPageScroll");
    },

/**

  • Page size change
    */
    onResize() {
    console.log("onResize");
    },

/**

  • It is currently a tab page. It will be triggered when you click the tab of the current page
    */
    onTabItemTap() {
    console.log("onTabItemTap");
    }
    })

Added by wiseone on Sat, 15 Jan 2022 19:02:01 +0200