美文网首页
Vue组件的通信方式

Vue组件的通信方式

作者: 未路过 | 来源:发表于2022-09-30 19:28 被阅读0次

    1. 父子组件

    • 父组件传递给子组件:通过props属性
    • 子组件传递给父组件:通过emit触发事件

    1.1 props

    Props:在子组件上注册一些自定义的属性,父组件给这些attribute赋值,子组件通过attribute的名称获取到对应的值
    Props有两种常见的用法:
    方式一:数组,数组的字符串就是attribute的名称
    方式二:对象类型,对象类型我们可以在指定attribute的名称同时,指定它需要传递的类型,是否是必须的,默认值等
    Father.vue

    <template>
      <d>father-test11</d>
      <son-test :receiveFatherTitle="title"></son-test>
      <son-test :receive-father-title="title"></son-test>
      <!--
    以上两个等价
    HTML 中的 attribute 名是大小写不敏感的,所以浏览器会把所有大写字符解释为小写字符;
    这意味着当你使用 DOM 中的模板时,
    camelCase (驼峰命名法) 的 prop 名需要使用其等价的
     kebab-case(短横线分隔命名) 命名
     -->
    </template>
    
    <script lang="ts">
    import { defineComponent, ref } from 'vue'
    import SonTest from './son-test.vue'
    export default defineComponent({
      components: {
        SonTest
      },
      setup() {
        const title = ref('I am father title')
        return {
          title
        }
      }
    })
    </script>
    
    <style scoped></style>
    

    Son.vue

    <template>
      <div>son-test</div>
      <div>{{ receiveFatherTitle }}</div>
      <div>{{ setupTest }}</div>
    </template>
    
    <script lang="ts">
    import { defineComponent, computed } from 'vue'
    
    export default defineComponent({
      props: {
        receiveFatherTitle: {
          type: String,
          required: true,
          default: ''
          //对象和数组默认值必须从一个函数获取,就是default:()=>{}
    //return{}或者return[]
        }
      },
      setup(props) {
        const setupTest = computed(() => props.receiveFatherTitle + ' setup')
        return { setupTest }
      }
    })
    </script>
    
    <style scoped></style>
    
    
    image.png

    setup函数
    第一个参数:props
    是父组件传递过来的属性会被放到props对象中,我们在setup中如果需要使用,那么就可以直接通过props参数获取
    第二个参数: context
    它里面包含三个属性

    1. attrs:所有的非prop的attribute;
    2. slots:父组件传递过来的插槽(这个在以渲染函数返回时会有作用,后面会讲到);
    3. emit:当我们组件内部需要发出事件时会用到emit(因为我们不能访问this,所以不可以通过 this.$emit发出事件);

    setup的返回值可以在模板template中被使用;
    也就是说我们可以通过setup的返回值来替代data选项;

    通过attrs得到所有的非prop的attribute;

    Father.vue

    <template>
      <d>father-test</d>
      <son-test
        :receive-father-title="title"
        id="iddata"
        class="classdata"
        noProps="noPropsData"
      ></son-test>
    </template>
    
    <script lang="ts">
    import { defineComponent, ref } from 'vue'
    import SonTest from './son-test.vue'
    export default defineComponent({
      components: {
        SonTest
      },
      setup() {
        const title = ref('I am father title')
        const noPropsData = ref('noPropsData')
    
        return {
          title,
          noPropsData
        }
      }
    })
    </script>
    
    <style scoped></style>
    
    

    Son.vue

    <template>
      <div>son-test</div>
      <div>{{ receiveFatherTitle }}</div>
      <div>{{ setupTest }}</div>
    </template>
    
    <script lang="ts">
    import { defineComponent, computed } from 'vue'
    
    export default defineComponent({
      props: {
        receiveFatherTitle: {
          type: String,
          required: true,
          default: ''
          //对象和数组默认值必须从一个函数获取,就是return{}或者return[]
        }
      },
      setup(props, context) {
        const setupTest = computed(() => props.receiveFatherTitle + ' setup')
        console.log(context.attrs.class) //classdata
        console.log(context.attrs.id) //iddata
        console.log(context.attrs.noProps) //noPropsData
        return { setupTest }
      }
    })
    </script>
    
    <style scoped></style>
    
    

    1.2 emit

    Father.vue

    <template>
      <div>father-test</div>
      <div>{{ title }}</div>
      <son-test @addOne="incrementOne"></son-test>
    </template>
    
    <script lang="ts">
    import { defineComponent, ref } from 'vue'
    import SonTest from './son-test.vue'
    export default defineComponent({
      components: {
        SonTest
      },
      setup() {
        const title = ref(1)
        const incrementOne = () => title.value++
    
        return {
          title,
          incrementOne
        }
      }
    })
    </script>
    
    <style scoped></style>
    

    Son.vue

    <template>
      <div>son-test</div>
      <button @click="btnClick">plus 1</button>
    </template>
    
    <script lang="ts">
    import { defineComponent } from 'vue'
    
    export default defineComponent({
      emit: ['addOne'],
    
      setup(props, context) {
        const btnClick = () => {
          context.emit('addOne')
        }
    
        return { btnClick }
      }
    })
    </script>
    
    <style scoped></style>
    
    

    非父子组件

    2 provide-inject

    我们用props把数据传递给子组件,子组件通过emit把数据传递给父组件。但是当层级比较多的时候,比如祖先组件和重孙组件需要传递数据,而中间的那些组件不需要,用props和emit就显得有些繁琐了,这时候我们可以用provide和inject。provide提供一个具有名字的变量传递给子孙组件,子孙组件用inject接收同名变量,就能够使用了。


    image.png

    2.1基本使用

    image.png

    2.2 Provide和Inject函数的写法

    image.png

    2.3 处理响应式数据

    image.png

    2.4setup中的使用

    image.png
    image.png

    2.5 数据的响应式

    image.png

    2.6 修改响应式property

    image.png

    3.事件总线

    3.1 全局事件总线mitt库

    image.png

    3.2 使用事件总线工具

    image.png

    3.3 Mitt的事件取消

    image.png

    相关文章

      网友评论

          本文标题:Vue组件的通信方式

          本文链接:https://www.haomeiwen.com/subject/uwcrartx.html