vue3、react组件数据传值对比分析——父组件传递子组件,子组件传递父组件(二)

简介: vue3、react组件数据传值对比分析——父组件传递子组件,子组件传递父组件

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,对于选型我分成两种情况讨论。

  1. vue项目选型——vue3 vben admin
    a. 外包项目(可维护性强,中文文档多,容错率高)
    b. 国内开发者众多的团队,因为vue中文文档比较多
    c. 使用vue较多的团队,适合快速上手
  2. react项目——qiankun
    a. 自研大型项目(个人觉得react项目不好抄袭)
    b. 外企团队,因为react的文档大部分都是英文
    c. 使用react较多的团队,适合快速上手

个人比较看好vue,有以下3点。

a. 国内开发人数众多,搭建可以用中文在社区交流vue3,扩大国内开发影响力

b. vue3的组件传值等我都比react好用,react用的费劲

c. vue的生态良好,版本也一直在迭代更新

⭐结束

本文分享到这结束,如有错误或者不足之处欢迎指出!

目录
相关文章
|
5月前
|
缓存 前端开发 JavaScript
React Hooks深度解析与最佳实践:提升函数组件能力的终极指南
🌟蒋星熠Jaxonic,前端探索者。专注React Hooks深度实践,从原理到实战,分享状态管理、性能优化与自定义Hook精髓。助力开发者掌握函数组件的无限可能,共赴技术星辰大海!
React Hooks深度解析与最佳实践:提升函数组件能力的终极指南
|
10月前
|
缓存 前端开发 数据安全/隐私保护
如何使用组合组件和高阶组件实现复杂的 React 应用程序?
如何使用组合组件和高阶组件实现复杂的 React 应用程序?
349 68
|
10月前
|
缓存 前端开发 Java
在 React 中,组合组件和高阶组件在性能方面有何区别?
在 React 中,组合组件和高阶组件在性能方面有何区别?
318 67
|
10月前
|
前端开发 JavaScript 安全
除了高阶组件和render props,还有哪些在 React 中实现代码复用的方法?
除了高阶组件和render props,还有哪些在 React 中实现代码复用的方法?
397 62
|
编解码 前端开发 开发者
React 图片组件样式自定义:常见问题与解决方案
在 React 开发中,图片组件的样式自定义常因细节问题导致布局错乱、性能损耗或交互异常。本文系统梳理常见问题及解决方案,涵盖基础样式应用、响应式设计、加载状态与性能优化等,结合代码案例帮助开发者高效实现图片组件的样式控制。重点解决图片尺寸不匹配、边框阴影不一致、移动端显示模糊、加载失败处理及懒加载等问题,并总结易错点和最佳实践,助力开发者提升开发效率和用户体验。
427 22
|
移动开发 前端开发 API
React 音频播放器组件 Audio Player
本文介绍如何使用React创建音频播放器组件,涵盖核心功能如播放/暂停、进度条、音量控制和时间显示。通过HTML5 `&lt;audio&gt;` 元素和React的声明式状态管理,实现交互式音频播放。常见问题包括控件不响应、进度条无法更新和音量控制失灵,并提供解决方案。此外,还讨论了浏览器兼容性、异步错误处理和性能优化等易错点及避免方法。
890 123
|
前端开发 JavaScript
除了使用Route组件,React Router还有其他方式处理404错误页面吗
除了使用Route组件,React Router还有其他方式处理404错误页面吗
385 58
|
前端开发
React 中高阶组件的原理是什么?
React 中高阶组件的原理是什么?
267 57
|
前端开发 开发者
除了函数组件和类组件,React 还有其他创建组件的方式吗?
除了函数组件和类组件,React 还有其他创建组件的方式吗?
215 57
|
前端开发
如何在React Router中定义404错误页面组件?
如何在React Router中定义404错误页面组件?
354 57