In the vue project, index.html data communicates with components, passing values, for example, to get a MAC address

Keywords: Javascript Mac Vue

Recently, I took over other people's code in my project to improve it. One of them is to fix the bug that can't get the MAC address. I looked closely at the code and found that I need to use Activex control.

The last colleague wrote <object></object> in the index.html file while writing, and the js code to get the mac address was also written in index.html, which was saved in the localStorage after reading, but there is a problem. This Activex control is an asynchronous operation to get the mac address. If you get the mac address for the first time and cache information without the mac address, you will get an error.

The key point of this modification is how to turn this asynchronous operation into a synchronous operation, or when the control gets mac and propagates to the component, the component does the corresponding action.

So how the data that evolves into an index.html file communicates with the components.

Now that you have found the key point, solve the problem!

We all know that there are several ways to communicate within a vue component:

Child->parent component communication: child component $on, parent component $emit;

Parent->child component communication: the child component defines props, and the parent component passes values to the child component through props when it uses the child component;

Brothers or parallel components: Define an eventBus, introduce eventBus, and communicate through $on and $emit of eventBus;

If the project is large, vuex is recommended for communication.

The above methods do not seem to work in index.html unless they are bound to a window object...

So make a change,

In the main.js file:

window.eventBus = new Vue();

Next we print eventBus on the script tag in index.html:

Very good, just print it out.

index.html file, insert in the body tag:

<object classid="CLSID:76A64158-CB41-11D1-8B02-00600806D9B6" id="locator" style="display:none;visibility:hidden"></object>
<object classid="CLSID:75718C9A-F029-11d1-A1AC-00C04FB6C223" id="foo" style="display:none;visibility:hidden"></object>

script code:

<script FOR="foo" EVENT="OnObjectReady(objObject,objAsyncContext)" LANGUAGE="JScript">
  var IPEnabled = objObject.IPEnabled;
  var IPAddress = objObject.IPAddress(0);
  if (IPEnabled != null && IPEnabled != "undefined" && IPEnabled == true ) {
    if (IPAddress) {
      window.sIPAddr = objObject.IPAddress(0);
    }
    if (objObject.MACAddress) {
      window.sMacAddr = objObject.MACAddress;
    }
    if (objObject.DNSHostName) {
      window.sDNSName = objObject.DNSHostName;
    }
  }
</script>
<script FOR="foo" EVENT="OnCompleted(hResult,pErrorObject, pAsyncContext)" LANGUAGE="JScript">
  // console.log("Success in getting mac address:", sMacAddr);
  window.eventBus.$emit('getMac', window.sMacAddr);
</script>

Method in vue component:

clickPort() {
  var userAgent = navigator.userAgent;
  if (userAgent.indexOf(".NET") > -1 && userAgent.indexOf("NT 10.0") > -1) {
    var service = locator.ConnectServer(); // eslint-disable-line
    service.Security_.ImpersonationLevel = 3;
    service.InstancesOfAsync(foo, "Win32_NetworkAdapterConfiguration"); // eslint-disable-line
  }
  eventBus.$off('getMac'); // Close last listening
  eventBus.$on('getMac', (_mac) => {
    alert(`Obtain MAC Address: ${_mac}`);
    this.msg = _mac;
  });
}

ok, execute one:

Success!

This is the first method, using eventBus, remember to turn off the last listening when using eventBus

Here is the second method:

How do I assign values to components in index.html?Or how do I call a method in a component?

Using the same principle, you can bind this to window s.

Up Code,

Components:

clickPort() {
  var userAgent = navigator.userAgent;
  window.thisComponent = this; // Assign component instance to a global variable
  if (userAgent.indexOf(".NET") > -1 && userAgent.indexOf("NT 10.0") > -1) {
    var service = locator.ConnectServer(); // eslint-disable-line
    service.Security_.ImpersonationLevel = 3;
    service.InstancesOfAsync(foo, "Win32_NetworkAdapterConfiguration"); // eslint-disable-line
  }
}

index.html:

<script FOR="foo" EVENT="OnCompleted(hResult,pErrorObject, pAsyncContext)" LANGUAGE="JScript">
  // First determine if window.thisComponent.componentThis is a vue component instance
  if (window.thisComponent) {
    // Give the mac address a property of the instance
    window.thisComponent.sMacAddr = window.sMacAddr;
    // Empty to avoid memory leak;
    window.thisComponent = null;
    // console.log(window.componentThis);
  }
</script>

Run one:

No problem, and show it directly in the template;

Using the second method, the sMacAddr field needs to be initialized in the component's data function, otherwise it will not be shown in the template and will be window.thisComponent.sMacAddr in the index.html file, where the sMacAddr field must match the field initialized in the component

Summary:

No matter which way you use it, you have to take advantage of the object window; this is also impossible, in fact, using the same principle, it is also bound directly to the instance of VUE;
All roads lead to Rome, and my younger brother offers a little skill.

Article Reference: https://blog.csdn.net/zyw_anq...

Welcome to upload, please note the source! https://segmentfault.com/a/11...

Posted by rapmonkey on Sun, 28 Apr 2019 13:10:37 -0700