vue3、react组件数据传值对比分析——父组件传递子组件,子组件传递父组件(一)https://developer.aliyun.com/article/1492684
💖 子组件传递事件给父组件使用emit
子组件
<template> <div class="iframe-container"> <div class="iframe-content" v-if="!isPage&&!isModel"> <div style="width: 100%"> <span> 标题:{{ title }} </span> {{kind}} <a-button @click="jumpPage" type="primary" style="float: right; margin: 5px" > 跳转</a-button > </div> <iframe :src="url" class="iframe-box"></iframe> </div> <div class="iframe-content" v-else-if="!isModel"> <UserTable></UserTable> </div> <div class="iframe-content" v-else> <ChatTable></ChatTable> </div> </div> </template> <script lang="ts" setup> import {computed} from 'vue' // @ts-ignore const props = defineProps<{ url: string; title: string; kind: string; }>(); const isPage=computed(()=>{ console.log('props',props) return props.kind=='page' }) const isModel=computed(()=>{ console.log('props',props) return props.kind=='model' }) const emit = defineEmits<{ (e: "change", id: number): void; (e: "update", value: string): void; }>(); const jumpPage = () => { window.open(props.url); }; </script>
父组件通过@绑定事件change和update就能接受子组件触发的change和update事件
💖 父组件获取子组件实例使用Ref
通过使用ref绑定formRef去获取校验事件
<template> <div class="container"> <div class="loginUser-container"> <div class="loginUser-title">管理平台</div> <a-form :model="state.formState" :label-col="state.layoutConfig.labelCol" :wrapper-col="state.layoutConfig.wrapperCol" :rules="state.formRule" ref="formRef" layout="vertical" autocomplete="off" > <a-form-item label="账号" name="username"> <a-input v-model:value="state.formState.username" allowClear placeholder="请输入账号" :disabled="state.spinning" /> </a-form-item> <a-form-item label="密码" name="password"> <a-input-password v-model:value="state.formState.password" :disabled="state.spinning" allowClear placeholder="请输入密码" /> </a-form-item> <a-form-item name="remember" :wrapper-col="state.wrapperCol"> <a-checkbox v-model:checked="state.formState.remember" :disabled="state.spinning" >记住密码</a-checkbox > </a-form-item> <a-form-item :wrapper-col="state.submitWrapperCol" class="submit-box"> <a-button type="primary" html-type="submit" @click="loginAction" :loading="state.spinning" style="width: 100%; font-size: 16px; font-weight: bolder" >登录</a-button > </a-form-item> </a-form> <div class="description"> <span class="description-prefix">没账号?</span> <span @click="jumpRegister" class="description-after" :disabled="state.spinning" >去注册</span > </div> </div> </div> </template> <script lang="ts" setup> import { reactive, ref, onMounted } from "vue"; import { useRouter } from "vue-router"; import { useStore } from "vuex"; import { message } from "ant-design-vue"; import { loginUser } from "../../service/user/userApi"; import type { FormInstance } from "ant-design-vue"; interface FormStateType { username: string; password: string; remember: boolean; } interface FormRuleType { username: Object; password: Object; } interface stateType { formState: FormStateType; formRule: FormRuleType; layoutConfig: any; wrapperCol: any; submitWrapperCol: any; spinning: boolean; backgroundImgUrl: string; } // 路由 const router = useRouter(); //store const store = useStore(); const formRef = ref<FormInstance>(); const state: stateType = reactive({ formState: { username: "", password: "", remember: false, }, spinning: false, formRule: { username: [{ required: true, message: "请输入账号!" }], password: [{ required: true, message: "请输入密码!" }], }, layoutConfig: { labelCol: { span: 8, }, wrapperCol: { span: 24, }, }, wrapperCol: { offset: 0, span: 24 }, submitWrapperCol: { offset: 0, span: 24 }, backgroundImgUrl: "http://www.yongma16.xyz/staticFile/common/img/background.png", }); /** * 初始化表单内容 */ const initForm = () => { const userInfoItem: any = window.localStorage.getItem("userInfo"); interface userInfoType { username: string; password: string; remember: boolean; } const userInfo: userInfoType = userInfoItem ? JSON.parse(userInfoItem) : { username: "", password: "", remember: false, }; if (userInfo.username && userInfo.password) { state.formState.username = userInfo.username; state.formState.password = userInfo.password; state.formState.remember = userInfo.remember; } }; /** * 前往注册! */ const jumpRegister = () => { // 带 hash,结果是 /about#team router.push({ path: "/register" }); }; /** * 前往home! */ const jumpHome = () => { // 带 hash,结果是 /about#team router.push({ path: "/" }); }; /** * 记住密码 * @param params */ const rememberAction = (params: Object) => { window.localStorage.setItem("userInfo", JSON.stringify(params)); }; /** * 登录 */ const loginAction = () => { if (formRef.value) { formRef.value.validate().then(async (res: any) => { state.spinning = true; const params = { username: state.formState.username, password: state.formState.password, }; if (state.formState.remember) { rememberAction({ ...params, remember: state.formState.remember }); } try { console.log('登录',params) // @ts-ignore await store.dispatch( "user/loginUser", params ); // 跳转 setTimeout(() => { jumpHome(); }, 500); state.spinning = false; } catch (r: any) { message.error(JSON.stringify(r)); state.spinning = false; throw Error(r); } }); } }; onMounted(() => { //初始化 initForm(); }); </script>
⭐总结
综合比较react和vue,对于选型我分成两种情况讨论。
- vue项目选型——vue3 vben admin
a. 外包项目(可维护性强,中文文档多,容错率高)
b. 国内开发者众多的团队,因为vue中文文档比较多
c. 使用vue较多的团队,适合快速上手 - react项目——qiankun
a. 自研大型项目(个人觉得react项目不好抄袭)
b. 外企团队,因为react的文档大部分都是英文
c. 使用react较多的团队,适合快速上手
个人比较看好vue,有以下3点。
a. 国内开发人数众多,搭建可以用中文在社区交流vue3,扩大国内开发影响力
b. vue3的组件传值等我都比react好用,react用的费劲
c. vue的生态良好,版本也一直在迭代更新
⭐结束
本文分享到这结束,如有错误或者不足之处欢迎指出!