8 способов взаимодействия компонентов Vue

Vue.js
8 способов взаимодействия компонентов Vue

предисловие

После полугодовой работы над системой компании, позавчера она наконец была запущена. Исправление ошибок в более позднем периоде заняло слишком много времени.Большинство появившихся ошибок были вызваны асимметрией информации фронтенда и бэкенда.Логических ошибок было не так много,да и пользовательский опыт был чуть хуже.В конце концов , это был первый раз, когда я делал такую ​​большую систему (100 Вт +), благодаря разработке этой системы я обобщил большой опыт, как лучше сотрудничать с бэк-энд персоналом в разработке и как проектировать для улучшения пользовательский опыт.Я не обращал внимания на этот аспект, когда сам разрабатывал, и сосредоточился только на реализации функции.Это больше, чем дополнение.

После запуска проекта следующий шаг - обслуживание и обновление системы.В последнее время времени наконец-то не так много, как раньше, поэтому я просто пересмотрел систему. Поскольку стек технологий, принятый в проекте,Vue, Обычно разработка фокусируется только на реализации функции, и следующим шагом будет VueУглубленный анализ для инкапсуляции общих бизнес-компонентов иVue源码解析

Эта глава будет кратким изложением методов коммуникации компонентов Vue 8. Ежедневная разработка коммуникации компонентов близка, и знакомство с коммуникацией компонентов может лучше развивать бизнес.

VueПередача значений между компонентами

1. Родительские компоненты передают значение подкомпоненту

    1. Внедрение дочерних компонентов в родительские компоненты
    1. Зарегистрировать дочерние компоненты
    1. Используется на странице, динамическая привязка тега подкомпонента для передачи динамического значения/статического значения.
    1. В дочернем компоненте используйте propsпринять 父组件переданное значение

Значение родительского компонента, полученное дочерним компонентом, делится на два типа: ссылочный тип и общий тип:

  • Общие типы: строка, число, логическое значение, нуль
  • Типы ссылок: массив, объект
#父组件

<template>
  <div>
    <!-- 传递值 -->
    <Test
     :obj="obj" 
     info="测试"/>
  </div>
</template>

<script>
// 引入子组件
import Test from "../components/Test.vue";
export default {
  name: "about",
  // 注册子组件
  components: {
    Test,
  },
  data() {
    return {
      obj: {
        code: 200,
        title: "前端自学社区",
      },
    };
  },
};
</script>

<template>
    <div>
        <h1>{{obj.code}}</h1><br>
        <h2>{{obj.title}}</h2>
        <h3>{{info}}</h3>
    </div>
</template>

<script>
    export default {
        name:'test',
        props:{
            obj:Object,
            info: [String,Number]  //info值为其中一种类型即可,其他类型报警告
        }
    }
</script>

из-за Vueоднонаправленный поток данных, 子组件не может быть изменено напрямую 父组件значение.

2. Дочерние компоненты передают значения родительским компонентам

Подкомпоненты связывают события через this.$emit('函数名',传递参数)

#父组件

<Test
     :obj="obj" 
     info="测试"
     @modify="modifyFatherValue"/>

<script>
// 引入子组件
import Test from "../components/Test.vue";
export default {
  name: "about",
  // 注册子组件
  components: {
    Test,
  },
  data() {
    return {
      msg:'我是父组件'
    };
  },
  methods:{
    // 接受子组件传递来的值,赋值给data中的属性
    modifyFatherValue(e){
      this.msg = e
    }
  }
};
</script>
# 子组件

<button @click="modifyValue">修改父组件的值</button>


<script>
    export default {
        name:'test',
        methods:{
            modifyValue(){
                this.$emit('modify','子组件传递过来的值')
            }
        }
    }
</script>

3. Родительский компонент передается $refs / $children чтобы получить значение дочернего компонента

$refs :

  • Получите элемент DOM и экземпляр компонента, чтобы получить свойства и методы компонента.

  • Привязка к дочерним компонентом ref,использовать this.$refs.refName.子组件属性 / 子组件方法

$children :

  • Дочерний компонент текущего экземпляра, который возвращает коллекцию дочерних компонентов. Если вы хотите получить свойства и методы компонента, вы можете передать this.$children[index].子组件属性/f方法

Пример текстового компонента

<script>
    export default {
        name:'test',
        data() {
            return {
                datas:"我是子组件值"
            }
        },
        props:{
            obj:Object,
            info: [String,Number]
        },
        methods:{
            getValue(){
                console.log('我是Test1')
            }
        }
    }
</script>

Пример компонента Text2

<template>
    <div>
        <h1>我是Test2</h1>
    </div>
</template>

<script>
    export default {
        name:'test',
        data() {
            return {
                datas:"我是Test2"
            }
        },
        created(){
         console.log( this.$parent.obj ) 
         this.$parent.getQuery()
        },
        methods:{
            getTest2(){
                console.log(this.datas)
            }
            
        }
    }
</script>

refs

<template>
  <div>
   // 给子组件上绑定 ref  
    <Test
      ref="son"
    />
   <Test2/>
  </div>
</template>

// 通过 $refs 示例来获取 子组件的属性和方法

 console.log( this.$refs.son.datas) 

 this.$refs.son.getValue()

$children

//  通过 $children  来获取 子组件的属性和方法
      this.$children[0].getValue(); // 我是 Test1
      this.$children[1].getTest2();  //我是 Test2
      console.log(`---------${this.$children[1].datas}`); //我是Test2

4. Подкомпоненты пройдены $parentчтобы получить свойства и методы экземпляра родительского компонента

<script>
    export default {
        name:'test',
        created(){
         console.log( this.$parent.obj ) 
         this.$parent.getQuery()
        },
        
    }
</script>

5. $attrsа также $listenersПолучить свойства и методы экземпляра родительского компонента (используются, когда компоненты вложены)

$attrs: содержит не рассматриваемые (и не ожидаемые) в родительской области propsпривязки функций (кроме класса и стиля), доступ к которым можно получить через v-bind=". $attrs" передается во внутренний компонент. Когда компонент не объявляет никаких props, он включает все привязки родительской области (кроме класса и стиля).

$listeners: содержит прослушиватель событий v-on в родительской области (без модификатора .native). Доступ к нему можно получить через v-on=”$listeners" передается во внутренний компонент. Это объект, содержащий все прослушиватели событий, действующие на этот компонент, что эквивалентно дочернему компоненту, наследующему события родительского компонента.

Сценарий использования: Используйте в случае многоуровневых вложенных компонентов, вы можете избежать использования Vuex для обработки данных, используйте v-bind="$attrs" v-on="$listeners"Это очень удобно для передачи бизнес-данных.

родительский компонент

<template>
    <div>
        <Test3  
        :status="status" 
        :title="title"
        @getData="getData" />
    </div>
</template>

<script>
import Test3 from "../components/Test3.vue";
    export default {
        name:'person',
        data(){
            return {
                title:'personal 组件',
                status: false
            }
        },
        methods:{
          getData(){
              console.log(this.title)
          }  
        },
        components:{
            Test3
        }
    }
</script>

подкомпонент 1

<template>
  <div>
    <h1>Test3 组件</h1>
    <br /><br />
    // 通过 $attrs(属性,除了【props中定义的属性】)  和 $listeners(方法)  来给嵌套子组件传递父组件的属性和方法
    <Test4   v-bind="$attrs" v-on="$listeners"/>
  </div>
</template>

<script>
// 引入子子组件   
import Test4 from "../components/Test4";
export default {
  name: "test3",
  props: ["title"],
  components: {
    Test4,
  },
  created() {
    console.log(this.$attrs);  //{status: false}
    console.log("-----------");
    console.log(this.$listeners); // {getData: ƒ}
  },
};
</script>

Вложенные дочерние компоненты

<template>
    <div>
        <h1>Test4 组件</h1>
    </div>
</template>

<script>
    export default {
        name:'test4',
        created(){
            console.log('-----Test4------')
            console.log(this.$attrs) //{status: false}
            console.log(this.$listeners) // {getData: ƒ}
        }
    }
</script>

6. Передача значений между компонентами

путем создания нового jsфайл, импорт vue, экспорт vueэкземпляр; затем привязать события к экспортированному экземпляру с помощью $emitсобытие, а затем через $onПрислушивайтесь к инициированным событиям, чтобы обеспечить общий доступ к глобальным компонентам.

используемые сцены:

Он может удовлетворить любой сценарий для передачи данных, 父子组件传值 , 子父传值 , 兄弟组件之间传值 , 跨级组件之间传值 .

Когда данные связи относительно просты, эта схема может быть использована, а проект относительно большой и может быть использован Vuex .

vue .js

/*
 * @Description: 
 * @Author: ZhangXin
 * @Date: 2021-01-22 15:48:56
 * @LastEditTime: 2021-01-22 15:51:24
 * @LastEditors: ZhangXin
 */

 import Vue from 'vue'

 export default new Vue()

Компонент А

<!--
 * @Description: 
 * @Author: ZhangXin
 * @Date: 2021-01-22 14:44:17
 * @LastEditTime: 2021-01-22 16:25:33
 * @LastEditors: ZhangXin
-->

<template>
    <div>  
        <button @click="changeValue">改变</button>
    </div>
</template>

<script>
import zxVue from '../util/newVue.js';
    export default {
        name:'person',
        data(){
            return {
                title:'personal 组件',
                status: false
            }
        },
        methods:{
          changeValue(){
             // 通过给 vue实例绑定事件
             zxVue.$emit("getTitle", this.title)   
          }  
        }
    }
</script>



компонент С

<!--
 * @Description: 
 * @Author: ZhangXin
 * @Date: 2021-01-22 15:07:30
 * @LastEditTime: 2021-01-22 16:26:38
 * @LastEditors: ZhangXin
-->
<template>
  <div>
    <h1>Test4 组件</h1>
    <h1>{{ title }}</h1>
  </div>
</template>

<script>
import zxVue from "../util/newVue";
export default {
  name: "test4",
  data() {
    return {
      title: "test4",
    };
  },
  mounted(){
    // 通过 vue 实例.$on  监听事件名,来接收跨级组件传递过来的值
    zxVue.$on("getTitle", (item) => {
      this.title = item;
      console.log(item)
    });

  }
};
</script>

7. Vuex

Я не буду представлять это здесь, я напишу отдельную статью после того, как закончу. Vuex

8. provideа также injectРеализуйте родительские компоненты для передачи значений компонентам-потомкам. (Неограниченный уровень)

provideа также injectЭту пару опций необходимо использовать вместе, чтобы позволить компоненту-предку внедрить зависимость во все его потомки, независимо от того, насколько глубока иерархия компонентов, и она всегда будет действовать, пока устанавливаются отношения восходящего и нисходящего потоков.

provide :

  • это объект или функция, которая возвращает объект

  • Этот объект содержит свойства, которые можно внедрить в его потомков.

inject :

  • массив строк или объект

  • Используется для внедрения в дочерние или дочерние компоненты provideПредоставленные свойства родительского компонента.

используемые сцены:

provide/inject可以轻松实现跨级访问父组件的数据

# provide
//对象
provide:{
    name:'测试'
}
//返回对象的函数
provide(){
    return {
        name: '测试'
    }
}

#inject
inject:['name']

родительский компонент

<!--
 * @Description: 
 * @Author: ZhangXin
 * @Date: 2021-01-22 23:24:16
 * @LastEditTime: 2021-01-22 23:49:50
 * @LastEditors: ZhangXin
-->
<template>
    <div>
        <h1>我是父组件</h1>
        <Son />
    </div>
</template>

<script>
import Son from '../components/son/SonOne'
    export default {
        name:'father',
        provide(){
            return {
                titleFather: '父组件的值'
            }
        },
        components:{
            Son
        },
        data(){
            return{
                title:'我是父组件 '
            }
        },
        
    }
</script>


Подсборка

<template>
    <div>
        <h1>我是子孙组件</h1>
       
    </div>
</template>

<script>
import SonTwo from '../son/SonTwo'
    export default {
        name:'sonone',
        components:{
           SonTwo
        },
        inject:['titleFather'],
        created(){
             console.log(`${this.titleFather}-----------SonTwo`)
        },
        data(){
            return{
                title:'我是子组件 '
            }
        },
        
    }
</script>

компонент-потомок

<template>
    <div>
        <h1>我是子孙组件</h1>
       
    </div>
</template>

<script>
import SonTwo from '../son/SonTwo'
    export default {
        name:'sonone',
        components:{
           SonTwo
        },
        inject:['titleFather'],
        created(){
             console.log(`${this.titleFather}-----------SonTwo`)
        },
        data(){
            return{
                title:'我是子组件 '
            }
        },
        
    }
</script>

Эпилог

❤️Подписывайтесь + лайк + избранное + комментарий + пересылка ❤️, оригинальность непроста, поощряйте автора создавать лучшие статьи

  • Подпишитесь на официальный аккаунт Front-end Self-Learning Community, чтобы получать больше качественных статей о front-end!

  • Подписавшись на ключевое слово «добавить группу» и ответив на него, вы можете присоединиться к «группе обмена самообучающимися интерфейсами», чтобы учиться и развиваться вместе.

  • После подписки добавьте меня в WeChat и втяните в группу технического обмена.

  • Добро пожаловать, чтобы обратить внимание на официальный аккаунт, более интересные статьи публикуются только на официальном аккаунте.