一、通过props和emit传值和接收值
父组件
<div>
<child :myName="childName" @myNewName="onMyNewName"></child>
</div>
<script setup lang="ts">
import {ref} from 'vue'
let childName=ref("Emily");
const onMyNewName=()=>{
childName.ref="new Emily"
}
</script>
子组件
<div>
<span>{{myName}}</span>
<button @click="changeName">改变名称</button>
</div>
<script>
import {defineProps,defineEmits} from 'vue'
const emit=defineEmits(['clickChild'])
const pros=defineProps({
myName:{
type:string
}
})
const changeName=()=>{
emit('myNewName','new name')
}
</script>
二、provide/inject
传静态数据,值不会被子组件修改
父组件
<div></div>
<script setup lang="ts">
import {provide} from 'vue'
provide('provideStatic','staticData'); //传string
</script>
子组件
<div>{{provideStatic}}</div>
<script setup lang="ts">
import {inject} from 'vue'
const provideStatic=inject('provideStatic');
</script>
传动态数据,值可以被子组件修改(不安全) 父组件
<div></div>
<script setup lang="ts">
import {provide,ref} from 'vue'
const provideStatic=ref('staticData')
provide('provideStatic',provideStatic); //传string
</script>
子组件
<div>{{provideStatic}}</div>
<script setup lang="ts">
import {inject} from 'vue'
const provideStatic=inject('provideStatic');
</script>
使用readonly,使子组件无法直接修改父组件数据,但是可以由父组件provide一个方法以供子组件修改
父组件
<script>
import { provide, ref, readonly } from 'vue'
const readonlyData = ref({ name: '张三' })
provide('readonlyData', readonly(readonlyData)) //使用readonly,提供响应性的数据,该值可以不可以直接被子组件修改。但是可以再提供一个方法专门用于修改数据
const changeReadonlyData = (val: string) => { readonlyData.value.name = val } provide('changeReadonlyData', changeReadonlyData)
</script>
子组件
<template>
<div>子组件{{ readonlyData.name }}</div>
<button @click="changeReadonlyData('李四')">点击修改</button>
</template>
<script lang="ts">
import { defineComponent, inject } from 'vue'
const readonlyData = inject('readonlyData')
const changeReadonlyData = inject('changeReadonlyData')
三、透传 Attributes
“透传 attribute”指的是传递给一个组件,却没有被该组件声明为props或emits的 attribute 或者 v-on 事件监听器。最常见的例子就是 class、style 和 id。
组件
<button>按钮</button>
传入class 渲染为 click me
组件让的class和type值会被渲染到根节点 inheritAttrs: false禁止自动继承arribute; 如果想透传到子组件特定的元素上可以给指定的元素设置v-bind="$attrs";
父组件(添加type="button")
<MyButton type="button" />
<script setup lang="ts">
import {defineOptions } from 'vue'
defineOptions({
inheritAttrs: false
})
</script>
子组件
<div class="btn-wrapper">
<button class="btn" v-bind="$attrs">click me</button>
</div>
最终渲染为
<div class="btn-wrapper">
<button class="btn" type="button">click me</button>
</div>
四、vuex状态管理
store/index.js
import { createStore } from 'vuex'
export default createStore({
state: {
count: 100, num: 10
},
mutations: {
increment (state) { state.count++ }
sum (state, num) { state.count += num }
},
actions: {
sum_actions (context, num) { setTimeout(() => {
context.commit('sum', num)// 通过context去触发mutions中的sum
}, 1000) }
},
modules: {
}
})
page页
<script setup>
import { useStore } from 'vuex'
// 引入useStore 方法
const store = useStore();
store.commit('increment')
store.dispatch('sum_actions', num)
console.log(store)
</script>