一、@api @track @wire的区别
1.@track注解private类型的reactive变量。
2. @api注解public类型的reactive变量(public类型:即可暴露给其他的APP用来可以赋值注入)。
3. @wire:我们常用的注解除了@track 以及 @api以外,还会经常使用@wire,区别为前两个是只针对前台的,wire既可以用在前台也可以用在后台,可以用来获取数据,创建数据,调用apex等等。
例子
@api
1 // howToUseVariables.js 2 import { LightningElement, api } from 'lwc'; 3 export default class howToUseVariables extends LightningElement { 4 @api 5 age; 6 }
<!-- howToUseVariables.html --> <template> <lightning-card class="slds-m-around_small"> (@api) <p>age : {age}</p> </lightning-card> </template>
-------------------------------------------------------------------------
1 // parent.js 2 export default class parent extends LightningElement { 3 @api 4 age; 5 6 handleChanges(e){ 7 age = e.target.value; 8 } 9 }
1 <!-- parent.html --> 2 <template> 3 <c-how-to-use-variables age={age}></c-how-to-use-variables> 4 <lightning-input type="number" default=40 onchange={handleChanges} label="age"></lightning-button> 5 </template>
表示
@api を用いると、外部に変数や関数を公開することができます。
この例のように、親のコンポーネントが、公開された変数に値を入力することができます。
@track
@track
1 // howToUseVariables.js 2 import { LightningElement, track } from 'lwc'; 3 export default class howToUseVariables extends LightningElement { 4 @track 5 parsonObj = { 6 name : 'オブジェ太郎', 7 age : 123 8 }; 9 10 @track 11 parsonObjList = [ 12 {name : 'リスト太郎', age : '40'}, 13 {name : 'リスト次郎', age : '30'}, 14 {name : 'リスト三郎', age : '20'}, 15 ]; 16 17 handleChange = function(e){ 18 this.parsonObj.age = e.target.value; 19 this.parsonObjList[0].age = e.target.value; 20 } 21 }
1 <!-- howToUseVariables.html --> 2 <template> 3 <lightning-card class="slds-m-around_small"> 4 (@track - Object) 5 <div class="slds-box"> 6 <p>name : {parsonObj.name}</p> 7 <p>age : {parsonObj.age}</p> 8 </div> 9 10 (@track - Array) 11 <template for:each={parsonObjList} for:item="parsonObj"> 12 <div key={parsonObj.name} class="slds-box"> 13 <p>name : {parsonObj.name}</p> 14 <p>age : {parsonObj.age}</p> 15 </div> 16 </template> 17 18 <form> 19 <lightning-input type="number" default=40 onchange={handleChange}> 20 </lightning-input> 21 </form> 22 </lightning-card> 23 </template>
表示
このサンプルでは、「オブジェクト」「配列」に対して @track を使ってみました。
以前は、@track を使わないと、変数の変更時に再描画が行われませんでしたが、
Spring’20 の更新以降は、@track をつけなくても、再描画がされるようになっています。
しかし、オブジェクトや配列の子要素に変更を加えた場合の再描画は、@track を付けないと行われません。
そのため、このサンプルでは オブジェクトと配列を扱いました。
上記の画像は、入力欄 に99を入力したあとの状態です。handleChanges()
によってオブジェクトとリストの子要素の値が変更し、画面に反映されているのが分かると思います。
@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 : 6 <lightning-formatted-text 7 value={NameOfContactByApex} 8 ></lightning-formatted-text> 9 </p> 10 <p>Phone : 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。
标签:wire,track,age,Salesforce,api,LightningElement,类型,lwc From: https://www.cnblogs.com/zhuzhubaoya/p/17597996.html