美文网首页
Lightning Container 简介

Lightning Container 简介

作者: 程程哥 | 来源:发表于2019-12-28 01:06 被阅读0次

    在 Lightning 框架中,如果我们想要使用第三方的组件,可以将它们包含在 Lightning Container 模块中。

    Lightning Container 的工作原理

    Lightning Container 会将内部的组件包含在一个 iframe 中,并且提供了若干函数让其内部的组件和外部的 Lightning 应用进行通信。

    它要求内部的组件是作为“静态资源(static resource)”上传到 Salesforce 中。

    它的语法本质上是调用静态资源的 URL 路径。

    举个例子,我们已经有了一个 Vue 应用,它的入口文件是 index.html,我们将它上传到 Salesforce 的静态资源,名字叫 “testApp”,那么调用它的方式如下:

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

    Lightning Container NPM 包和使用实例

    Lightning Container 提供了 NPM 包,可以让第三方组件调用 API,从而和 Lightning 组件进行通信。

    我们以两个 Vue-cli 例子程序来说明:

    • 如何和 Lightning 组件进行通信
    • 如何从第三方组件中调用 Apex 函数

    设置 Lightning Container

    初始化 Vue-cli 项目,然后安装 NPM 包:

    npm install lightning-container --save
    

    在 main.js 文件中加入以下两行:

    import LCC from 'lightning-container'
    
    Vue.prototype.$LCC = LCC
    

    这样,我们就可以在其他的组件中引用模块了,语法如下:

    this.$LCC
    

    编译 Vue 应用

    在命令行中运行以下命令即可将 Vue 的应用编译到 “dist” 文件夹下:

    npm run build
    

    然后我们将 “dist” 文件夹下的内容打包成 zip 文件,上传到 Salesforce 中作为静态资源。

    Vue-cli 的应用默认的入口是 index.html 文件。

    和 Lightning 组件的通信演示

    在这个通信的演示程序中,我们要达到的目标是把文字在 Lightning 组件和 Vue 应用中相互发送。

    在 Vue 项目中,在 “src/components” 文件夹中新建 Vue 组件,名为 “Messaging.vue”,代码如下:

    <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>
    

    在 Vue 项目的 “src/router” 文件夹下,修改 “index.js” 文件,将刚才建立的 Vue 组件定义为默认的路径:

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

    编译 Vue 应用,然后上传到 Salesforce 中,作为静态资源,名为 “VueApplication”。

    在 Salesforce 中新建 Lightning 组件:

    <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>
    

    定义控制器:

    ({
        /*
         * 从 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);        
        },
    })
    

    当我们使用这个 Lightning 组件时,它会自动调用 Vue 应用,然后可以将文字在两个应用之间发送和接收。

    当我们查看页面的源代码时,可以看到,lightning:container 中的内容被放在了一个 iframe 中,所以我们的 Vue 应用其实是封装起来的。

    调用 Apex 函数

    在接下来的应用中,我们要从 Vue 应用中调用 Apex 函数。

    在 Salesforce 中建立 Apex 函数:

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

    为了调用 Apex 函数,我们在 Vue 应用中需要一个特殊的设置。在 “dist” 文件夹下建立一个名为 “manifest.json” 的文件,内容如下:

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

    在 Vue 应用中建立一个名为 “AccountList” 的组件:

    <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>
    

    这样,在用 lightning:container 在 Lightning 组件中执行 Vue 应用时,Vue 应用会直接调用 Apex 函数,然后给出结果。

    与 Locker Service 的比较

    Lightning Container 机制和 Locker Service 机制都是对 Lightning 组件的安全进行提高,将不同来源(命名空间等)的组件分别封装。

    Lightning Container 是基于 iframe 的,它将第三方的组件或应用封装在 iframe 中,而 Locker Service 则不需要这样,它是将不同的组件放在同一个 DOM 树中,将不同的 DOM 元素封装起来。这是两者最大的不同,从而也决定了它们不同的特性:

    • Locker Service 可以利用 Lightning 框架的各种本地功能,而 Lightning Container 中的内容则受到限制,比如只能通过其 NPM 包中提供的 API 函数来进行通信
    • Lightning Container 支持的第三方框架比 Locker Service 更多
    • Locker Service 中的组件执行速度比 Lightning Container 中的要快
    • Locker Service 中的组件和整个 Lightning 框架的外观是一致的,而 Lightning Container 中的内容由于被封装在 iframe 中,在特殊的情况下可能会出现问题

    相关文章

      网友评论

          本文标题:Lightning Container 简介

          本文链接:https://www.haomeiwen.com/subject/qbgxuftx.html