【Salesforce】【lwc】@api @track @wire

发布时间 2023-08-01 17:18:20作者: 猪猪宝丫

一、@api @track @wire的区别

1.@track注解private类型的reactive变量。

2. @api注解public类型的reactive变量(public类型:即可暴露给其他的APP用来可以赋值注入)。

3. @wire:我们常用的注解除了@track 以及 @api以外,还会经常使用@wire,区别为前两个是针对前台的,后面的这个是wire service,可以用来获取数据,创建数据,调用apex等等

@wire の2つの方法

@wire は、組織からデータを取得できるデコレータです。

uiRecordApi.getRecord を用いる場合と、Apex を用いる場合があるので、それぞれ書いていきます。

uiRecordApi.getRecord を用いる場合

 1 // howToUseVariables.js
 2 import { LightningElement, wire } from 'lwc';
 3 import { getRecord } from 'lightning/uiRecordApi';
 4 export default class howToUseVariables extends LightningElement {
 5 
 6     @wire(getRecord, { recordId: '0035h00000DN1ciAAD', fields: ['Contact.Name', 'Contact.Phone']})
 7     contactRecord;
 8 
 9     get NameOfContactRecord() {
10         if(this.contactRecord.data) {
11             return this.contactRecord.data.fields.Name.value;
12         }
13         return null;
14     }
15 
16     get PhoneOfContactRecord() {
17         if(this.contactRecord.data) {
18             return this.contactRecord.data.fields.Phone.value
19         }
20         return null;
21     }
22 }

 

<!-- howToUseVariables.html -->
<template>
    <lightning-card class="slds-m-around_small">
        (@wire - uiRecordApi.getRecord)<br>
        <p>Name : {NameOfContactRecord}</p>
        <p>Phone : {PhoneOfContactRecord}</p>
    </lightning-card>
</template>

表示

この方法では、レコードID と 取得する項目を指定して、組織からデータを取得することができます。

this.contactRecord.data.fields.Name.valueといったように、項目の値を参照するのに、少し深く階層を指定する必要があります。
これをそのままHTML側で指定すると、データがまだ取得できていないときに ~.dataが null になるので、エラーになります。
そのため、このサンプルでは getter プロパティ から値を取得しています。

getRecord について、公式の説明はこちらになります。

Apex を用いる場合

 1 // ContactUtil.cls
 2 public with sharing class ContactUtil {
 3     
 4     @AuraEnabled (cacheable=true)
 5     public static Contact getContact(){
 6         try {
 7             return (Contact) [SELECT Name, Phone FROM Contact LIMIT 1];
 8         } catch (QueryException e) {
 9             throw new AuraHandledException(e.getMessage());
10         }
11     }
12 }
 1 // howToUseVariables.js
 2 import { LightningElement, wire } from 'lwc';
 3 import getContact from '@salesforce/apex/ContactUtil.getContact';
 4 export default class howToUseVariables extends LightningElement {
 5 
 6     @wire(getContact)
 7     contactByApex;
 8 
 9     get NameOfContactByApex() {
10         if(this.contactByApex.data) {
11             return this.contactByApex.data.Name;
12         }
13         return null;
14     }
15 
16     get PhoneOfContactByApex() {
17         if(this.contactByApex.data) {
18             return this.contactByApex.data.Phone;
19         }
20         return null;
21     }
22 }

 

 1 <!-- howToUseVariables.html -->
 2 <template>
 3     <lightning-card class="slds-m-around_small">
 4         (@wire - Apex)
 5         <p>Name :&nbsp;
 6             <lightning-formatted-text
 7                 value={NameOfContactByApex}
 8             ></lightning-formatted-text>
 9         </p>
10         <p>Phone :&nbsp;
11             <lightning-formatted-phone
12                 value={PhoneOfContactByApex}
13             ></lightning-formatted-phone>
14         </p>
15     </lightning-card>
16 </template

 

二、Private和 Reactive的区别

Private 以及 Reactive,针对 Private,举一个不太恰当的比喻,在apex中可以声明变量为 private / public / global 类型,其中 private只能当前这个类当中引用,并且 apex page中无法引用,这里的 Private也有这层意思,区别是 Private类型变量可以在component中使用,但是他的后期的任何变化不会对component进行重新渲染,而且父页面也无法通过注入方式修改此类型变量;我们更多的要介绍的是 Reactive类型变量,此种变量的特点为当此变量改变以后,component便会重新渲染,在这个component中的所有的表达式都会重新计算。此种变量有两个类型: public / tracked(private). public 使用@api注解进行修饰。tracked使用@track注解进行修饰。这里需要注意的是,如果使用了@track 或者@api,必须要import track或者 import api在头部才能使用。

 Tracked: Tracked类型也可以称为Private类型的Reactive,此种声明类型可以实现当变量改变以后,component进行reRender操作,此种类型的变量当其他的component引用以后,不可以通过attribute方式进行注入值,;此种类型头部声明需要引用:

import { LightningElement, track} from 'lwc';

Public:Public类型和Track类型区别为当其他的component进行引用时,可以通过attribute进行注入值。此种类型声明时头部需要引用:

import { LightningElement, api} from 'lwc';

看到上面这几种类型的介绍,我们可能会有一个疑问,声明成reactive是不是比private更好更方便?其实在变量声明时我们一定要千万的注意考虑好变量的作用域,变量类型。reactive类型当改变以后整个component都会reRender,所有template中包含的表达式都会被重新计算,使用不当可能会造成不准确或者不必要的性能影响,所以声明以前要考虑清楚变量用途。下面的Demo用来深化一下Tracked以及Public的用法。我们想要知道LWC封装了哪些component,我们可以访问:https://developer.salesforce.com/docs/component-library/overview/components进行查看。

既然reActive类型变量这么神奇,是否有什么相关的limitation呢?答案是有的。针对reActive类型变量只支持三种类型:

  • Primitive values
  • Plain objects created with {…}
  • Arrays created with []

只有这三种类型允许reActive,其他的类型即使声明了,也没法做到改变以后重新渲染component,并且会在console log里面提示你当前类型不支持track。