AVR组件常用的通信方式

angular,vue,react,组件通信,props,事件

AVR组件常用的通信方式

父组件向子组件传递数据,子组件执行父组件方法

  1. angular
// list.component.ts
@Component({
  selector: "app-list",
  template: `
    <div>当前选择的是:{{ curUrl.name || "-" }}</div>
    <ul>
      <list-item
        *ngFor="let url of urls"
        [url]="url"
        (selected)="onSelected($event)"
      ></list-item>
    </ul>
  `,
  styleUrls: ["./app.component.css"]
})
export class ListComponent {
  curUrl = {} as Url;
  urls = [
    {
      name: "岁月无痕",
      href: "https://chenggang.win"
    },
    {
      name: "tb",
      href: "https://taobao.com"
    }
  ];
  onSelected(url: Url) {
    this.curUrl = url;
  }
}

// list-item.component.ts
@Component({
  selector: "list-item",
  template: `
    <li (click)="selectUrl(url)">{{ url.name }}</li>
  `,
  styles: [
    `
      li {
        list-style: none;
        color: green;
        cursor: pointer;
      }
    `
  ]
})
export class ListItemComponent {
  @Input() url: Url;
  @Output() selected = new EventEmitter<Url>();

  selectUrl(url: Url) {
    this.selected.emit(url);
  }
}

  1. vue
// List.vue
<template>
  <div>
    <div>当前选择的是:{{curUrl.name || '-'}}</div>
    <ul>
      <list-item v-for="url in urls" :key="url.name" :url="url"></list-item>
    </ul>
  </div>
</template>

<script lang="ts">
import * as Vue from "vue";
import * as ListItem from "./ListItem.vue";

export default Vue.extend({
  name: "List",
  components: {
    ListItem
  },
  data() {
    return {
      curUrl: {},
      urls: [
        {
          name: "岁月无痕",
          href: "https://chenggang.win"
        },
        {
          name: "tb",
          href: "https://taobao.com"
        }
      ]
    };
  },
  methods: {
    onSelected(url: ListItem.Url) {
      this.curUrl = url;
    }
  }
});
</script>


// ListItem.vue
<template>
  <li @click="selectUrl(url)">{{url.name}}</li>
</template>
<script lang="ts">
import * as Vue from "vue";

export type Url = {
  name: string;
  href: string;
};

export default Vue.extend({
  name: "ListItem",
  props: {
    url: {
      default: () => ({
        name: "",
        href: ""
      }),
      type: Object
    }
  },
  methods: {
    selectUrl(url: Url) {
      this.$emit("selected", url);
    }
  }
});
</script>
<style lang="scss" scoped>
li {
  list-style: none;
  color: green;
  cursor: pointer;
}
</style>

另外,vue还可以通过$children / $parent

  1. react
// List.tsx
const urls: Url[] = [
  {
    name: "岁月无痕",
    href: "https://chenggang.win"
  },
  {
    name: "tb",
    href: "https://taobao.com"
  },
];

export const List: React.FC = () => {
  const [curUrl, setUrl] = React.useState("-");
  return (
    <div>
      <div>当前选择的是:{curUrl}</div>
      <ul>
        {urls.map(url => {
          return <ListItem key={url.name} url={url} selected={setUrl} />;
        })}
      </ul>
    </div>
  );
};

// ListItem.tsx
export type Url = {
  name: string;
  href: string;
};
type Props = {
  url: Url;
  selected: (name: string) => void;
};
export const ListItem: React.FC<Props> = ({ url, selected }) => (
  <li style={liStyle} onClick={e => selected(url.name)}>
    {url.name}
  </li>
);

总结

  • 父组件利用props传递数据,子组件接收props得到数据 props down
  • 父组件注册事件监听(即传递的props是方法),子组件触发事件(即执行方法)events up

跨组件通信

  1. angular

    • 共享service
    • @ViewChild或模板变量,获取组件实例
  2. react

    • context
    • 第三方状态管理库(redux等)
    • ref/refs获取组件实例
  3. vue

    • 根组件上添加属性,然后可以通过this.$root.xxx访问
    • eventBus即全局事件总线
    • ref/refs获取组件实例
    • 状态管理库(vuex等)

component-interaction
prop
passing-data-through-props
angular-interact
vue-interact
react-interact