Vue3笔记——(五)路由

组件通信_方式1_props

作用:

若父传子,属性值是飞函数

若子传父,属性值是函数

Parent.vue

html 复制代码
<template>
  <div class="father">
    <h3>父组件</h3>
		<h4>汽车:{{ car }}</h4>
		<h4 v-show="toy">子给的玩具:{{ toy }}</h4>
		<Child :car="car" :sendToy="getToy" :aa="bb"/>
  </div>
</template>
typescript 复制代码
<script setup lang="ts" name="Father">
	import Child from './Child.vue'
	import {ref} from 'vue'
	// 数据
	let car = ref('奔驰')
	let toy = ref('')
	let bb = ref(0)
	// 方法
	function getToy(value:string){
		toy.value = value
	}
</script>

Child.vue

html 复制代码
<template>
  <div class="child">
    <h3>子组件</h3>
		<h4>玩具:{{ toy }}</h4>
		<h4>父给的车:{{ car }}</h4>
		<h4>其它{{$attrs}}</h4>
		<button @click="sendToy(toy)">把玩具给父亲</button>
  </div>
</template>
javascript 复制代码
<script setup lang="ts" name="Child">
	import {ref} from 'vue'
	// 数据
	let toy = ref('奥特曼')
	// 声明接收props
	defineProps(['car','sendToy'])
</script>

组件通信_方式2_自定义事件

作用:子传父

Parent.vue

html 复制代码
<template>
  <div class="father">
    <h3>父组件</h3>
		<h4 v-show="toy">子给的玩具:{{ toy }}</h4>
		<!-- 给子组件Child绑定事件 -->
    <Child @send-toy="saveToy"/>
  </div>
</template>
typescript 复制代码
<script setup lang="ts" name="Father">
  import Child from './Child.vue'
	import { ref } from "vue";
	// 数据
	let toy = ref('')
	// 用于保存传递过来的玩具
	function saveToy(value:string){
		toy.value = value
	}
</script>

Child.vue

html 复制代码
<template>
	<div class="child">
		<h3>子组件</h3>
		<h4>玩具:{{ toy }}</h4>
		<button @click="emit('send-toy', toy)">测试</button>
	</div>
</template>
typescript 复制代码
<script setup lang="ts" name="Child">
import { ref, onMounted } from "vue";
// 数据
let toy = ref('奥特曼')
// 声明事件
const emit = defineEmits(['send-toy'])
</script>

组件通信_方式3_mitt

作用:任意组件间通信

安装:npm i mitt

创建utils/emitter文件

emitter.ts文件

typescript 复制代码
// 引用
import mitt from "mitt";
// 调用emitter,emitter能够绑定事件,触发事件
const emitter = mitt()
export default emitter

Child1.vue

html 复制代码
<template>
  <div class="child1">
    <h3>子组件1</h3>
		<h4>玩具:{{ toy }}</h4>
		<button @click="emitter.emit('send-toy',toy)">玩具给弟弟</button>
  </div>
</template>
typescript 复制代码
<script setup lang="ts" name="Child1">
	import {ref} from 'vue'
	import emitter from '@/utils/emitter';
	// 数据
	let toy = ref('奥特曼')
</script>

Child2.vue

html 复制代码
<template>
  <div class="child2">
    <h3>子组件2</h3>
		<h4>电脑:{{ computer }}</h4>
		<h4>哥哥给的玩具:{{ toy }}</h4>
  </div>
</template>
typescript 复制代码
<script setup lang="ts" name="Child2">
	import {ref,onUnmounted} from 'vue'
	import emitter from '@/utils/emitter';
	// 数据
	let computer = ref('联想')
	let toy = ref('')
	// 给emitter绑定send-toy事件
	emitter.on('send-toy',(value:any)=>{
		toy.value = value
	})
	// 在组件卸载时解绑send-toy事件
	onUnmounted(()=>{
		emitter.off('send-toy');//在组件卸载时解绑
		emitter.all.clear();//清除总线上绑定的所有事件
	})
</script>

v-model

html 复制代码
<template>
  <div class="father">
    <h3>父组件</h3>
    <h4>{{ username }}</h4>
    <h4>{{ password }}</h4>
    <!-- v-model用在html标签上 -->
    <!-- <input type="text" v-model="username"> -->
    <!-- <input type="text" :value="username" @input="username = (<HTMLInputElement>$event.target).value"> -->

    <!-- v-model用在组件标签上 -->
    <!-- <AtguiguInput v-model="username"/> -->
    <!-- <AtguiguInput 
      :modelValue="username" 
      @update:modelValue="username = $event"
    /> -->

    <!-- 修改modelValue -->
    <AtguiguInput v-model:ming="username" v-model:mima="password"/>
  </div>
</template>

<script setup lang="ts" name="Father">
  import { ref } from "vue";
  import AtguiguInput from './AtguiguInput.vue'
  // 数据
  let username = ref('zhansgan')
  let password = ref('123456')
</script>

AtguiguInput.vue

html 复制代码
<template>
  <input 
    type="text" 
    :value="ming"
    @input="emit('update:ming',(<HTMLInputElement>$event.target).value)"
  >
  <br>
  <input 
    type="text" 
    :value="mima"
    @input="emit('update:mima',(<HTMLInputElement>$event.target).value)"
  >
</template>
typescript 复制代码
<script setup lang="ts" name="AtguiguInput">
  defineProps(['ming','mima'])
  const emit = defineEmits(['update:ming','update:mima'])
</script>

组件通信_方式5_$attrs

作用:祖传孙、孙传祖

Parent.vue

html 复制代码
<template>
  <div class="father">
    <h3>父组件</h3>
		<h4>a:{{a}}</h4>
		<h4>b:{{b}}</h4>
		<h4>c:{{c}}</h4>
		<h4>d:{{d}}</h4>
		<Child :a="a" :b="b" :c="c" :d="d" v-bind="{x:100,y:200}" :updateA="updateA"/>
  </div>
</template>
typescript 复制代码
<script setup lang="ts" name="Father">
	import Child from './Child.vue'
	import {ref} from 'vue'
	let a = ref(1)
	let b = ref(2)
	let c = ref(3)
	let d = ref(4)
	function updateA(value:number){
		a.value += value
	}
</script>

Child.vue

html 复制代码
<template>
	<div class="child">
		<h3>子组件</h3>
		<GrandChild v-bind="$attrs"/>
	</div>
</template>
typescript 复制代码
<script setup lang="ts" name="Child">
	import GrandChild from './GrandChild.vue'
</script>

GrandChild .vue

html 复制代码
<template>
	<div class="grand-child">
		<h3>孙组件</h3>
		<h4>a:{{ a }}</h4>
		<h4>b:{{ b }}</h4>
		<h4>c:{{ c }}</h4>
		<h4>d:{{ d }}</h4>
		<h4>x:{{ x }}</h4>
		<h4>y:{{ y }}</h4>
		<button @click="updateA(6)">点我将爷爷那的a更新</button>
	</div>
</template>
typescript 复制代码
<script setup lang="ts" name="GrandChild">
	defineProps(['a','b','c','d','x','y','updateA'])
</script>

组件通信_方式6_ r e f s 与 refs与 refs与parent

$refs父传子

$parent子传父

Father.vue

html 复制代码
<template>
	<div class="father">
		<h3>父组件</h3>
		<h4>房产:{{ house }}</h4>
		<button @click="changeToy">修改Child1的玩具</button>
		<button @click="changeComputer">修改Child2的电脑</button>
		<button @click="getAllChild($refs)">让所有孩子的书变多</button>
		<Child1 ref="c1"/>
		<Child2 ref="c2"/>
	</div>
</template>
typescript 复制代码
<script setup lang="ts" name="Father">
	import Child1 from './Child1.vue'
	import Child2 from './Child2.vue'
	import { ref,reactive } from "vue";
	let c1 = ref()
	let c2 = ref()
	// 数据
	let house = ref(4)
	// 方法
	function changeToy(){
		c1.value.toy = '小猪佩奇'
	}
	function changeComputer(){
		c2.value.computer = '华为'
	}
	function getAllChild(refs:{[key:string]:any}){
		console.log(refs)
		for (let key in refs){
			refs[key].book += 3
		}
	}
	// 向外部提供数据
	defineExpose({house})
</script>

Child1.vue

html 复制代码
<template>
  <div class="child1">
    <h3>子组件1</h3>
		<h4>玩具:{{ toy }}</h4>
		<h4>书籍:{{ book }} 本</h4>
		<button @click="minusHouse($parent)">干掉父亲的一套房产</button>
  </div>
</template>
typescript 复制代码
<script setup lang="ts" name="Child1">
	import { ref } from "vue";
	// 数据
	let toy = ref('奥特曼')
	let book = ref(3)
	// 方法
	function minusHouse(parent:any){
		parent.house -= 1
	}
	// 把数据交给外部
	defineExpose({toy,book})
</script>

组件通信_方式7_provide_inject

作用:祖传子

Father.vue

html 复制代码
<template>
  <div class="father">
    <h3>父组件</h3>
    <h4>银子:{{ money }}万元</h4>
    <h4>车子:一辆{{car.brand}}车,价值{{car.price}}万元</h4>
    <Child/>
  </div>
</template>
typescript 复制代码
<script setup lang="ts" name="Father">
  import Child from './Child.vue'
  import {ref,reactive,provide} from 'vue'
  let money = ref(100)
  let car = reactive({
    brand:'奔驰',
    price:100
  })
  function updateMoney(value:number){
    money.value -= value
  }
  // 向后代提供数据
  provide('moneyContext',{money,updateMoney})
  provide('car',car)
</script>

GrandChild.vue

html 复制代码
<template>
  <div class="grand-child">
    <h3>我是孙组件</h3>
    <h4>银子:{{ money }}</h4>
    <h4>车子:一辆{{car.brand}}车,价值{{car.price}}万元</h4>
    <button @click="updateMoney(6)">花爷爷的钱</button>
  </div>
</template>
typescript 复制代码
<script setup lang="ts" name="GrandChild">
  import { inject } from "vue";
  let {money,updateMoney} = inject('moneyContext',{money:0,updateMoney:(param:number)=>{}})
  let car = inject('car',{brand:'未知',price:0})
</script>
相关推荐
binnnngo2 小时前
2.体验vue
前端·javascript·vue.js
LCG元2 小时前
Vue.js组件开发-实现多个文件附件压缩下载
前端·javascript·vue.js
╰つ゛木槿2 小时前
深入探索 Vue 3 Markdown 编辑器:高级功能与实现
前端·vue.js·编辑器
豆豆(设计前端)2 小时前
在 Vue 项目中快速引入和使用 ECharts
vue.js
醉の虾2 小时前
VUE3 使用路由守卫函数实现类型服务器端中间件效果
前端·vue.js·中间件
程序边界3 小时前
AIGC时代下的Vue组件开发深度探索
vue.js
码上飞扬3 小时前
Vue 3 30天精进之旅:Day 05 - 事件处理
前端·javascript·vue.js
阿芯爱编程12 小时前
vue3 vue2区别
前端·javascript·vue.js
绿草在线12 小时前
Vue3+Elementplus物流订单信息跟踪管理
vue.js
customer0814 小时前
【开源免费】基于SpringBoot+Vue.JS校园失物招领系统(JAVA毕业设计)
java·vue.js·spring boot·后端·开源