props
父组件以数据绑定的形式声明要传递的数据,子组件通过defineProperty()方法创建props对象来拿到父组件传来的数据。
父组件
<!-- list是我们要传递的数据 -->
<child :list="list"></child>
子组件
<template>
<ul>
<li v-for="i in props.list" :key="i">{{ i }}</li>
</ul>
</template>
<script setup>
import { defineProps } from 'vue'
const props = defineProps({
list: {
type: Array,
default: () => [],
},
})
</script>
emit
用于子组件向父组件传递消息
父组件
<!-- add是子组件要传递的动作,handleAdd是监听到之后执行的事件 -->
<child @add="handleAdd"></child>
<script>
const list = ref([1,2,3])
const handleAdd = value => {
list.value.push(value)
}
</script>
子组件
const emits = defineEmits(['add'])
emits('add', 1)
v-model方式
父组件
<child v-model:list="list" />
// 等价于
<child :list="pageTitle" @update:list="list = $event" />
子组件需要emit一个叫update:xxx的事件,再把需要更新的响应式数据传给emit方法的第二个参数
const emits = defineEmits(['update:list'])
emits('update:list', arr)
Refs
默认情况下,setup 组件是关闭的,通过模板 ref 获取组件的公共实例。如果需要公开,需要通过defineExpose API 公开。
父组件
<template>
<ul class="parent list-group">
<li class="list-group-item" v-for="i in childRefs?.list" :key="i">
{{ i }}
</li>
</ul>
<!-- The value of the child component ref is the same as that in the <script> -->
<child ref="childRefs"></child>
<!-- parent component -->
</template>
<script setup>
import { ref } from 'vue'
import child from './child.vue'
const childRefs = ref(null)
</script>
子组件
<template>
<div class="child-wrap input-group">
<input
v-model="value"
type="text"
class="form-control"
placeholder="Please enter"
/>
<div class="input-group-append">
<button @click="handleAdd" class="btn btn-primary" type="button">
add
</button>
</div>
</div>
</template>
<script setup>
import { ref, defineExpose } from 'vue'
const list = ref(['JavaScript', 'HTML', 'CSS'])
const value = ref('')
// event handling function triggered by add
const handleAdd = () => {
list.value.push(value.value)
value.value = ''
}
defineExpose({ list })
</script>
provide/inject
provide/inject是 Vue 中提供的一对 API。无论层级多深,API 都可以实现父组件到子孙组件的数据传递。
父组件
<template>
<child></child>
</template>
<script setup>
import { ref, provide } from 'vue'
import child from './child.vue'
const list = ref(['JavaScript', 'HTML', 'CSS'])
const value = ref('')
provide('list', list.value)
const handleAdd = () => {
list.value.push(value.value)
value.value = ''
}
</script>
子组件
<template>
<ul class="parent list-group">
<li class="list-group-item" v-for="i in list" :key="i">{{ i }}</li>
</ul>
</template>
<script setup>
import { inject } from 'vue'
const list = inject('list')
</script>
vuex
//store/index.js
import { createStore } from "vuex"
export default createStore({
state:{ count: 1 },
getters:{
getCount: state => state.count
},
mutations:{
add(state){
state.count++
}
}
})
// main.js
import { createApp } from "vue"
import App from "./App.vue"
import store from "./store"
createApp(App).use(store).mount("#app")
// Page.vue
// 方法一 直接使用
<template>
<div>{{ $store.state.count }}</div>
<button @click="$store.commit('add')">按钮</button>
</template>
// 方法二 获取
<script setup>
import { useStore, computed } from "vuex"
const store = useStore()
console.log(store.state.count) // 1
const count = computed(()=>store.state.count) // 响应式,会随着vuex数据改变而改变
console.log(count) // 1
</script>