Набор из девяти методов связи между компонентами Vue.

Vue.js
Набор из девяти методов связи между компонентами Vue.

предисловие

Vue обеспечивает различные коммуникации, в том числе兄弟间общение и非兄弟间Информационный бюллетень, воспользуйтесь этой возможностью, чтобы сделать резюме, легко проконсультироваться. Если вам это нравится, вы можете помочь лайкнуть 👍 или подписаться 😋

1. реквизит

Структура каталогов

components
   ├── Parent.vue   // 父亲
   ├── Son1.vue     // 儿子1

структура кода

Используйте компонент сына в родительском компоненте, дайте сыну пропуск:date="xxx"Стоимость прохода в одну сторону

<template>
  <div>
    <div>爸爸:{{date}}</div>
    <Son1 :date="date"></Son1>
  </div>
</template>
<script>
import Son1 from "./son1";
export default {
  components: { Son1 },
  data() {
    return {
      date: 1,
    };
  },
};
</script>

пропуск компонента сынаpropsПринять значение, переданное от родительского компонента

<template>
  <div>儿子:{{date}}</div>
</template>
<script>
export default {
  props: {
    date: {
      type: Number, //校验类型
      default: "1",
    },
  },
};
</script>

2. $ излучать

Структура каталогов

components
   ├── Parent.vue   // 父亲
   ├── Son1.vue     // 儿子1

структура кода

Дочерние компоненты запускаются касанием их собственных методов$emitметод, а затем активировать метод родительского компонента через回调传参Способ передачи измененного содержимого родительскому компоненту

<template>
  <div>
    <div>儿子:{{date}}</div>
    <button @click="changeNum">修改</button>
  </div>
</template>
<script>
export default {
  props: {
    date: {
      type: Number,
      default: "1",
    },
  },
  methods: {
    changeNum() {
      this.$emit("changeNum", 2);
    },
  },
};
</script>

Родительский компонент принимает обратный вызовparamsпараметр, то есть отцу нужно привязать кастомное событие к сыну,$on("changeNum",params)

<template>
  <div>
    <div>爸爸:{{date}}</div>
    <Son1 :date="date" @changeNum="changeNum"></Son1>
  </div>
</template>
<script>
import Son1 from "./son1";
export default {
  components: { Son1 },
  data() {
    return {
      date: 1,
    };
  },
  methods: {
    changeNum(params) {
      this.date = params;
    },
  },
};
</script>
.sync
Структура каталогов
components
   ├── Parent.vue   // 父亲
   ├── Son1.vue     // 儿子1
структура кода

дочерний компонент через$emit("update:xxx")запуск события

<template>
  <div>
    <div>儿子:{{date}}</div>
    <button @click="changeNum">修改</button>
  </div>
</template>
<script>
export default {
  props: {
    date: {
      type: Number,
      default: "1",
    },
  },
  methods: {
    changeNum() {
      this.$emit("update:date", 2);
    },
  },
};
</script>

родительский компонент через:xxx.sync="xxx"принять параметры

<template>
  <div>
    <div>爸爸:{{date}}</div>
    <Son1 :date.sync="date"></Son1>
  </div>
</template>
<script>
import Son1 from "./son1";
export default {
  components: { Son1 },
  data() {
    return {
      date: 1,
    };
  },
};
</script>
<Son1 :date.sync="date"></Son1>
//这个写法是上面的替代品 默认组件内部触发 update:count 规定写法
<Son1 :date="date" @update:date="val=>date=val"></Son1>
v-model
Структура каталогов
components
   ├── Parent.vue   // 父亲
   ├── Son1.vue     // 儿子1
структура кода

События, запускаемые дочерними компонентами, могут бытьinputсобытие, получитьpropsИмя свойства можно назвать толькоvalue

<template>
  <div>
    <div>儿子:{{value}}</div>
    <button @click="changeNum">修改</button>
  </div>
</template>
<script>
export default {
  props: {
    value: {
      type: Number,
      default: 1,
    },
  },
  methods: {
    changeNum() {
      this.$emit("input", 2);
    },
  },
};
</script>

родительский компонент черезv-modelполучить параметры

<template>
  <div>
    <div>爸爸:{{value}}</div>
    <Son1 v-model="value"></Son1>
  </div>
</template>
<script>
import Son1 from "./son1";
export default {
  components: { Son1 },
  data() {
    return {
      value: 1,
    };
  },
};
</script>
<Son1 :value="value" @input="val=>value=val"></Son1>
//这个写法是上面的替代品 默认组件内部触发 input 规定写法
<Son1 v-model="value"></Son1>

v-modelОграничения могут передавать только одно свойство, если можно использовать только одноv-modelНеобходимо использовать несколько.sync

3.$parent和 $children

Структура каталогов
components
   ├── Parent.vue   // 父亲
   ├── Son1.vue     // 儿子1
   ├── Grandson1.vue  //孙子1
структура кода

Следующий сценарий: внук хочет передать данные дедушке, внуку нужно найти событие на дедушке, чтобы передать$parent.$emit

<template>
  <div>
    <div>孙子{{value}}</div>
    <button @click="$parent.$emit('change',3)">修改</button>
  </div>
</template>
<script>
export default {
  props: {
    value: {
      type: Number,
      default: "",
    },
  },
};
</script>

Дочерний компонент использует дочерний компонент

<template>
  <div>
    <div>儿子:{{value}}</div>
    <grandson1 :value="value"></grandson1>
  </div>
</template>
<script>
import grandson1 from "./grandson1";
export default {
  components: {
    grandson1,
  },
  props: {
    value: {
      type: Number,
      default: 1,
    },
  },
};
</script>

Пользовательское изменение события для внука на папу

<template>
  <div>
    <div>爸爸:{{value}}</div>
    <Son1 @change="val=>value=val" :value="value"></Son1>
  </div>
</template>
<script>
import Son1 from "./son1";
export default {
  components: { Son1 },
  data() {
    return {
      value: 1,
    };
  },
};
</script>

Если иерархия глубокая, то она появится$parent.$parent.....Мы можем инкапсулировать$dispatchспособ отправки вверх

Vue.prototype.$dispatch = function $dispatch(eventName, data) {
  let parent = this.$parent;
  while (parent) {
    parent.$emit(eventName, data);
    parent = parent.$parent;
  }
};

По той же причине, если вы можете искать отца, вы можете искать сына, и вы также можете инкапсулировать метод нисходящего распределения.$broadcast

Vue.prototype.$broadcast = function $broadcast(eventName, data) {
  const broadcast = function () {
    this.$children.forEach((child) => {
      child.$emit(eventName, data);
      if (child.$children) {
        $broadcast.call(child, eventName, data);
      }
    });
  };
  broadcast.call(this, eventName, data);
};

4.$attrs和 $listeners

Структура каталогов
components
   ├── Parent.vue   // 父亲
   ├── Son1.vue     // 儿子1
   ├── Grandson1.vue  //孙子1

$attrsМассовые атрибуты прохода вниз

<template>
  <div>
    <div>爸爸:{{value}}</div>
    <Son1 @change="val=>value=val" :value="value"></Son1>
  </div>
</template>
<script>
import Son1 from "./son1";
export default {
  components: { Son1 },
  data() {
    return {
      value: 1,
    };
  },
};
</script>

Используйте атрибут $attrs в дочернем компоненте сv-bindСвойства могут быть переданы дальше

<template>
  <div>
    <div>儿子:{{$attrs.value}}</div>
    <grandson1 v-bind="$attrs"></grandson1>
  </div>
</template>
<script>
import grandson1 from "./grandson1";
export default {
  components: {
    grandson1,
  },
  mounted() {
    console.log(this.$attrs);
  },
};
</script>

Примечание. При использовании $attrs, если компонент используетсяpropsизменит атрибут с текущегоattrsУдалить

Используйте атрибут $attrs в компоненте grandchild для передачи атрибутов вниз

<template>
  <div>
    <div>孙子{{$attrs.value}}</div>
  </div>
</template>
<script>
export default {
  //props: {
  //  value: Number,
  //},
  mounted() {
    console.log(this.$attrs);
  },
};
</script>

Если отец переходит к элементу сына, сын имеет три атрибута, которые не используются, а внук передает внуку, но не хочет, чтобы этот атрибут был на странице, вы можете установить егоinheritAttrs: false

$listenersПакетный метод нисходящего прохода

<template>
  <div>
    <div>爸爸:{{value}}</div>
    <Son1 @click="change" :value="value"></Son1>
  </div>
</template>
<script>
import Son1 from "./son1";
export default {
  components: { Son1 },
  data() {
    return {
      value: 1,
    };
  },

  methods: {
    change() {
      this.value = 2;
    },
  },
};
</script>

Может использоваться в компоненте son1$listenersатрибут, подходитv-onМетод может продолжать передаваться по наследству

<template>
  <div>
    <div>儿子:{{$attrs.value}}</div>
    <grandson1 v-bind="$attrs" v-on="$listeners"></grandson1>
  </div>
</template>
<script>
import grandson1 from "./grandson1";
export default {
  components: {
    grandson1,
  },
  mounted() {
    console.log(this.$attrs);
    console.log(this.$listeners);
  },
};
</script>

внучатые компоненты могут использоваться напрямую$listenersметод на

<template>
  <div>
    <div>孙子{{$attrs.value}}</div>
    <button @click="$listeners.click"></button>
  </div>
</template>
<script>
export default {
  mounted() {
    console.log(this.$attrs);
    console.log(this.$listeners);
  },
};
</script>

5. Обеспечьте и внедрите

Структура каталогов
app.vue
components
   ├── Parent.vue   // 父亲
   ├── Son1.vue     // 儿子1
   ├── Grandson1.vue  //孙子1
структура кода

объявить общедоступные данные в родительском

export default {
  provide() {
    return { vm: this };
  },
};

Принцип может быть внедрен в подкомпонент, а данные будут смонтированы на текущем экземпляре.

<template>
  <div>
    <div>孙子</div>
  </div>
</template>
<script>
export default {
  inject: ["vm"],
  mounted() {
    console.log(this);
  },
};
</script>

Меры предосторожности: Этот метод сбивает с толку после использования, обычно不会在业务代码中使用, часто в библиотеках компонентов или многоуровневом общении, для удобства можно использоватьprovide.

6. ссылка

Структура каталогов
components
   ├── Parent.vue   // 父亲
   ├── Son1.vue     // 儿子1
структура кода

refПолучается настоящий элемент dom, если его поместить на компонент, он представляет当前组件的实例. Родительский компонент может напрямую получить метод или данные дочернего компонента.

<template>
  <div>
    <div>爸爸</div>
    <Son1 ref="son"></Son1>
  </div>
</template>
<script>
import Son1 from "./son1";
export default {
  components: { Son1 },
  mounted() {
    this.$refs.son.show();
  },
};
</script>
<template>
  <div>
    <div>儿子</div>
  </div>
</template>
<script>
export default {
  methods: {
    show() {
      console.log(1);
    },
  },
};
</script>

Меры предосторожности:refне хочу重名, но только при использованииv-forприведет к возникновению数组условие

7. Шина событий

Структура каталогов
main.js
components
   ├── Grandson1.vue   // 孙子1
   ├── Son2.vue     // 儿子2
структура кода

EventBusможно использовать напо компонентамУведомления (несложные проекты могут использовать этот метод)

Vue.prototype.$bus = new Vue();

Компонент Grandson1 и Son2 взаимодействуют друг с другом

<template>
  <div>孙子1</div>
</template>
<script>
export default {
  mounted() {
    this.$nextTick(() => {
      this.$bus.$emit("test", "go");
    });
  },
};
</script>

Здесь можно использовать только компоненты сына 2$onдля запуска событий компонента Grandson1

<template>
  <div>儿子2</div>
</template>
<script>
export default {
  mounted() {
    this.$bus.$on("test", (data) => {
      console.log(data);
    });
  },
};
</script>

8. Векс

Vuex— это шаблон управления состоянием, разработанный для приложений Vue.js.

Ознакомьтесь с конкретными документами

9. наблюдаемый

Vue.observableВы можете сделать возвращенный объект реактивным, и возвращенный объект можно использовать напрямую.渲染函数а также计算属性и будет запускать соответствующие обновления при возникновении изменений, которые можно использовать как простое хранилище

Структура каталогов
store
   ├── index.js
components
   ├── hello.vue   //函数式组件
   ├── home.vue     
структура кода

store/index.js

import Vue from 'vue';

export const state = Vue.observable({msg:"hello world"});

export const mutation = {
    setMsg(paylod){
       state.msg = paylod
    }
}

Реактивная связь с вычисляемыми свойствамиhome.vue

<template>
  <div @click="handleClick">home332131{{msg}}</div>
</template>
<script>
import { state, mutation } from "@/store";
export default {
  computed:{
    msg(){
        return state.msg
    }
  },
  methods: {
    handleClick() {
      mutation.setMsg("你好,世界");
    },
  },
};
</script>

Реактивная связь с функциями рендерингаhome.vue

<template>
  <div>
      <hello />
  </div>
</template>
<script>
import hello from './hello'
export default {
    components:{
        hello
    },
};
</script>

hello.vue

<script>
import { state, mutation } from "@/store";
export default {
    props:{
        render:Function
    },
     render(h) {
      return h("div",{on:{click:this.handleClick}}, `${state.msg}`);
    },
    methods:{
        handleClick() {
            mutation.setMsg("你好,世界");
        },
    }
}
</script>

конец

Выше приведен весь контент, приветствуются комментарии и указатели, общайтесь и добивайтесь прогресса вместе 🙏🙏🙏🙏