组件传值(vue3)

7,167 阅读1分钟

1、父传子

  • 父组件的 setup 函数里面定义响应式数据 prop,并 return 出来
  • 父组件的模板中通过 :prop="prop" 传递变量给子组件
  • 子组件 通过 props 接收,可以直接在子组件模板中使用
  • 子组件从父组件获取的值是只读的,不能直接修改

父传子:父组件传值

<template>
  <div>
    <p>我是父组件</p>
    <button @click="fn">按钮</button>
    <!-- 使用子组件 -->
    <Son :msg="msg"></Son>
  </div>
</template>

<script>
// 导入子组件
import Son from './components/Son.vue'
import { ref } from 'vue'
export default {
  // 注册子组件
  components: {
    Son
  },
  setup () {
    // 设置父传子的值
    const msg = ref('')
    const fn = () => {
      msg.value = '这是父组件传给子组件的'
    }
    return { msg, fn }
  }
}
</script>

父传子:子组件收值

<template>
  <div>
    <p>我是子组件----{{ msg }}</p>
  </div>
</template>

<script>
export default {
  // 通过 props 接收父组件传过来的值(可以直接在模板中使用)
  // props 也可以是对象接收
  props: ['msg'],
  setup () {
    return {}
  }
}
</script>

2、子传父

  • 父组件绑定自定义事件 :@自定义事件名=“事件处理函数”
  • 子组件在 setup 函数中,在特定时间通过 context.emit('自定义事件名',实参) 触发父组件的自定义函数
  • 父组件收到子组件传递过来的信号后,进行相应处理

子传父:子组件传值

<template>
  <div>
    <p>我是子组件</p>
    <button @click="fn">按钮</button>
  </div>
</template>

<script>

export default {
  // 里面是子传父的事件名,传多个值一定要写,不然会有警告
  emits:['sonHandler']
  // 子传父
  setup (props, context) { // context 这里也可以解构
    const fn = () => {
      context.emit('sonHandler', '这是子组件传给父组件的')
    }
    return { fn }
  }
}
</script>

子传父:父组件收值

<template>
  <div>
    <p>我是父组件---{{ message }}</p>
    <!-- 使用子组件 Son -->
    <Son @sonHandler="sonHandlerFn"></Son>
  </div>
</template>

<script>
// 导入子组件
import Son from './components/Son.vue'
import { ref } from 'vue'
export default {
  // 注册子组件
  components: {
    Son
  },
  setup () {
    const message = ref('')
    const sonHandlerFn = (payload) => {
      message.value = payload
    }
    return { sonHandlerFn, message }
  }
}
</script>

3、跨组件传值(依赖注入 provideinject

  • 父组件利用 provide(键,值) 提供数据
  • 子孙组件利用 inject(键)获取数据(子孙后代, 都可以拿到这个数据)

父传子:父组件 provide

<template>
  <div>
    <p>我是父组件:{{ root }}</p>
    <!-- 使用子组件 -->
    <Son></Son>
  </div>
</template>

<script>
// 导入子组件 Son
import Son from './components/Son.vue'
import { ref, provide } from 'vue'
export default {
  // 注册子组件 Son
  components: {
    Son
  },
  setup () {
    // 准备要传给其他组件的值
    const root = ref('金元宝')
    provide('rootMsg', root)
    return { root }
  }
}
</script>

父传子:子组件 inject

<template>
  <div>
    <p>我是子组件</p>
    <p>传家宝:{{ s }}</p>
    <Sun>我是孙组件</Sun>
  </div>
</template>

<script>
import { inject } from 'vue'
// 导入子组件 Sun
import Sun from './Sun.vue'
export default {
  // 注册子组件 Sun
  components: {
    Sun
  },
  setup () {
    // 通过 inject 接收 父组件传过来的值(父传子)
    const s = inject('rootMsg')
    return { s }
  }
}
</script>

父传孙:孙组件 inject

<template>
  <div>
    <p>我是孙子组件</p>
    <p>传家宝:{{ s }}</p>
  </div>
</template>

<script>
import { inject } from 'vue'
export default {
  // 通过 inject 接收父组件传过来的值 (父传孙)
  setup  () {
    const s = inject('rootMsg')
    return { s }
  }
}
</script>

4、v-model双向传值

  • 父传子
    • 父组件在模板中通过 v-model="prop"传递值给子组件
    • 子组件通过 props对象接收一个对象,固定值 modelValue:{}
    • 在子组件的模板中 使用 modelValue
  • 子传父
    • 子组件在特定时期,通过 context.emit('update:modelValue',实参),更新父组件的 prop

父组件:父传子

<template>
  <div>
    <p>我是父组件==={{count}}</p>
    <button @click="fn">按钮</button>
    <!-- 使用子组件 -->
    <Son v-model="count"></Son>
  </div>
</template>

<script>
// 导入子组件
import Son from './components/Son.vue'
import { ref } from 'vue'
export default {
  // 注册子组件
  components: {
    Son
  },
  setup () {
    // 准备父传子的值
    const count = ref(0)
    const fn = () => {
      count.value++
    }
    return { fn, count }
  }
}
</script>

子组件:子传父

<template>
    <div>
     <p>我是子组件==={{modelValue}}</p>
     <button @click="fn">按钮</button>
    </div>
</template>

<script>
export default {
  // 接收父传子的值
  props: {
    modelValue: { // modelValue 为固定关键字
      type: Number,
      default: 0
    }
  },
  setup (props, { emit }) {//解构过的
    // 子改变父传过来的值
    const fn = () => {
      emit('update:modelValue', 20)
    }
    return { fn }
  }
}
</script>