初学vue3与ts:朕与太子的props、emit互动

父页面(index-props)


<template>
	<div class="flex">
		<div class="props-item">
			<div class="index-title">皇帝:div>
			<div class="flex a-c mt-20">
				<div class="title-item">{{oneTitle}}div>
				<button class="ml-20" @click="sendSign" v-if="oneStatus">传圣旨button>
			div>
			<div class="title-item" v-if="fourStatus">
				朕心甚安
			div>
		div>
		<div class="props-item">
			<indexEmit ref="indexEmitRef" @threeChange="threeChange" :son="son">indexEmit>
		div>
	div>
template>

<script lang="ts" setup>
	import { ref } from 'vue'
	import indexEmit from '../../components/index-emit.vue'
	const indexEmitRef = ref()
	const oneStr = ref('朕有一个任务要你去做')
	const oneList = oneStr.value.split('')
	const oneTitle = ref('')
	const oneTime = ref<any>(null)
	const oneIndex = ref(0)
	const oneStatus = ref(false)
	const son = '太子'
	// 定时器
	oneTime.value = setInterval(()=>{
		if(oneIndex.value >= oneList.length){
			clearInterval(oneTime.value)
			oneStatus.value = true
		}else{
			oneTitle.value += oneList[oneIndex.value]
			oneIndex.value++;
		}
	},100)
	const signList = ref([
		{title:'朕要吃面线糊,去打包一份过来'},
		{title:'给朕接着舞,接着乐'},
		{title:'传拜登觐见'},
		{title:'双11到了,去囤10万吨粮食'},
		{title:'朕命你打下倭国'},
		{title:'你登基吧,朕累了'},
		{title:'摆驾白宫'},
		{title:'原神,启动'},
		{title:'周四要到了,穿上西装去打团'},
		{title:'天王盖地虎'}
	])
	function sendSign(){
		oneStatus.value = false
		let oneNum = Math.floor(Math.random() * 10);
		//触发子组件的事件
		indexEmitRef.value.acceptSign(signList.value[oneNum].title)
	}
	const fourStatus = ref(false)
	//子组件触发父组件的事件
	function threeChange(){
		fourStatus.value = true
	}
script>

<style>
	.index-title{
		font-size: 24px;
		font-weight: bold;
	}
	.title{
		font-weight: bold;
		font-size: 20px;
		padding-top: 20px;
		padding-left: 20px;
	}
	.title-sub{
		padding-left: 40px;
		margin-top: 10px;
	}
	.flex{
		display: flex;
	}
	.pl-60{
		padding-left: 60px !important;
	}
	.props-item{
		min-width: 600px;
		padding-right: 30px;
	}
	.title-item{
		font-weight: bold;
		font-size: 20px;
		padding-left: 20px;
	}
	.mt-20{
		margin-top: 20px;
	}
	.ml-20{
		margin-left: 20px;
	}
	.a-c{
		align-items: center;
	}
style>

子组件(index-emit)


<template>
	<div>
		<div class="index-title">{{son}}:div>
		<div class="flex a-c mt-20" v-if="towStr">
			<div class="title-item">{{towStr}}div>
			<button v-if="towStatus" class="ml-20" @click="acceptNext">接圣旨button>
		div>
		<div v-if="threeStatus" class="title-item">
			儿臣接旨
		div>
	div>
template>

<script lang="ts" setup>
	// setup()模式的话,要改成setup(props,{emit})即可,不需要defineExpose、defineProps和defineEmits
	import { ref, reactive, onMounted } from 'vue'
	// props接收值 setup的用法,setup()不需要
	// props接收值 setup的用法,setup()不需要
	// props接收值 setup的用法,setup()不需要
	const props = defineProps({
		son:{
			type:String,
			default:''
		}
	})
	const towTime = ref<any>(null)
	const towIndex = ref(0);
	const towStatus = ref(false)
	const towStr = ref('')
	// 接收父组件传的值
	function acceptSign(sign:string){
		let towSign = ''
		if(sign == '天王盖地虎'){
			towSign = '小鸡炖蘑菇'
		}else{
			towSign = `奉天承运,皇帝诏曰:${sign}`
		}
		let towList = towSign.split('')
		towTime.value = setInterval(()=>{
			if(towIndex.value >= towList.length){
				clearInterval(towTime.value)
				towStatus.value = true
			}else{
				towStr.value += towList[towIndex.value]
				towIndex.value++;
			}
		},100)
	}
	const threeStatus = ref(false)
	//用emit需要的 setup的用法,setup()不需要
	//用emit需要的 setup的用法,setup()不需要
	//用emit需要的 setup的用法,setup()不需要
	const emit = defineEmits(['threeChange'])
	//发送emit事件
	function acceptNext(){
		towStatus.value = false
		threeStatus.value = true
		setTimeout(()=>{
			emit('threeChange')
		},500)
	}
	//父组件要调用子组件的事件,必须暴露子组件的事件...重要的事说三遍,setup()不需要
	//父组件要调用子组件的事件,必须暴露子组件的事件...重要的事说三遍,setup()不需要
	//父组件要调用子组件的事件,必须暴露子组件的事件...重要的事说三遍,setup()不需要
	defineExpose({ acceptSign })
script>

<style>
	
style>

你可能感兴趣的:(vue,前端,vue,typescript)