Lightning Container Introduction

In Lightning framework, if we want to use third-party components, they can be included in the Lightning Container module.

Lightning Container Works

Lightning Container inside an iframe will be included in the assembly, and provides a number of functions allowed to the interior of the components and external applications communicating Lightning.

It requires components inside as a "static resource (static resource)" uploaded to Salesforce.

Its essence is to call the URL path syntax static resources.

For example, we've got a Vue application, its entry document is index.html, we will upload it to static resources Salesforce, by the name "testApp", then it calls the following way:

<lightning:container src="{!$Resource.testApp + '/index.html'}" />

Lightning Container NPM packages and Example

Lightning Container provides the NPM package that allows third-party component calls API, and thus Lightning components communicate.

We have two programs Vue-cli example to illustrate:

  • Lightning component and how to communicate
  • How to call functions from third-party components in Apex

Set Lightning Container

Initialization Vue-cli project, and then install the NPM package:

npm install lightning-container --save

Main.js add the following two lines in the file:

import LCC from 'lightning-container'

Vue.prototype.$LCC = LCC

In this way, we can refer to other components in the module, the syntax is as follows:

this.$LCC

Vue compiled application

Run the following command on the command line to compile the Vue will be applied to the "dist" folder:

npm run build

Then we will be content "dist" folder in a zip file, uploaded to Salesforce as a static resource.

Apply the default entry Vue-cli is the index.html file.

Lightning communication and presentation components

In this demonstration program communication, we want to achieve is to send each other text components in the Lightning and Vue applications.

In Vue project, in the "src / components" folder in the new Vue component named "Messaging.vue", the code is as follows:

<template>
  <div>
    <h3>通信演示</h3>
    
    <div>
      发送给 Lightning Component:
      <input type="text" id="text-input-to-Lc" class="slds-input" v-model="msgToLC" />
      <button id="sendBtn" class="slds-button slds-button--neutral" v-on:click="sendMessage">发送到 Lightning Component</button>
    </div>
    
    <div>
      从 Lightning Component 接收的信息:
      <input type="text" id="text-input-from-Lc" class="slds-input" v-model="msgFromLC" />
    </div>
  </div>
</template>

<script>
export default {
    data () {
        return {
        msgToLC: '',
        msgFromLC: ''
        }
    },
    mounted: function() {
        this.$LCC.addMessageHandler(this.receiveMessage); // 使用 addMessageHandler() 函数定义如何接收从 Lightning 组件中传来的数据
    },
    methods: {
        receiveMessage: function(message) {
            this.msgFromLC = message.value;
        },

        sendMessage: function() {
            // 使用 sendMessage() 函数发送信息给 Lightning 组件
            this.$LCC.sendMessage({name: "Message To LC", value: this.msgToLC})
        }
    }
}
</script>

Under Vue project "src / router" folder and modify the "index.js" file, Vue component definition you just created as the default path:

import Messaging from '@/components/Messaging'

export default new Router({
    routes: [
    {
        path: '/',
        name: 'Messaging',
        component: Messaging
    },
    ]
})

Vue compiled application, then uploaded to Salesforce, as a static resource, called "VueApplication".

New Lightning Components in Salesforce:

<aura:component access="global">
    <aura:attribute access="private" name="messageToSend" type="String" default=""/>
    <aura:attribute access="private" name="messageReceived" type="String" default=""/>
    
    <div>
        <lightning:input name="messageToSend" value="{!v.messageToSend}" label="发送给 Vue 应用: "/>
        <lightning:button label="Send" onclick="{!c.sendMessage}"/>
        <br/>

        <lightning:input value="{!v.messageReceived}" label="接收自 Vue 应用: "/>
        <br/>
    
        <!-- 使用 lightning:container 来调用静态资源中的 Vue 应用,并定义在收到它的信息时使用的函数 -->
        <lightning:container aura:id="vueApp"
                             src="{!$Resource.vueApplication + '/index.html'}"
                             onmessage="{!c.handleMessage}"/>
    </div>
</aura:component>

Defined Controller:

({
    /*
     * 从 Lightning 组件中发送信息
     */
    sendMessage : function(component, event, helper) {
        var msg = {
            name: "Message From LC",
            value: component.get("v.messageToSend")
        };
      
        component.find("vueApp").message(msg);
    },
    
    /*
     * 接收从 Vue 应用中发送的信息
     */ 
    handleMessage: function(component, event, helper) {
        var value = event.getParams().payload.value;
   
        component.set("v.messageReceived", value);        
    },
})

When we use the Lightning component that automatically calls the Vue application, then the text can be sent and received between two applications.

When we view the source code of the page, you can see, lightning: container contents are placed in an iframe, so we actually Vue application package together.

Apex function call

In the next application, we call applications from Vue Apex function.

Apex established function in Salesforce:

global without sharing class VueController {
    @RemoteAction
    global static Account[] getAccounts(String searchString) {
        return [SELECT Id, Name, Phone, Type, NumberOfEmployees FROM Account Limit 10];
    }
}

In order to invoke Apex function, we need a special setting in Vue applications. Create a file called "manifest.json" under "dist" folder, as follows:

{
    "landing-pages" : [
        {
            "path": "index.html",
            "apex-controller": "VueController"
        }
    ]
}

Establish a component called "AccountList" at Vue applications:

<template>
  <div>
    <h3>接收到的数据:</h3>
    
    <ul>
      <li v-for="item in accounts">
        {{ item.Name }}
      </li>
    </ul>
  </div>
</template>

<script>
export default {
    data () {
        return {
            accounts: [],
        }
    },
    mounted: function() {
        this.getAccounts();
    },
    methods: {
        getAccounts: function() {
            // 使用 callApex() 函数来调用相应的函数
            this.$LCC.callApex("VueController.getAccounts", 
            {
            searchString: ''
            }, 
            this.handleResult, 
            {});
        },

        handleResult: function(result) {
            this.accounts = result;
        },
    }
}
</script>

Thus, with lightning: applied when the container executed in the Lightning Vue component, the application will directly call Vue Apex function, and then gives the result.

Compared with the Locker Service

Lightning Container mechanism and Locker Service mechanisms are carried out to improve safety Lightning components, the different sources (namespace, etc.) components are encapsulated.

Lightning Container iframe-based, third-party components or applications it is encapsulated in an iframe, and Locker Service not require such, it is the different components in the same DOM tree, different DOM elements encapsulated. This is the biggest difference between the two, which also determines their different characteristics:

  • Locker Service Lightning may utilize various functions of a local frame, while the contents of Container Lightning is limited, such as only API functions provided by which to communicate packet NPM
  • Lightning Container support of third-party frameworks more than Locker Service
  • Components Locker Service in execution speed faster than the Lightning Container in to
  • Locker Service and the appearance of the entire assembly Lightning frame is the same, but since the contents of Container Lightning is encapsulated in an iframe, problems may occur in exceptional circumstances

Guess you like

Origin www.cnblogs.com/chengcheng0148/p/lightning_container_introduction.html