vue3常用的传值方式

1,521 阅读1分钟

今年所有的vue项目都要升级到vue3了,这里写了vue3常用的一些事件和方法

props 传值

父组件传值到子组件

创建子组件ChildComponent

<template>
  <h1>{{msg}}</h1>
  <ul>
    <li v-for="(item, index) in list" :key="index" v-html="item.id +'-'+item.name"></li>
  </ul>
</template>
<script lang="ts">
import { defineComponent } from 'vue'
export default defineComponent({
  props: {
    list: {
      type: Array,
      require: true
    }
  },
  setup () {
    const msg = 'child-组件(props传值)'
    return {
      msg
    }
  }
})
</script>

将子组件导入到父组件,并注册

import ChildComponent from './components/ChildComponent.vue'

components: {
  ChildComponent
},

setup () {
    const msg = 'Vue demo'
    const list = [
      { id: 0, name: '张三' },
      { id: 1, name: '李四' },
      { id: 2, name: '王五' }
    ]
    return {
      msg,
      list
    }
  }

在template中使用

<child-component :list='list'></child-component>

整体代码如下

<template>
  <div id="nav">
    <h1>{{msg}}</h1>
    <child-component :list='list'></child-component>
    <!-- <router-link to="/">Home</router-link> |
    <router-link to="/about">About</router-link> -->
  </div>
  <!-- <router-view/> -->
</template>
<script lang="ts">
import { defineComponent } from 'vue'
import ChildComponent from './components/ChildComponent.vue'
export default defineComponent({
  components: {
    ChildComponent
  },
  setup () {
    const msg = 'Vue demo'
    const list = [
      { id: 0, name: '张三' },
      { id: 1, name: '李四' },
      { id: 2, name: '王五' }
    ]
    return {
      msg,
      list
    }
  }
})
</script>

结果如下

image.png

emit 调用父组件事件

子组件定义emit

template

<li v-for="(item, index) in list" :key="index" v-html="item.id +'-'+item.name" @click="handleClick(item)"></li>

script

emits: ['childSend'],
  setup (props, context) {
    const msg = 'child-组件(props传值)'
    const handleClick = (item: any) => {
      console.log(item)
      context.emit('childSend', '这是捕获到的名字' + item.name)
   }
  return {
      msg,
      handleClick
  }
}

父组件拿到使用自定义的函数

template

 <child-component :list='list' @childSend="childSend"></child-component>
 <h4>{{childMsg.msg}}</h4>

js

import { defineComponent, reactive } from 'vue'

const childMsg = reactive({
      msg: ''
    })
    const childSend = (data: any) => {
      childMsg.msg = data
    }
    return {
      msg,
      list,
      childMsg,
      childSend
    }

这里注意的是使用reactive,这样才能返回响应式的副本参数。

ref - 调用子组件事件

template

<button @click="childClick">点击子组件的事件</button>
<child-component ref="sonRef" :list='list' @childSend="childSend"></child-component>

js

import { defineComponent, reactive, ref } from 'vue'
const sonRef = ref()
const childClick = () => {
  sonRef.value.refson('通过父组件调用的子组件事件')
}
return {
  childClick,
  sonRef
}

子组件中定义父组件调用的事件

// html
 <h4>{{msgObj.parentMsg}}</h4>
 
//js
const msgObj = reactive({
   parentMsg: ''
})
const refson = (value:any) => {
   msgObj.parentMsg = value
}
return {
  msg,
  handleClick,
  refson,
  msgObj
}

结果如下:

image.png

Provide / Inject

在父组件中引用方法 provide 函数允许你通过两个参数定义 property:name, value

import { defineComponent, reactive, ref, provide } from 'vue'

const location = ref('North Pole')
const geolocation = reactive({
  longitude: 10,
  latitude: 125
})
provide('location', location)
provide('geolocation', geolocation)

点击事件

methods: {
    handleInject () {
      this.location = 'North Pole North Pole'
      this.geolocation.longitude = this.geolocation.longitude + 1
      this.geolocation.latitude = this.geolocation.latitude + 1
    }
}

子组件,在vue中显式引入inject, 函数有两个参数: name和默认值

const userLocation = inject('location', 'The Universe')
const userGeolocation = inject('geolocation')
return {
  userLocation,
  userGeolocation
}

点击事件前

image.png

点击事件后

image.png

未完待续。。。。。