适用于: 父向子传递参数、方法, 子触发父传递的方法
props方式组件通信和vue2中的props传参类似,只是使用方式和接收方式有一些区别。
注意点: 通过props方式传递的参数为只读属性,不可修改
父组件
父组件
子组件
子组件
玩具:{{ toy }}
父亲的车:{{ car }}
// 父组件
// 子组件
// 通过 defineEmits 接收父组件传递来的方法
const emit = defineEmits(['set-toy-fn'])
// 调用方法 emit('方法名',参数1,参数2...)
emit('set-toy-fn','玩具')
import mitt from "mitt";
// 调用mitt得到emitter ,emitter能绑定事件、触发事件
const emiiter = mitt()
// 四个api: all-操作所有事件 emit-触发事件 off-解绑事件 on-绑定某一个事件
export default emiiter
组件A :绑定事件-接收数据
import { ref } from 'vue'
import emitter from "@/utils/emitter.ts";
let num = ref(0)
// 绑定事件
emitter.on('getData',(data)=>{
num.value ++
console.log('拿到了数据:',data);
if(num.value==3){
emitter.off('getData');// 解除绑定
}
})
组件B:触发事件-传递数据
import { ref,reactive } from 'vue'
import emitter from "@/utils/emitter.ts";
let info = reactive({
userName:'张三',
userId:'007'
})
let toy = ref('小猪佩奇')
function toData() {
// 触发事件并传递参数
emitter.emit('getData',{info ,toy})
}
这种方式可以参考Vue3-在HTML标签、组件标签上使用v-model,这里就不再详述
$attrs:父组件通过props向子组件传参时,子组件未声明接收的值。通过$attrs接收到的参数是只读的
父组件
父组件
b:{{ b }}
子组件
// 子组件 在子组件中不对父组件传递的参数做任何操作
// 传递的方法值不在页面中显示 但是可以直接通过 $attrs.方法名 调用
子组件
{{ $attrs }} // { "a": 1, "b": 2, "c": 3, "d": 4 }
{{ $attrs.addA }} // function addA(num = 1) { a.value += num; }
孙组件
孙组件
$attrs的值:{{$attrs}}
// { "b": 2, "c": 3, "d": 4 }
// 此处为ts的类型断言,ts不能确定$attrs上面的addA是一个方法
注意:此种方式只能在组件模板中拿到$refs和$parent的值。并且$refs获取不到孙组件
父组件 :在组件模板中拿到$refs并当做参数传递使用
父组件sum值:{{ sum }}
子组件sum值:{{ sum }}
说明:父组件通过provide暴露数据,任意一级子组件都可以直接通过inject获取数据,数据为响应式
注意:通过provide传递ref定义的数据时,不要加 .value 否则数据会失去响应式
import { provide, reactive } from 'vue'
import Children from "./children.vue";
let info = reactive({
label:'父组件',
str:'数据'
})
function changeInfo(){
info.str += '-小猪'
}
//格式 provide('参数名',参数值)
provide('provideData',{info,changeInfo})
// 格式 inject('接收的参数名',参数的默认值) // 默认值可有可无 有函数或对象类型时建议写
// let {info,changeInfo} =inject('parentData')
let {info,changeInfo} = inject('parentData',{info:{str:'',label:''},changeInfo:()=>{}})
function changParentInfo(){
// 可以直接对接收到的值进行修改,数据是响应式的
info.str+='-大猪'
}
父组件-在子组件标签中编写需要插入的代码
数据
子组件-写slot标签标识插槽的位置(如果父组件未传递插槽内容,就会显示slot中的默认内容)
默认内容
父组件 :给插槽内容命名,插入到指定name的slot标签中,如果没有对应name的标签就不插入
// 命名方式 v-slot:插槽名 或 #插槽名
// 写法一:直接在组件标签上命名 不推荐
数据1
// 写法二:在template上命名
数据2
数据2
子组件:给slot标签加上name作为标识
默认内容
默认内容
子组件
c1默认内容
父组件
插槽传递的参数:{{ params }}
//params={ "str": "字符串str", "a": "哈哈" }
在main.ts文件中修改
import { createApp } from "vue";
import App from "./App.vue";
import { createPinia } from "pinia";
const pinia = createPinia()
const myApp = createApp(App)
myApp.use(pinia)
myApp.mount('#app')
import { defineStore } from "pinia";
// 基础写法
export const useCountStore = defineStore('count',{
state(){
return {
sum:6,//在组件中使用时可以直接修改
}
},
getters:{
bigSum(state){
return state.sum*3
}
},
actions:{
addSum(val:number){
this.sum+=val
},
},
})
import { defineStore } from "pinia";
import { ref } from 'vue'
export default defineStore('text',()=>{
let sum = ref(6)
function addSum(val:number){
sum.value+=val
}
let bigSum = computed(()=>{
return sum.value*3
})
return {sum,addSum,bigSum }
})
父组件
Pinia
当前sun值:{{ sumStore.sum }}。bigSum:{{sumStore.bigSum}}
子组件
组件一