lwc关联笔记(1) 父子互调原则

1.你可以在aura里面使用lwc的componet，你也可以在aura里面触发lwc的方法，或者给lwc赋值
![Image 1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/491095/47581c89-1f76-3bc1-dc3a-bf6f921f2654.png)

反之则不行。你无法在lwc里面使用aura的component。
一般的做法是，在lwc里面通过调用方法获取aura的值进行再表示。

2.你可以在vf里面调用lwc，其调用方法和vf调用aura是一样的

```
vf.page
<apex:page >
    <apex:includeLightning />
    <div id="lightning" />
	<script>
		$Lightning.use("c:lwcVfDemoApp", function() {
        	 $Lightning.createComponent("c:lwcVFDemo", {
            	   objectName: "Contact"
                 },
              "lightning",
              function(cmp) {
                console.log("LWC component was created");
                // do some stuff
              }
          );
        });
    </script>
</apex:page>

```


```
vf.app

<aura:application access="GLOBAL" extends="ltng:outApp">
    <aura:dependency resource="lwcVFDemo"/>
</aura:application>


```



3.lwc当中的父子互调原则
一般的写法如下
父控件只需要调用子控件，并且给子控件的属性或者公共成员赋值就可以了

```ruby:qiita.rb
parent.html
<template>
//这是一种子控件调用父控件函数的方法
//在子控件里注册event，在父控件中，使用on+event名字的写法，
//这里注册的方法将会触发父控件的函数，即括号里面的内容
  <c-child attribute-value={value1}  contact={contact} oncumtomeventname={parentCalledFromChild}/>
//这是第二种调用子控件函数的方法
  <lightning-button variant="brand" label="Submit" onclick={parentFunc}>
  </lightning-button>
<template>

parent.js
import { LightningElement, api } from "lwc";

export default class ParentLwcComponent extends LightningElement {
  //这里使用公共修饰符和前台联动
  @api value1;
 //将这个数据传递给子控件，经过子控件的处理后再重新返回父控件
  @api contact;

  parentCalledFromChild(event) {
  //这里标志着，你是从子控件调用的
  //通过下面的方法你可以获取子控件传过来的参数
  const contactId = event.detail;

  }

  //按下按钮，触发这里的parent方法，在方法里面调用子控件的方法
  parentFunc(){
  this.template.querySelector("c-child").childFunc();
  }


}
```
下面的child控件通过这样的写法就可以实现
parent赋值给child的功能


```ruby:qiita.rb
child.html
<template>
<a href="#" onclick={selectHandler}/>
  {attributeValue}
</template>

child.js
import { LightningElement, api } from "lwc";

export default class childLwcComponent extends LightningElement {
  @api attributeValue;//这里使用公共修饰符和前台联动
//用来接收父控件传来的参数
  @api contact;
//这里必须声明api，否则无法被父控件调用
@api 
childFunc(){
//当父控件触发时就会执行

}

selectHandler(event) {
// Prevents the anchor element from navigating to a URL.
event.preventDefault();

// Creates the event with the contact ID data.
//在声明event的同时，传过去参数,event的名字必须是小写字母
const selectedEvent = new CustomEvent('cumtomeventname', { detail: this.contact.Id });

// Dispatches the event.
this.dispatchEvent(selectedEvent);
}


}




}
```

```ruby:qiita.rb
在这里我们稍加说明一下

单纯从父调用子很容易理解

但是关于注册event那部分却十分繁琐

我们需要理清楚整个生命流程的顺序

1.父控件首先给了子控件一个值，这个值可以是list或者任何类型

2.如果你点击了画面的link或者按钮
   首先，他会去执行子控件的方法，帮你注册一个customEvent
   通过该事件，你就可以调用父控件的方法了
   同时你还可以规定调用父控件时返回什么参数

3.调用了父控件的函数。并且从even.detail里面获取到了子控件传来的参数
   你可以在这之后添加其他的操作



如果用流程图来表示的话，大概是这样的

parent----->child(注册事件)-------->注册事件指向父控件的方法------>parent(调用parent的方法，使用child里的参数)

你会发现，父控件饶了一大圈，结果还是调用了自己，甚至可以说，一开始传递给子控件的数据都是自己的。

所以这么繁琐的做法。究竟优化在哪里？
直接将子控件的代码写入父控件的话，岂不是中间少了很多麻烦。

实际上它的本质在于shadow tree。也就是说，将dom元素分割为互相独立的个体。

这些独立的控件因为是在各自的shadow中，所以他们各自的event都会匹配对应的监听器。

说白了就是，同一个页面里注册的event，可能会互相调用。比如说我们都知道的：

refresh()------------->刷新页面的话，会调用init(),初始化函数。

当然我只是举了一个简单的例子。

实际上这正是lwc的本质，分割，独立，互不干扰。

当然最省事的方法还是一个控件解决。
如果你本身使用的功能和event不复杂的话。

```










4.Shadow DOM
https://developer.salesforce.com/docs/component-library/documentation/en/lwc/lwc.create_dom

通过使用shadow tree，我们可以知道。当你刷新子控件的时候，并不会引发父控件的刷新。