Note: If the running result of the developer tool is inconsistent with the running result of the real machine, please refer to the debugging operation of the real machine.

Learning Content

❣️ Basic TYML, TYSS, and related syntax of Smart MiniApp.

❣️ Smart MiniApp page, component, combination development.

❣️ Introduction and usage of some APIs.

❣️ The built-in Smart MiniApp extension capability is supplemented, including theme adaptation, multi-language, etc.

❣️ Other extension capabilities, including component library, gesture library, chart library, animation library, etc.

Project Structure

├── project.tuya.json
├── app.js
├── app.json
├── app.tyss
├── assets
│ └── images
│ └── tab
│ └─ component.png
├── i18n
│ └── strings.json
├── components
│ └── foo
│ ├── index.js
│ ├── index.json
│ ├── index.tyml
│   └── index.tyss
├── pages
│ └── page
│ ├── index.js
│ ├── index.json
│ ├── index.tyml
│   └── index.tyss
├── theme.json
├── package.json
└── node_modules

1. Data binding

<!--tyml-->
<view> {{message}} </view>
// page.js
Page({
  data: {
    message: "Hello MINA!",
  },
});

2. List rendering

<!--tyml-->
<view ty:for="{{array}}"> {{item}} </view>
// page.js
Page({
  data: {
    array: [1, 2, 3, 4, 5],
  },
});

3. Conditional rendering

<!--tyml-->
<view ty:if="{{view == 'WEBVIEW'}}"> WEBVIEW </view>
<view ty:elif="{{view == 'APP'}}"> APP </view>
<view ty:else="{{view == 'MINA'}}"> MINA </view>
// page.js
Page({
  data: {
    view: "MINA",
  },
});

4. Template

<!--tyml-->
<template name="staffName">
  <view>
    FirstName: {{firstName}}, LastName: {{lastName}}
  </view>
</template>

<template is="staffName" data="{{...staffA}}"></template>
<template is="staffName" data="{{...staffB}}"></template>
<template is="staffName" data="{{...staffC}}"></template>
// page.js
Page({
  data: {
    staffA: { firstName: "Hulk", lastName: "Hu" },
    staffB: { firstName: "Shang", lastName: "You" },
    staffC: { firstName: "Gideon", lastName: "Lin" },
  },
});

##Apps

Register the Miniapp. Accepts an Object parameter, which specifies the Miniapp's lifecycle callback, etc.

App() ** must be called in ** app.js **, must be called and can only be called once. Otherwise, unexpected effects will occur. **

1. Lifecycle

Sample code

App({
  onLaunch(options) {
    // Do something initial when launch.
  },
  onShow(options) {
    // Do something when show.
  },
  onHide() {
    // Do something when hide.
  },
  onError(msg) {
    console.log(msg);
  },
  globalData: "I am global data",
});

2. getApp

Sample code

//other.js
var appInstance = getApp();
console.log(appInstance.globalData); // I am global data

##Page

1.data

data is the initial data used by the first render of the page.

Sample code

<view>{{text}}</view>
<view>{{array[0].msg}}</view>
Page({
  data: {
    text: "init data",
    array: [{ msg: "1" }, { msg: "2" }],
  },
});

2. Event binding

Sample code

<view bind:tap="viewTap">{{num}}</view>

Page({
  data: {
    num: 0,
  },
  viewTap: function () {
    this.setData({
      num: this.data.num + 1,
    });
  },
});

3. Lifecycle

4. Page event handler

Sample code

//index.js
Page({
  data: {
    text: "This is page data.",
  },
  onLoad: function (options) {
    // Do some initialize when page load.
  },
  onShow: function () {
    // Do something when page show.
  },
  onReady: function () {
    // Do something when page ready.
  },
  onHide: function () {
    // Do something when page hide.
  },
  onUnload: function () {
    // Do something when page close.
  },
  onPullDownRefresh: function () {
    // Do something when pull down.
  },
  onReachBottom: function () {
    // Do something when page reach bottom.
  },
});
// file /components/foo/index.js
Component({
  options: Object,
  properties: Object,
  observers: Object,
  data: Object,
  methods: Object,
  behaviors: Array,
  lifetimes: Object,
  pageLifetimes: Object,
  relations: Array,
});

1.properties

Sample code

Component({
  properties: {
    myName: {
      type: String,
      value: "smart",
      observer: function (newValue, oldValue) {
        // do something
      },
    },
  },
});

2.observers

Component({
  observers: {
    "value1, value2": function (value1, value2) {
      // trigger when this.setData corresponds to data
    },
    "some.subfield": function (subfield) {
      // Triggered when this.data.some.subfield is set using setData
      // (Other than that, setting this.data.some with setData will also fire)
      subfield === this.data.some.subfield;
    },
    "arr[12]": function (arr12) {
      // Triggered when this.data.arr[12] is set using setData
      // (Other than that, setting this.data.arr with setData will also fire)
      arr12 === this.data.arr[12];
    },
    "some.field.**": function (field) {
      // Triggered when this.data.some.field itself or any sub-data fields under it are set using setData
      // (Other than that, setting this.data.some with setData will also fire)
      field === this.data.some.field;
    },
    "**": function () {
      // every time setData fires
    },
  },
});

3.data

<view>{{name}}: {{age}}</view>
Component({
  properties: {
    'name': {
      type: String,
      value: 'smart'
    }
  }
  data: { age: 18 },
});

4. Lifecycle

lifetimes

Sample code

Component({
  lifetimes: {
    attached: function () {
      // Executed when the component instance enters the page node tree
    },
  },
});

pageLifetimes

Sample code

Component({
  pageLifetimes: {
    show: function () {
      // Executed when the page where the component is located is displayed
    },
  },
});

5. Component page communication

There are two common communication methods between components.

Listen for events

<!-- When the custom component triggers the "myevent" event, the "onMyEvent" method is called -->
<component-tag-name bind:myevent="onMyEvent" />
Page({
  onMyEvent: function (e) {
    e.detail; // The detail object provided when the custom component triggers the event
  },
});

trigger event

<!-- in custom component -->
<button bind:tap="onTap">Clicking this button will trigger the "myevent" event</button>
Component({
  properties: {},
  methods: {
    onTap: function () {
      var myEventDetail = {}; // detail object, provided to the event listener function
      var myEventOption = {}; // option to trigger event
      this.triggerEvent("myevent", myEventDetail, myEventOption);
    },
  },
});

6. slot

<!-- Component template -->
<view class="wrapper">
  <slot name="before"></slot>
  <view>here are the internal details of the component</view>
  <slot name="after"></slot>
</view>
<!-- The page template of the referenced component -->
<view>
  <component-tag-name>
    <!-- This part of the content will be placed in the position of the component <slot name="before"> -->
    <view slot="before">here is the content inserted into the component slot name="before"</view>
    <!-- This part of the content will be placed in the position of the component <slot name="after"> -->
    <view slot="after">here is the content inserted into the component slot name="after"</view>
  </component-tag-name>
</view>

7. Style isolation

Component({
  options: {
    styleIsolation: "isolated",
  },
});

styleIsolation value

Sample code

<!-- component custom-component.tyml -->
<text class="red-text">The color of this text is determined by the style definitions in `app.tyss` and the page `tyss`</text>
/* app.tyss */
.red-text {
  color: red;
}
/* component custom-component.js */
Component({
  options: {
    addGlobalClass: true,
  },
});

1. Routing behavior

2. Routing parameters

Sample code

ty.navigateTo({
  url: 'test?id=1',
  events: {
    // Add a listener for the specified event to get the data sent from the opened page to the current page
    acceptDataFromOpenedPage: function(data) {
      console.log(data)
    },
    someEvent: function(data) {
      console.log(data)
    }
    ...
  },
  success: function(res) {
    // Send data to the opened page through eventChannel
    res.eventChannel.emit('acceptDataFromOpenerPage', { data: 'test' })
  }
})
//test.js
Page({
  onLoad: function (option) {
    console.log(option.query);
    const eventChannel = this.getOpenerEventChannel();
    eventChannel.emit("acceptDataFromOpenedPage", { data: "test" });
    eventChannel.emit("someEvent", { data: "test" });
    // Listen to the acceptDataFromOpenerPage event, and get the data sent from the previous page to the current page through eventChannel
    eventChannel.on("acceptDataFromOpenerPage", function (data) {
      console.log(data);
    });
  },
});

1. JSAPI

The API provided by the basic library, including basic/application-level events, interface animation related, map, audio and video, canvas, interface and other capabilities. View more.

2. TTT

Note: To use some API, such as navigateTo, showToast, showModal, you need to integrate the corresponding Kit plugin capability.

The multi-language Smart MiniApp has been integrated into the framework, and there is no need to introduce additional packages or methods.

Instructions

Multilingual key values ​​need to be added in the Mini Program Developer Platform. After selecting the corresponding Mini Program, click Multilingual Management on the sidebar.

Code writing

<text>{{I18n.t('TYTimer_day2')}}</text>
<text>{{i18n.t('TYTimer_day2')}}</text>
console.log(I18n.t("TYTimer_day2"));
console.log(i18n.t("TYTimer_day2"));

View more notes

1. Extended component library

how to use

// index.json
"usingComponents": {
    "mpdialog": "@tuya-miniapp/miniapp-components-plus/dialog/index"
  }
<mpdialog title="test" show="{{true}}" bind:buttontap="tapDialogButton" buttons="{{[{text: 'Cancel'}, {text: 'Confirm'}]}}">
    <view>test content</view>
</mpdialog>

2. More abilities

Property Name

Type

Default Value

Required

Description

bind:submit

eventhandle

-

No

Carry the data in the form to trigger the submit event, and you can get the value of the form item corresponding to the name in event.detail

bind:reset

eventhandle

-

no

reset event is fired when the form is reset

Sample code

  <form bind:submit="handleSubmit" bind:reset="handleReset">
    <switch name="switch"></switch>
    <button form-type="submit" data-info="Submit button" type="primary" class="submit-btn">Submit</button>
    <button form-type="reset" data-info="reset button" class="reset-btn">reset</button>
  </form>
Page({
  data: {
    resultData: [
      {
        name: "switch",
        value: "",
      },
    ],
  },

  handleSubmit(ev) {
    const value = ev.detail.value;
    console.log(value);
  },

  handleReset(ev) {
    const value = ev.detail.value;
    console.log(value);
  },
});

More sample code sample code experience effect.

We have provided several templates for developers to learn