记性太差了,学了的东西过几天就忘了,现在打算把学习的内容都整理成笔记,现在给大家分享一下自己在学习组件通信时候的笔记吧
-
props 父 => 子
//父组件 <template> <List :list="list"/> </template> <script setup> import { ref } from 'vue'; import List from './List.vue'// const list = ref(['JavaScript', 'HTML', 'CSS'])//要把这个list传给子组件 </script> //子组件 <script setup> import { defineProps } from 'vue' const props = defineProps({ // defineProps专门用来解析父组件传递的数据 list: { type: Array, default: () => [] } }) </script> -
emit 子 => 父
<!--子组件(名为Child)--> <template> div class="wrap"> <input type="text" class="form-control" v-model="value"> <button class="btn" type="button" @click="handleAdd">添加</button> </div> </template> <script setup> import { ref, defineEmits } from 'vue'; const value = ref('') const emits = defineEmits(['add'])//定义一个事件的名称为emits const handleAdd = () => { emits('add',value.value) //发散名为add,值为value.value的事件 value.value = '' } </script> <!--父组件--> <template> <!-- 接收add,给它绑定一个handleAdd事件 --> <ChildVue @add = 'handleAdd' /> </template> <script setup> import ChildVue from './Child.vue' import { ref } from 'vue' const list = ref (['a','b','c']) const handleAdd = value => {//会有一个回调参数 list.push(value) } </script> -
v-model 子 => 父
<!--子组件(名为Child)--> <template> div class="wrap"> <input type="text" class="form-control" v-model="value"> <button class="btn" type="button" @click="handleAdd">添加</button> </div> </template> <script setup> import { ref,defineEmits,defineProps } from 'vue' const props = defineProps({ list:{ type:Array, default:() => [] } }) const emits = defineEmits('update:list')//这里update是固定写法,list为从父组件接受过来的数据 const arr = props.list const handleAdd = () => { arr.push(value.value) emits('update:list',arr) value.value = '' } </script> <!--父组件--> <template> <!-- 只要给v-model添加一个list属性就可以了 --> <ChildVue v-model:list = 'list' /> </template> <script setup> import ChildVue from './Child.vue' import { ref } from 'vue' const list = ref (['a','b','c']) </script> -
refs 子 => 父
<!--子组件(名为Child)--> <template> div class="wrap"> <input type="text" class="form-control" v-model="value"> <button class="btn" type="button" @click="handleAdd">添加</button> </div> </template> <script setup> import { ref,defineExpose) } from 'vue' const list = ref (['a','b','c']) const handleAdd = () => { list.value.push(value.value) value.value = '' } // <script setup>写法会导致整个组件实例无法暴露出来,父组件无法通过ref获取到子组件的实例 defineExpose({ list })//使list暴露出来 </script> <!--父组件--> <template> <!-- 这里就是相当于将childRefs设置为子组件的实例对象 --> <ChildVue ref:'childRefs' /> <div class="child"> <ul class="list-group"> <li class="list-item" v-for="item in childRefs?.list" :key="item">{{ item }}</li> </ul> </div> </template> <script setup> import ChildVue from './Child.vue' import { ref } from 'vue' const childRefs = ref(null)//初始化 </script>不用setup写法的话,子组件JS部分应该写成:
<script> import { ref } from 'vue'; export default { setup() { const list = ref(['JavaScript', 'HTML', 'CSS']) const value = ref('') const handleAdd = () => { list.value.push(value.value) value.value = '' } return { list, value, handleAdd } } } </script> -
provide / inject 父 => 子
<!--父组件--> <template> <div> <div class="wrap"> <input type="text" class="form-control" v-model="value"> <button class="btn" type="button" @click="handleAdd">添加</button> </div> <Child/> </div> </template> <script setup> import { ref, provide } from 'vue'; import Child from './Child.vue' const list = ref(['JavaScript', 'HTML', 'CSS']) const value = ref('') const handleAdd = () => { list.value.push(value.value) value.value = '' } provide('list', list.value) // 向子组件提供数据,相当于广播这个list </script> <!--子组件(名为Child)--> <template> <div class="child"> <ul class="list-group"> <li class="list-item" v-for="item in list" :key="item"> {{ item }} </li> </ul> </div> </template> <script setup> import { inject } from 'vue'; const list = inject('list')//接受父组件的传递 </script> -
vue2 当中使用EventBus(事件总线)实现组件通信,vue3中移除了事件总线,使用 mitt.js 或者 tiny-emitter.js(这两个都是第三方工具) 父 - 子 || 子 - 父 || 兄弟组件
-
Vuex 和 Pinia