uni-app from entry to advanced day02, MOOC learning

The core syntax of applets

opening

Mini program core syntax:

  1. data-driven principles
  2. Realize two cases and connect core knowledge points
    1. Commodity case
    2. list case

The data-driven principle of small programs

question:

  1. What is data-driven?
  2. How to complete data binding in applet?

Data driven:

  // 商品
  let product = {
    
    
    price: 10,
    num: 5
  }
  // 总价格
  let total = 0;
  // 计算总价格的方法
  function getTotal(product) {
    
    
    return product.price * product.num
  }
  // 计算商品的总价格
  total = getTotal(product)
  // 进行打印
  console.log('总价格:' + total);
  // 50 太贵了,所以我们少购买了两个商品,也就是让 num = 3
  product.num = 3;
  // 问:总价格是多少?
  console.log('总价格:' + total); // 此时,打印发现总价格还是 50 元,如果要说原因的话,那么应该很简单,【因为我们没有重新进行价格的计算嘛】
  // 但是,此时大家有没有想过一点?我们为什么要进行价格的计算呢?
  // ----------------------------------------------------
  // 当商品的数量发生变化时,商品的总价格【理应发生变化】,不是吗?

The above example is what I want to tell you: [When the quantity changes, the total price of the commodity should change].

Then the same reason, in our page, if:

A certain DOM depends on a certain data for display, so [when the data changes, the view should also change].

And this is [Responsive Data Driven].

PS: If you want to learn more about it, you can check out the blog: Talk about the experience of responsive construction

Complete the responsive style in the applet:

  • dataDefine data in

    // index.js
    // 获取应用实例
    const app = getApp()
    
    Page({
          
          
     data: {
          
          
       product: {
          
          
         price: 10,
         num: 5
       }
     }
    })
    
  • wxmlUsing data in

    <view>
      <view>
        <!-- wxml 中访问数据,必须使用 {
          
          {}} 语法,{
          
          {}} 语法中可以放置【任意的、单一的 JavaScript 表达式】 -->  
        商品的单价:{
         
         {product.price}}
      </view>
      <view>
        商品的数量:{
         
         {product.num}}
      </view>
      <view>
        商品的总价格:{
         
         {product.price * product.num}}
      </view>
    </view>
    

Now we can define data js 的 datain and wxml 中通过 { {}}use data in syntax.

So let's go back to our problem:

Answer:

  1. What is data-driven?
    1. When the data changes, the view should change
  2. How to complete data binding in applet?
    1. Define data in data
    2. Using data via {{}} in wxml

But at this time, everyone should still have a doubt in their hearts, that is: [The data has not changed yet? I didn't see the change of view either? 】.

If you really have such a confusion in your heart, then keep reading!

List of common events and properties in applets

question:

  1. How to add click event to button?
  2. How to modify the value of the data in data?

Handle the click event

Next we want to do one thing:

create a button

when the user clicks the button

Let the num of product + 1

The way to create a button is very simple:

<button type="primary">num + 1</button>

The question is: how do we add a click event to this button?

Students who have experience in development may guess that: we can give buttonan clickevent to listen for button clicks.

But everyone needs to know that now we are in the [Mini Program], so if you want to buttonadd you can't use clickit instead bind:tap / bindtap.

Among them, bind: / bindmeans 【Binding Event】, tapwhich is the specific event of binding. For the list of specific events of the applet, you can click here to view.

  <button type="primary" bind:tap="onAddNum">num + 1</button>

Next, you need to define the corresponding eventjs in

 /**
  * 定义事件处理的方法
  */
 onAddNum () {
    
    
  console.log('onAddNum')
 }

So far: we have listened to the click event of the button and written the corresponding processing function , then we need to **modify the value of num**

Modify the data of data

To modify the data datain , then we need a function setData.

setDataReceive an object as a parameter, this object is the latest datadata .

Where keyis the data to be modified and valueis the latest value

Access the data of data

Because we want to let num + 1, we also need to get the current value numof , and want to access numthe value of , we can access it this.data.product.numin the form of

So the final nummodified code is:

 /**
  * 定义事件处理的方法
  */
 onAddNum () {
    
    
  this.setData({
    
    
    'product.num': this.data.product.num + 1
  })

At this point, when we click button, we can find: [When num changes, the total price also changes accordingly]

Answer:

  1. How to add click event to button?
    1. bindtap || bind:tap
  2. How to modify the value of the data in data?
    1. this.setData({})Define new values ​​by
    2. this.dataAccess specific values ​​via

event parameter

question:

  1. If you want to pass parameters in [click event], what do you need to do?

new needs

Now let's make the requirements a little more complex.

We hope that onAddNumthe method can receive a parameter, and each click numincreases the number of incoming parameters

So if you want to realize this requirement, then you need to involve a knowledge point: [event parameter passing].

If you have experience in development, you may think that this is a very simple requirement. By the way, you can write the following code:

// html
<button type="primary" bind:tap="onAddNum(5)">num + 1</button>

// js
 onAddNum (step) {
    
    
  this.setData({
    
    
    'product.num': this.data.product.num + step
  })
 }

However, if we really implement it according to the above code, then you should receive the following warning:

Please add a picture description

What this warning means is that there is no method onAddNum(5)called that handles the current tapevent.

That is to say: onAddNum(5)will be treated as a complete method name , not the method name: onAddNum, the parameter passed in is 5!

So what should we do if we want to pass parameters?


In the applet, if you want to pass parameters to the click event, you need to use the event object and data- attribute !

The passing of parameters consists of two parts:

  1. keepsake
  2. Arguments

Reference:

First, look at the formal parameters . For the callback method of the click event , it will receive a parameter event (event object) by default . This eventobject is: the only parameter of the callback method

Arguments:

For applets , we cannot directly pass actual parameters to the callback method .

Instead, you need to bind the parameters that need to be passed to the current DOMelement , and the attribute of the bound data needs to data-start with . This property can be accessed e.target.datasetvia .

// html
<button type="primary" bind:tap="onAddNum" data-step="5">num + 1</button>

// js
 onAddNum (e) {
    
    
  //  获取 data-step 的值
  let step = parseInt(e.target.dataset.step);
  this.setData({
    
    
    'product.num': this.data.product.num + step
  })
 }

Answer:

  1. If you want to pass parameters in [click event], what do you need to do?
    1. Bind the parameters that need to be passed to the current DOMelement
    2. In the corresponding callback function, access e.target.datasetthrough

Realize [two-way data binding]

question:

  1. What is two-way data binding?
  2. How to implement two-way data binding in applet?

In the previous chapter, we realized the function of [each click + 5] through [event parameter passing], but such a function is still a bit too monotonous.

So we next hope to implement a new function:

Create a number input box, and complete the [two-way data binding] between the input box and [product quantity].

Right now:

  1. When the content of the input box changes, the quantity of the item changes synchronously
  2. When the quantity of the product changes, the content of the input box changes accordingly

So how should we achieve such a function?


If we want to realize this function, then we need to disassemble this function first, [dismantling a complex function into multiple simple functions] is a standard way to realize a complex logic.

So how to disassemble it? You can think about the following first, and then continue to learn!


The above functions are disassembled as follows:

  1. Create a [number input box]
  2. Set [Product Quantity] as the initial value of the input box
  3. Listen to user input behavior
  4. Get the value entered by the user
  5. Assign value to 【Product Quantity】
// html
<view>
    商品的数量:
    <!-- 1. 创建一个【数字输入框】 -->
    <!-- 2. 设置 【商品数量】 为输入框的初始值 -->
    <input class="num-input" type="number" value="{
    
    { product.num }}" bindinput="onInput" />
</view>
  
// js
/**
  * 3. 监听 input 的输入事件
  */
 onInput (e) {
    
    
  //  4. 获取用户输入的值
   const val = parseInt(e.detail.value);
  //  5. 赋值给【商品数量】
  this.setData({
    
    
    'product.num': val
  })

So now that we have implemented the function, let’s recall our questions:

Answer:

  1. What is two-way data binding?
    1. When the view changes, the data changes accordingly.
    2. When the data changes, the view changes accordingly.
  2. How to implement two-way data binding in applet?
    1. valueBy inputbinding data for the view
    2. bindinputObtain changes in the view by monitoring and modify the data in the callback method

conditional rendering

question:

  1. What is the difference between v-if and hidden?

Now you have bought a lot of products, but when you went out to check out, the salesperson exclaimed to you:

  1. If [total price <= 100]: hello handsome guy
  2. If [total price > 100 && total price < 1000]: Wow rich man
  3. If [total price >= 1000]: hello local tyrant

If you want to achieve such a function, then you need to use the [conditional rendering] function.

The applet provides two APIs that can realize the [conditional rendering] function:

  1. wx:if ... wx:elif ... wx:else
  2. hidden

Then let's use these two syntaxes to realize this function:

<!-- wx:if ... wx:elif ... wx:else:判断结果为 true 则进行渲染,否则不进行渲染 -->
  <view>
    售货员小姐姐惊呼:
    <text wx:if="{
     
     { product.price * product.num <= 100 }}">hello 帅哥</text>
    <text wx:elif="{
     
     { product.price * product.num > 100 && product.price * product.num < 1000 }}">哇哦 有钱人哦</text>
    <text wx:else>土豪你好</text>
  </view>
  <!-- hidden:结果为 true 则隐藏,否则不隐藏 -->
  <view>
    售货员小姐姐惊呼:
    <text hidden="{
     
     { !(product.price * product.num <= 100) }}">hello 帅哥</text>
    <text hidden="{
     
     { !(product.price * product.num > 100 && product.price * product.num < 1000) }}">哇哦 有钱人哦</text>
    <text hidden="{
     
     {product.price * product.num < 1000}}">土豪你好</text>
  </view>

Answer:

  1. What is the difference between v-if and hidden?
    1. v-ifUsed to control [whether the component will be rendered]
    2. hiddenUsed to control [whether the component will be hidden]
    3. In general, therewx:if is a higher switching cost and a higher initial rendering cost. hiddenTherefore, it hiddenis better , wx:ifand better if conditions are unlikely to change during runtime.

list rendering

question:

  1. wx:forWhen using , what are the defaults of [subscript variable name] and [current item variable name] of the current item?
  2. blockWill the component be rendered?

New requirements:

If we have a group of products and want to render all the products in this group, then we need to use the [List Rendering] function.

The applet provides us with v-forthe instruction , let us implement [list rendering].

At the same time, it also provides us with a wrapping container blockcomponent . When we loop multiple elements, we can use blockto wrap them. blockThe component only plays the role of other wrapped components and does not render itself.

// html
<!-- 
    利用 wx:for 循环渲染商品
    默认数组的当前项的下标变量名默认为 index,
    数组当前项的变量名默认为 item
   -->
  <view class="product-box">
    <block wx:for="{
    
    { products }}" wx:key="index">
      <view class="product-item">
        <text>商品名:{
    
    {
    
    item.name}}</text>
        <text>价格:{
    
    {
    
    item.price}}</text>
      </view>
    </block>
  </view>
  
// js
data: {
    
    
   products: [
     {
    
    
       name: '苹果',
       price: 3.2
     },
     {
    
    
       name: '面包',
       price: 5.0
     },
     {
    
    
       name: '可乐',
       price: 2.5
     }
   ]
 }

Answer:

  1. wx:forWhen using , what are the defaults of [subscript variable name] and [current item variable name] of the current item?
    1. The subscript variable name of the current item of the default array defaults to index
    2. The variable name of the current item in the array defaults to item
  2. blockWill the component be rendered?
    1. blockJust a wrapping container that won't be rendered.

Configuration file interpretation

  1. app.jsonConfiguration file:
    see the link for details
  2. pagesArray:
    see link for details
    1. create listpage
  3. windowObject:
    see link for details
  4. tabbarObject:
    see link for details
    1. indexpage
    2. listpage
  5. 页面.jsonConfiguration file:
    see the link for details

data request

Scenes

Let’s imagine a scenario first. Now you are [the front-end development engineer of MOOC], and then you have developed such a [small program]
Please add a picture description

The system is now live.

One day, you want to modify a piece of data in it, for example: change [C Language Systematic Intensive Lecture] to [C Language Intensive Lecture], then what should you do?

Remember, your project is now live! You want to modify the content of the online version, so how do you do it? Is it necessary to release a new version in order to modify this text? What if there are similar text changes in the future?

Then facing such a scenario at this time, we need to use [Data Request].

question

  1. What are the restrictions on data requests in applets? and how to work around this limitation
  2. Will there be cross-domain problems in the data request of the applet? Why?
  3. Can the data request of an applet be called ajaxa request ? Why?

content

wx.request initiates a network request, and there are two main methods of request:

  1. get request
  2. post request

Two data request interfaces are prepared here, which can be used to test the data request of wx.request (see interface documentation for details):

  1. Basic Course Cases-Youth Gang News Portal
  2. Find the post interface by yourself

Then we will complete a basic interface request according to wx.request

// html
<view>
  <button type="primary" bindtap="onGetClick">发起 get 请求</button>
</view>
// js
// index.js
// 获取应用实例
onGetClick () {
    
    
    wx.request({
    
    
        url: 'https://api.imooc-blog.lgdsunday.club/api/test/getList',
        method: 'GET',
        success: (res) => {
    
    
            console.log(res);
        }
    })
}

This code looks fine, but we get an error (testable APPID:wxf01e2ce0eb588aac):
Please add a picture description

To solve this problem, we need to clarify a question: What are the restrictions on data requests in applets?

  1. Only interfaces of HTTPStype
  2. The domain name of the interface must be added to the trust list

solution:

  1. Production environment: Change the domain name protocol you want to request to [Change to HTTPS] and [Add to the domain name trust list]
  2. Development environment: by tickingPlease add a picture description

When getthe request is complete, let's test postthe request:

// html 
  <button type="primary" bindtap="onPostClick">发起 post 请求</button>
  // js
   onPostClick () {
    
    
    wx.request({
    
    
      url: 'https://api.imooc-blog.lgdsunday.club/api/test/postData',
      method: 'POST',
      data: {
    
    
        msg: '愿大家心想事成,万事如意'
      },
      success: (res) => {
    
    
        console.log(res);
      }
    })
  }

Digression (extended content: for students with web front-end development experience):

  1. Cross-domain problem: The cross-domain problem is mainly for browsers , and the host environment of the applet is [WeChat applet client], so there is no [cross-domain problem] in the applet
  2. ajaxRequest: ajax depends on XMLHttpRequestthe object , and the host environment of the Mini Program is [WeChat Mini Program Client], so the [Network Request] in the Mini Program is not ajax a request

Answer

  1. What are the restrictions on data requests in applets? and how to work around this limitation
    1. limit:
      1. Only interfaces of HTTPStype
      2. The domain name of the interface must be added to the trust list
    2. solution:
      1. Production environment: Change the domain name protocol you want to request to [Change to HTTPS] and [Add to the domain name trust list]
      2. Development environment: by tickingPlease add a picture description
  1. Will there be cross-domain problems in the data request of the applet? Why?
    1. Won't
  2. [Cross-domain problem] only exists in browser-based Webdevelopment
  3. Since the host environment of the applet is not a browser, but a WeChat client
  4. So there is no cross-domain problem in the applet
  5. Can the data request of an applet be called ajaxa request ? Why?
    1. Can't
    2. ajaxThe core is XMLHttpRequestthe object
    3. Since the host environment of the applet is not a browser, but a WeChat client
    4. Therefore, the data request of the applet cannot be called ajaxa request

A new solution for asynchronous programming - promise

Scenes

First, let's assume a scenario:

There is currently a requirement that requires you to make interface requests according to the following logic:

  1. First go to request interface A
  2. After interface A gets the data, go to request interface B
  3. After interface B gets the data, go to request interface C
  4. After interface C obtains the data, it requests interface D

If we follow what we learned in the previous section, we will get the following code (for the interface code, please refer to: 03-Mini Program Core Syntax/02-Callback Hell.html):

   A(function (res) {
    
    
    console.log(res);
    B(function (res) {
    
    
      console.log(res);
      C(function (res) {
    
    
        console.log(res);
        D(function (res) {
    
    
          console.log(res);
        })
      })
    })
  })

In this world where "appearance is justice", our code structure should have no future . Because it's too ugly and too hard to read.

Imagine, if we want to request 10 interfaces, what will the code look like?

So in the programming circle, there is a very academic name for such code: callback hell -> a large number of nesting of callback functions leads to complex and difficult to read logic

question

  1. How does promise solve the problem of callback hell?
  2. There are several states of Promise, what are they?
  3. How to make Promise become fulfilled (fulfilled) state, how to receive fulfilled (fulfilled) result

content

Click Promise to enter the official document:

<!-- 
  使用 Promise 进行定义接口:
  Promise 对象用于表示一个异步操作的最终完成 (或失败)及其结果值。
  它一个构造函数,所以可以通过 new 关键字来构建它,获取实例。
  在 Promise 中,分为了三种状态:
  1. 待定(pending): 初始状态,既没有被兑现,也没有被拒绝。
  2. 已兑现(fulfilled): 意味着操作成功完成。
  3. 已拒绝(rejected): 意味着操作失败。
  
  可以通过 promise 实例的 
  1. 成功:promise.then()
  2. 失败:promise.catch() 
  3. 结束:promise.finally()
  的三个方法,进行链式调用来解决回调地狱的问题。
 -->
<script>
  const isA = true
  const isB = true
  const isC = true
  const isD = true

  function A() {
    
    
    // 1. 创建 Promise 实例
    return new Promise((resolve, reject) => {
    
    
      // 2. 当前处于 【待定(pending)】 状态下
      console.log('执行 A 接口的逻辑')
      setTimeout(() => {
    
    
        if (isA) {
    
    
          // 3. 进入 【已兑现(fulfilled)】 状态下
          resolve('接口 A 执行完成')
        } else {
    
    
          // 4. 进入 【已拒绝(rejected)】 状态下
          reject('接口 A 执行失败')
        }
      }, 1000)
    })
  }

  function B() {
    
    
    return new Promise((resolve, reject) => {
    
    
      console.log('执行 B 接口的逻辑')
      setTimeout(() => {
    
    
        if (isB) {
    
    
          resolve('接口 B 执行完成')
        } else {
    
    
          reject('接口 B 执行失败')
        }
      }, 1000)
    })
  }

  function C() {
    
    
    return new Promise((resolve, reject) => {
    
    
      console.log('执行 C 接口的逻辑')
      setTimeout(() => {
    
    
        if (isC) {
    
    
          resolve('接口 C 执行完成')
        } else {
    
    
          reject('接口 C 执行失败')
        }
      }, 1000)
    })
  }

  function D() {
    
    
    return new Promise((resolve, reject) => {
    
    
      console.log('执行 D 接口的逻辑')
      setTimeout(() => {
    
    
        if (isD) {
    
    
          resolve('接口 D 执行完成')
        } else {
    
    
          reject('接口 D 执行失败')
        }
      }, 1000)
    })
  }

  // 获取 Promise 实例
  A()
    // 通过 .then 方法获取当前 Promise 的执行结果
    .then(res => {
    
    
      console.log(res);
      // 标记下一步进入 B 方法
      return B()
    })
    // 继续 .then 进行下一次的异步操作
    .then(res => {
    
    
      console.log(res);
      // 标记下一步进入 C 方法
      return C()
    })
    // 继续 .then 进行下一次的异步操作
    .then(res => {
    
    
      console.log(res);
      // 标记下一步进入 D 方法
      return D()
    })
    // 继续 .then 进行下一次的异步操作
    .then(res => {
    
    
      console.log(res);
      // 结束
    })

Screenshot of the result code comparison between Promise and callback hell

Please add a picture description

Answer

  1. How does promise solve the problem of callback hell?
    1. Chain calls.then via
  2. There are several states of Promise, what are they?
    1. Pending: The initial state, neither honored nor rejected.
    2. Fulfilled: means the operation completed successfully.
    3. Rejected: means the operation failed.
  3. How to make Promise become fulfilled (fulfilled) state, how to receive fulfilled (fulfilled) result
    1. The status of can be changed from [pending (pending)] to [fulfilled (fulfilled)] resolvethroughPromise
    2. The fulfilled result can be received via promise实例.thenthe method

But after seeing this, there may still be many students who are full of doubts , "I don't promisethink this way is easier?" If you really have such doubts , then you should believe that such questions have also been answered before. people have proposed.

So how to solve this problem? Please see the next section Asynchronous Programming Upgrade - async + await

Asynchronous programming and then upgrade - async + await

Scenes

PromiseThe solution solves the problem of callback hell, but Promiseit brings a new problem, that is: a large number of chain calls, making our code stinky and long!

Let's look back at the code comparison of the two schemes promiseand the callback hell :

Please add a picture description

It can be found that the callback hell 11linepromise of code took a full line to solve, and the amount 18of code is quite large 60%.

This "regression" is absolutely unacceptable. So for such a situation, we need to use two new keywords async + await.

question

  1. asyncawaitWhat is the role of and ?
  2. awaitWhat are the precautions for using ?

content

Click async + await to enter the official documentation:

  // 使用 async 和 awiat 可以简化 Promise 的异步操作,把 Promise 的异步操作变为同步写法
  // async:标记一个函数为异步函数
  // await:标记当前操作为异步操作,await 关键字只能使用在被 【async标记的函数中】
  async function test() {
    const resA = await A();
    console.log(resA);
    const resB = await B();
    console.log(resB);
    const resC = await C();
    console.log(resC);
    const resD = await D();
    console.log(resD);
  }

Screenshot comparison of three implementation schemes:
Please add a picture description

Answer

  1. asyncawaitWhat is the role of and ?
    1. asyncand awaitcan simplify promisethe operation
    2. promiseMake the asynchronous operation of have synchronous writing
  2. awaitWhat are the precautions for using ?
    1. awaitmust be used in functions asyncmarked

Using promise in small programs to solve asynchronous programming

Scenes

Let’s look back at [the code of the applet], and at the same time review the needs we have solved before:

There is currently a requirement that requires you to make interface requests according to the following logic:

  1. First go to request interface A
  2. After interface A gets the data, go to request interface B
  3. After interface B gets the data, go to request interface C
  4. After interface C obtains the data, it requests interface D

This is the scenario we listed in our promisestudy , so this scenario is also applicable to the [Network Request Scenario] in the [Mini Program]. If we wx.requestachieve , we will get the following code:

wx.request({
    
    
      url: 'A',
      method: 'GET',
      success: (res) => {
    
    
        wx.request({
    
    
          url: 'B',
          method: 'GET',
          success: (res) => {
    
    
            wx.request({
    
    
              url: 'C',
              method: 'GET',
              success: (res) => {
    
    
                wx.request({
    
    
                  url: 'D',
                  method: 'GET',
                  success: (res) => {
    
    
                    console.log(res);
                  }
                })
              }
            })
          }
        })
      }
    })

A smelly and long code, right.

Then what we need to do next is very simple, we need to **use async and await** to simplify the above operations.

question

  1. How to wx.requestfit asyncand awaituse ?

content

If we want to achieve our goal, then we need to operate in two steps:

  1. Get promisethe instance object
  2. Simplified operations using asyncandawaitpromise

Get the promiseinstance object:

Because wx.requestdoes not support promiseization, we need to: use promisethe wrapper wx.requestrequest

  pA () {
    
    
    return new Promise((resolve, reject) => {
    
    
      console.log('执行 A 接口的逻辑');
      wx.request({
    
    
        url: 'https://api.imooc-blog.lgdsunday.club/api/test/A',
        success: (res) => {
    
    
          resolve(res)
        },
        fail: (err) => {
    
    
          reject(err)
        }
      })
    })
  }

Use asyncand simplifiedawait operations (PS: Be careful not to check ES6 to ES5)promise

async onPromiseGetClick () {
    
    
    const resA = await this.pA()
    console.log(resA.data.data.msg);
    const resB = await this.pB()
    console.log(resB.data.data.msg);
    const resC = await this.pC()
    console.log(resC.data.data.msg);
    const resD = await this.pD()
    console.log(resD.data.data.msg);
  }

Answer

  1. How to wx.requestfit asyncand awaituse ?
    1. Use promisepackage wx.requestrequest
    2. Simplified operations using asyncandawaitpromise

life cycle

So far we have learned a lot of core knowledge points of small programs, then we need to implement a small case.

Scenes

Then let's implement the first function of this case first:

We hope that after the page appears, the interface data can be obtained and rendered

Then such a simple requirement, according to the knowledge we have learned now, is: there is no way to achieve it .

If you want to achieve this function, you need to master the life cycle of the page

question

  1. What is a life cycle? What are lifecycle functions?
  2. onReadyWhat is the timing of the call?

content

What is a life cycle:

If you want to learn the life cycle of [small program], then we must first figure out what is [life cycle]

The so-called "life cycle" is: the whole process of a thing from creation to destruction .

There will be many "critical moments" in this process , and these critical moments are life cycle functions


In [Mini Program], the life cycle is mainly divided into two parts:

  1. Page life cycle (content in this chapter)
  2. Component life cycle (explained in subsequent chapters)

Create a new page list. In the newly created page, we can find that a lot of code has been generated by default in jsthe file :

// pages/list/list.js
Page({
    
    
	...
    /**
     * 生命周期函数--监听页面加载
     */
    onLoad: function (options) {
    
    
        console.log('onLoad');
    },

    /**
     * 生命周期函数--监听页面初次渲染完成
     */
    onReady: function () {
    
    
        console.log('onReady');
    },

    /**
     * 生命周期函数--监听页面显示
     */
    onShow: function () {
    
    
        console.log('onShow');
    },

    /**
     * 生命周期函数--监听页面隐藏
     */
    onHide: function () {
    
    
        console.log('onHide');
    },

    /**
     * 生命周期函数--监听页面卸载
     */
    onUnload: function () {
    
    
        console.log('onUnload');
    },
	...
})

In these codes, we focus on lifecycle functions –xx related content.

These 5 functions are [life cycle functions in applets], we put the mouse on [functions], then [mini-program development tools] will prompt the corresponding [function explanation].

These life cycle functions do not need to be mastered , we only need to focus on mastering two of them:

  1. onLoad: It is called first and can be used to [receive data from other pages]. In the following [page jump], I will explain it again.
  2. onReady: Called after the page is rendered for the first time. We can get data from the server here

So after knowing this, let's go back to our initial requirements, we hope that after the page appears, we can get the interface data and render it . So how to implement it?

It's easy! You only need to call the method of obtaining interface data onReadyin .

So now we have obtained the data of the interface after the page appears , so next we only need to complete the rendering of the page according to the data:

// html
<scroll-view class="list-box" scroll-y>
    <block wx:for="{
    
    { listData }}" wx:key="index">
        <view class="list-item">{
    
    {
    
     index }} -- {
    
    {
    
     item.title }}</view>
    </block>
</scroll-view>

// js
    /**
     * 生命周期函数--监听页面初次渲染完成
     */
    onReady: async function () {
    
    
        console.log('onReady');
        const data = await this.getList()
        this.setData({
    
    
            listData: data.list
        })
    },
    getList() {
    
    
        return new Promise((resolve, reject) => {
    
    
            wx.request({
    
    
                url: 'https://api.imooc-blog.lgdsunday.club/api/test/getList',
                method: 'GET',
                success: (res) => {
    
    
                    resolve(res.data.data)
                }
            })
        })
    }
// css
.list-item {
    
    
    padding: 26px;
    font-size: 20px;
    font-weight: bold;
    border-bottom: 1px solid #cccccc;
}

Answer

  1. What is a life cycle? What are lifecycle functions?
    1. The so-called "life cycle" is: the whole process of a thing from creation to destruction .
    2. There will be many "critical moments" in this process , and these critical moments are life cycle functions
  2. onReadyWhat is the timing of the call?
    1. Called after the initial rendering of the page is complete. We can get data from the server here

pullToRefresh - Pull down to refresh and pull up to load

Scenes

At this point we have achieved basic page rendering , but this is not enough.

Because in our final molding project, the data list is displayed in pages .

The so-called paging is: when there is too much data in the list, loading all the data at once will cause the request to be too slow, so the front end will load the data by paging.

This pagination method is widely reflected in mobile projects, such as [Today's headlines], [Taobao], [WeChat chat records] and many others.

So if we want to implement [pagination request] in the current project, we need to use the function of [pull-down refresh to pull-up load], that ispullToRefresh

question

  1. How to enable pull-to-refresh
  2. onPullDownRefreshIn , what is the general operation
  3. onReachBottomIn , what is the general operation

content

The whole [page loading] is divided into two parts:

  1. pull up load
  2. Pull down to refresh

These two parts need to be processed separately. First, let’s look at [pull-up loading]

Pull-up loading:

In [Small Program], the function of [Pull-Up Loading] has been implemented by default, and you can onReachBottomdirectly monitor the event of the bottom-up pull-up on the page through the monitoring function . When the page slides to the bottom, onReachBottomthe function .

	/**
     * 页面上拉触底事件的处理函数
     */
    onReachBottom: function () {
    
    
        console.log('onReachBottom');
    },

When [user pulls up], we want to get the data of [next page], so we need to paginate the current data:

    /**
     * 页面的初始数据
     */
    data: {
    
    
        // 当前页数
        page: 1,
        // 每页的数据量
        size: 10
    },

Then [when the page enters], we get the data of the first page, so we need to modify the code:

    getList() {
    
    
        return new Promise((resolve, reject) => {
    
    
            wx.request({
    
    
                url: 'https://api.imooc-blog.lgdsunday.club/api/test/getList',
                method: 'GET',
                // 请求当前页的数据
                data: {
    
    
                    page: this.data.page,
                    size: this.data.size
                },
                success: (res) => {
    
    
                    resolve(res.data.data)
                }
            })
        })
    }

Then, during the [pull-up operation], continue to perform subsequent data requests:

    /**
     * 页面上拉触底事件的处理函数
     */
    onReachBottom: async function () {
    
    
        console.log('onReachBottom');
        // 修改 page
        this.setData({
    
    
            page: this.data.page + 1
        })
        // 获取最新数据
        const data = await this.getList()
        // 将最新的数据补充到现有数据的后面
        this.setData({
    
    
            listData: [...this.data.listData, ...data.list]
        })
    },

At the same time, we hope that after the data loading is completed, the user will be given a prompt, and at the same time, no data request will be initiated.

// html
    <!-- 底线 -->
    <view class="bottom" wx:if="{
    
    { listData.length === total }}">-- 我也是有底线的! --</view>
// js
data: {
    
    
    // 总数据量
    total: -1
},
onReady: async function () {
    
    
    const data = await this.getList()
    this.setData({
    
    
        listData: data.list,
        // 为总数据量赋值
        total: data.total
    })
},
/**
* 页面上拉触底事件的处理函数
*/
onReachBottom: async function () {
    
    
    console.log('onReachBottom');
    // 如果当前数据量已经 === 总数据量,则表示数据已经加载完成了
    if (this.data.listData.length === this.data.total) {
    
    
        return;
    }
    ...
}

So far, we have completed the [pull-up loading] operation, but we know that we still lack a [pull-down refresh] operation!


Pull down to refresh:

To implement [Pull-down Refresh] in [Mini Program] is different from pull-up loading, you need to enable [Pull-down Refresh] first :

// 页面.json
{
    
    
  "backgroundColor": "#cccccc",
  "enablePullDownRefresh": true
}

When we enable [Pull-down Refresh], we can listen to onPullDownRefreshthe function , which will call back when the user pulls down to refresh

    /**
     * 页面相关事件处理函数--监听用户下拉动作
     */
    onPullDownRefresh: function () {
    
    
        console.log('onPullDownRefresh');
    },

In this callback, the operations we need to perform are very simple, we only need to: reset the number of pages, reset the data source, and close the drop-down animation :

/**
     * 页面相关事件处理函数--监听用户下拉动作
     */
    onPullDownRefresh: async function () {
    
    
        console.log('onPullDownRefresh');
        // 重置页数
        this.setData({
    
    
            page: 1
        })
         // 获取最新数据
         const data = await this.getList()
         // 将最新的数据补充到现有数据的后面
         this.setData({
    
    
             listData: data.list
         })
        //  关闭下拉刷新的动作(在真机中,下拉刷新动作不会自动关闭)
        wx.stopPullDownRefresh()
    },

Answer

  1. How to enable pull-to-refresh
    1. In the file corresponding to the pagejson "enablePullDownRefresh": true, open it by
  2. onPullDownRefreshIn , what is the general operation
    1. Reset page count
    2. reset data source
    3. close drop down animation
  3. onReachBottomIn , what is the general operation
    1. Determine whether the data has been loaded
    2. auto increment page count
    3. accumulated data

page jump

Scenes

We have now displayed all the [Data List], and then we need to complete the [Rendering of the Article Details Page], that is, click [ itemJump to the Article Details Page]

question

  1. What are the ways to jump to the page?
  2. What are the ways to jump to the [tabbar] page and the [non-tabbar] page?
  3. How to pass parameters for navigation

content

There are two ways to jump to the page of the Mini Program:

  1. Declarative Navigation
    1. jump to tabbarpage
    2. jump to 非tabbarpage
    3. back page
  2. programmatic navigation
    1. jump to tabbarpage
    2. jump to 非tabbarpage
    3. back page

Declarative navigation:

[Small program] provides a component: the jump page componentnavigator , which can be used to complete [declarative navigation]

<!-- 跳转到 非 tabbar 页面 -->
<block wx:for="{
     
     { listData }}" wx:key="index">
        <view class="list-item">
            <!-- 注意:url 的表达式必须为 / 开头的页面路径 -->
            <navigator url="/pages/detail/detail">{
   
   { index }} -- {
   
   { item.title }}</navigator>
        </view>
    </block>

----

<!-- 跳转到 tabbar 页面 -->
<!-- 注意:跳转到 tabbar 页面,必须要指定 open-type="switchTab"-->
<navigator open-type="switchTab" url="/pages/index/index">跳转到首页</navigator>

-----

<!-- 后退页面 -->
<!-- 注意:后退页面必须指定 open-type="navigateBack" -->
<navigator open-type="navigateBack">后退</navigator>

Programmatic navigation:

[Small Program] provides three APIto help us programmatically navigate :

  1. wx.switchTab : Jump to the tabBar page and close all other non-tabBar pages

    <!-- 编程式导航跳转到首页 -->
    <button type="primary" bindtap="onSwitchToHome">利用 switchTab 跳转到首页</button>
    
    onSwitchToHome () {
          
          
        wx.switchTab({
          
          
            url: '/pages/index/index',
        })
    }
    
  2. wx.navigateTo : Keep the current page and jump to a page in the application. But can't jump to the tabbar page

    <!-- 编程式导航跳转到详情页面 -->
    <button type="primary" bindtap="onNavigateToDetail">利用 navigateTo 进入详情页</button>
    
    onNavigateToDetail () {
          
          
        wx.navigateTo({
          
          
            url: '/pages/detail/detail',
        })
    }
    
  3. wx.navigateBack : Close the current page and return to the previous page or multi-level pages.

    <!-- 编程式导航后退页面 -->
    <button type="primary" bindtap="onNavigateBack">利用 navigateBack 后退页面</button>
    
    onNavigateBack () {
          
          
        wx.navigateBack({
          
          
            delta: 1,
        })
    }
    

Navigation parameters:

[Mini Program]'s navigation parameters follow: getthe requested standard .

  1. with ?split urland arguments
  2. with =connection parameters keyandvalue
  3. &Splicing parameters since

Then let's complete the last function of the case: when you click to jump, pass the itemcurrent index and title, and detaildisplay it on the page :

// 声明式导航传递参数
<navigator url="/pages/detail/detail?index={
    
    {index}}&title={
    
    {item.title}}">{
    
    {
    
     index }} -- {
    
    {
    
     item.title }}</navigator>
// 编程式导航传递参数
<button type="primary" bindtap="onNavigateToDetail" data-index="{
    
    {index}}" data-title="{
    
    {item.title}}">利用 navigateTo 进入详情页</button>
onNavigateToDetail (e) {
    
    
    const {
    
     index, title } = e.target.dataset
    wx.navigateTo({
    
    
        url: `/pages/detail/detail?index=${
      
      index}&title=${
      
      title}`,
    })
}
// 在 detail 中接收数据,并展示
<view class="msg">index:{
    
    {
    
    index}} -- title:{
    
    {
    
    title}}</view>
onLoad: function (options) {
    
    
    const {
    
    index, title} = options;
    this.setData({
    
    
        index,
        title
    })
}

Answer

  1. What are the ways to jump to the page?
    1. Declarative Navigation
    2. programmatic navigation
  2. What are the ways to jump to the [tabbar] page and the [non-tabbar] page?
    1. Declarative Navigation
      1. <navigator open-type="switchTab" url="xx" />
      2. <navigator open-type="navigate"(默认可不指定) url="xx" />
    2. programmatic navigation
      1. wx.switchTab({ url: 'xx'})
      2. wx.navigateTo({ url: 'xx'})
  3. How to pass parameters for navigation
    1. [Mini Program]'s navigation parameters follow: getthe requested standard .

      1. with ?split urland arguments
      2. with =connection parameters keyandvalue
      3. &Splicing parameters since

summary

  1. Data-driven principle: data-driven view is one of the core ideas of modern front-end development
  2. Commodity case:
    1. data driven
    2. Component event handling
    3. Handle event method passing parameters
    4. two-way data binding
    5. conditional rendering
    6. list rendering
  3. List display cases:
    1. Generated using configuration filestabbar
    2. Limitations on Data Requests
    3. How to encapsulate the data request promiseof
    4. async + awaitSimplify asynchronous requests with
    5. Page Life Cycle Concept
    6. accomplishpullToRefresh
    7. page jump

Guess you like

Origin blog.csdn.net/weixin_46426412/article/details/129760802