目录
一、父子通信
1.父传子( defineProps)
2.父传子(useAttrs)
3.子传父(ref,defineExpose )
4.子传父(defineEmits)
5.子传父(v-model)
二、祖孙通信
1.祖传孙(provide/inject)
三、任意关系通信
1.mitt
2.vuex / pinia
3.浏览器缓存
四、路由跳转通信
1.query传参
2.params传参
3.state传参
一、父子通信
1.父传子( defineProps)
在子元素里面使用defineProps接收父元素传过来的参数。
父组件:
<template>
<child :data="data"></child>
</template>
<script setup>
import { ref } from 'vue'
import child from './child.vue'
const data= ref('传个参')
</script>
子组件:
<template>
<div>{{ props.data}}</div>
</template>
<script setup>
import { defineProps } from 'vue'
const props = defineProps({ //接收父组件传过来的参数
data: {
type: String,
default: '',
},
})
</script>
2.父传子(useAttrs)
父传给子参数,props参数(指 :data="参数")由defineProps接收,但非props参数(指 data="参数" 少了:)由useAttrs接收。
父组件:
<template>
<child :name="参数" data="666"/>
</template>
<script setup>
import child from './child.vue'
</script>
子组件:
<template>
<div>
{{ props.name }} // '参数'
</div>
</template>
<script setup>
import { defineProps, useAttrs } from 'vue'
const props = defineProps({
name: {
type: String
}
})
const myattrs = useAttrs()
console.log(myattrs) // { "data": "666" }
</script>
3.子传父(ref,defineExpose )
此方法是通过,父组件调用子组件抛出的的方法和参数来进行传参的。
子组件:
<template>
<div></div>
</template>
<script setup>
import { defineExpose } from "vue"
const chileMethod = () =>{
console.log("我是方法")
}
const name = ref('参数')
defineExpose({ // 对外暴露
name,
chileMethod
})
</script>
父组件:
<template>
<child ref="myref"></child>
<button @click="myClick">点击</button>
</template>
<script setup>
import child from "./child.vue"
import { ref } from "vue"
const myref = ref(null)
const myClick = () => {
console.log(myref.value.name) // 直接获取到子组件的属性
myref.value.chileMethod() // 直接调用子组件的方法
}
</script>
4.子传父(defineEmits)
在子元素里面使用defineEmits接收父元素里面的方法,并通过调用方法将参数传给父元素。
子组件:
<template>
<div ></div>
</template>
<script setup>
import { ref, defineEmits } from 'vue'
const data = ref('传个参')
const emits = defineEmits(['addEvent']) //addEvent是父元素里面的一个函数方法,通过这个方法传参
const handleSubmit = () => {
emits('addEvent', data.value)
}
</script>
父组件:
<template>
<child @addEvent="handle"></child>
</template>
<script setup>
import { ref } from 'vue'
import child from './child.vue'
const handle = value => {
console.log(value); // '传个参'
}
</script>
5.子传父(v-model)
v-model其实语法糖,如下两行代码作用是一样, 上面是下面的简写。
<chile v-model:title="title" />
<chile :title="title" @update:title="title = $event" />
父组件:
<template>
<child v-model:name="name" v-model:num="num"></child>
</template>
<script setup>
import child from "./child.vue"
import { ref, reactive } from "vue"
const name = ref("参数")
const num = ref("666")
</script>
子组件:
注意:update:是固定写法。
<template>
<button @click="clickEvent">点击</button>
</template>
<script setup>
import { defineEmits } from "vue"
const emit = defineEmits(["name","num"])
// 子组件更新参数
const clickEvent = () => {
emit("update:name", "孙悟空")
emit("update:num", "999")
}
</script>
二、祖孙通信
1.祖传孙(provide/inject)
这个祖传孙也包括了父传子。provide和inject叫依赖注入,是vue官方提供的API,它们可以实现多层组件传递数据,无论层级有多深,都可以通过这API实现。
祖组件:
<template>
<div></div>
</template>
<script setup>
import { ref, provide } from 'vue'
const name = ref('参数')
// 向后代组件提供数据, 只要是后代都能接收
provide('name', name.value)
</script>
孙组件:
<template>
<div>{{ name }}</div>
</template>
<script setup>
import { inject } from 'vue'
// 接收顶层组件的通信
const name = inject('name')
</script>
三、任意关系通信
1.mitt
首先下载 npm 包
npm install --save mitt
在main.js文件进行全局挂载, $bus是自定义属性名:
import mitt from "mitt"
const app = createApp(App)
app.config.globalProperties.$bus = new mitt()
传参出去的组件:
<script setup>
import mitt from 'mitt'
const emitter = mitt()
emitter.emit('自定义的事件名称','参数')
</script>
接收参数的组件:
<script setup>
import mitt from 'mitt'
const emitter = mitt()
emitter.on('自定义的事件名称', '参数' )
</script>
2.vuex / pinia
后续会出一个专门的文章讲解这部分。
3.浏览器缓存
- sessionStorage(临时存储):为每一个数据源维持一个存储区域,在浏览器打开期间存在,包括页面重新加载
- localStorage(长期存储):与 sessionStorage 一样,但是浏览器关闭后,数据依然会一直存在
// 存储数据
localStorage.setItem('key', 'value');
sessionStorage.setItem('key', 'value');
// 获取数据
const valueFromLocalStorage = localStorage.getItem('key');
const valueFromSessionStorage = sessionStorage.getItem('key');
// 删除数据
localStorage.removeItem('key');
sessionStorage.removeItem('key');
// 清空所有数据
localStorage.clear();
sessionStorage.clear();
四、路由跳转通信
1.query传参
传递参数:
import router from "@/router";
const query = { id: 666, name: '参数' }
router.push({ path: '/user', query })
接收参数:
import { useRoute} from 'vue-router'
const route = useRoute()
console.log(route.query)
2.params传参
传递参数:
router.push({
name: 'test',
params: {
name: '参数'
}
})
接收参数:
import { useRoute} from 'vue-router'
const route = useRoute()
console.log(route.params) // { name: '参数' }
3.state传参
传递参数
<script setup>
import { useRouter } from 'vue-router'
const router = useRouter();
router.push(
{
path: "/project",
state:
{
data:JSON.stringify(json)
}
})
<script>
接收参数:
<script setup>
import { ref } from "vue";
const tableData = ref([]);
if (history.state.data) {
tableData.value = JSON.parse(history.state.data)
}
<script>