TypeScript :module&传输数据

简介: 本文介绍了JavaScript模块的基本概念、语法及使用方法,包括如何定义和导入模块、处理默认导出与按需导入、以及在Vue组件中使用`props`和`emit`进行数据传递和事件触发的方法。通过示例代码详细解释了模块化编程和组件间通信的实现方式。

前言

在现代前端开发中,模块化编程已经成为提升代码可维护性和可重用性的关键实践。JavaScript 模块的引入,使得开发者能够将代码分割成更小、更易于管理的部分,从而提高了开发效率和团队协作的能力。本文将深入探讨 JavaScript 模块的基本概念与语法,包括如何定义和导入模块、处理默认导出与按需导入等内容。此外,我们还将重点介绍在 Vue 组件中使用 props 和 emit 进行数据传递和事件触发的方法。通过具体的示例代码,我们将详细解释模块化编程的基本实现以及组件间通信的有效方式。无论您是 JavaScript 的新手还是希望提升开发技能的经验开发者,本指南都将为您提供清晰的理解和实用的技巧,帮助您在构建现代应用时更加得心应手。

module

意思

如果你有一个文件,现在没有任何 import 或者 export,但是你希望它被作为模块处理,添加这行代码:

export {};

语法

// @filename: hello.ts
export default function helloWorld() {
  console.log("Hello, world!");
}
import hello from "./hello.js";
hello();

除了默认导出,你可以通过省略 defaultexport 语法导出不止一个变量和函数:

当没有default  的时候就 需要加上{} 按需导入

// @filename: maths.ts
export var pi = 3.14;
export let squareTwo = 1.41;
export const phi = 1.61;
export class RandomNumberGenerator {}
export function absolute(num: number) {
  if (num < 0) return num * -1;
  return num;
}
import { pi, phi, absolute } from "./maths.js";
console.log(pi);
const absPhi = absolute(phi);
// const absPhi: number
import { pi as π } from "./maths.js";
console.log(π);
// (alias) var π: number
// import π

你可以接受所有的导出对象,然后使用 * as name 把它们放入一个单独的命名空间:

// @filename: app.ts
import * as math from "./maths.js";
console.log(math.pi);
const positivePhi = math.absolute(math.phi);
// const positivePhi: number

传输数据

props

<script setup lang="ts">
interface Props {
  msg?: string
  labels?: string[]
}
const props = withDefaults(defineProps < Props > (), {
  msg: 'hello',
  labels: () => ['one', 'two']
})
console.log(props)
</script>
<template>
  <h1>{{ msg }}</h1>
  <ul v-for="item in labels ">
    <li>{{ item }}</li>
  </ul>
</template>
<template>
    <div>
        <A :labels="data"></A>
    </div>
</template>
<script setup lang="ts">
    import { reactive } from 'vue';
import A from './views/A.vue';
    let data = reactive(['first','second'])
</script>
<style scoped>
</style>

emit

<script setup lang="ts">
const emit = defineEmits<{
  (e: 'change', show: boolean): void
}>()
const show = () => {
  emit('change', false)
}
</script>
<template>
  <el-button @click="show">显示/不显示</el-button>
</template>
<template>
    <div>
      <A @change="change"></A>
    </div>
  </template>
  <script setup lang="ts">
  import A from './views/A.vue';
  const change = (data: boolean) => {
    console.log(data)
  }
  </script>


emit和props

<script setup lang="ts">
const emit = defineEmits<{
  (e: 'update:visible', show: boolean): void
}>()
const handSubmit = () => {
  emit('update:visible', false)
}
interface Props{
    showDialog?:boolean
}
withDefaults(defineProps<Props>(),{
    showDialog:false
})
</script>
<template>
  <!-- 这里使用的是v-show  -->
  <div class="box" v-show="showDialog">
    <el-button @click="handSubmit" >显示/不显示</el-button>
  </div>
</template>
<style scoped >
.box{
  width: 200px;
  height: 200px;
  background-color: red;
}
.box button{
  position: absolute;
  left: 8;
  top:  200px;
  z-index: 99;
}
</style>
<template>
    <div>
        <el-button @click="updateForm">显示/不显示</el-button>
      <A  :showDialog="showDialog" @update:visible="handSubmit"></A>
    </div>
  </template>
  <script setup lang="ts">
  import A from './views/A.vue';
  import {ref} from 'vue'
  let showDialog = ref(false)
  const updateForm = ()=>{
    showDialog.value= true
  }
  const handSubmit = (data: boolean) => {
    showDialog.value=data
  }
  </script>


FormModel

<template>
  <div>
    <el-dialog v-model="isShow" :title="props.dialogConfig?.dialogTitle" @close="handleCancel">
      <el-form :model="form" style="max-width: 600px" ref="ruleFormRef" :rules="rules" status-icon>
        <el-form-item label="Name" prop="name">
          <el-input v-model="form.name" />
        </el-form-item>
      </el-form>
      <template #footer>
        <el-button type="default" @click="handleCancel">取消</el-button>
        <el-button type="primary" @click="handleSaveSubmit">保存提交</el-button>
      </template>
    </el-dialog>
  </div>
</template>
<script lang="ts" setup>
import { reactive, computed, ref } from 'vue';
import type { FormInstance, FormRules } from 'element-plus';
// 定义 prop 类型  
interface DialogProps {
  dialogVisible?: boolean;
  dialogConfig?: {
    dialogTitle: string;
  };
}
interface FormValue {
  name: string;
}
// 使用 defineProps 声明 props  
const props = defineProps<DialogProps>();
const emits = defineEmits<{
  (e: 'update:dialogVisible', isVisible: boolean): void;
  (e: 'save', formData: FormValue): void;
  (e: 'cancel', isVisible: boolean): void;
}>();
// 校验
const ruleFormRef = ref<FormInstance>();
const form = reactive<FormValue>({ name: '' }); // 修改为 reactive
const rules: FormRules<FormValue> = {
  name: [
    { required: true, message: 'Please input Activity name', trigger: 'blur' },
    { min: 3, max: 5, message: 'Length should be 3 to 5', trigger: 'blur' },
  ],
};
// 使用 computed 属性来同步 props.dialogVisible 的变化  
const isShow = computed({
  get() {
    return props.dialogVisible;
  },
  set(value: boolean) {
    emits('update:dialogVisible', value);
  },
});
// 保存表单的回调函数  
const handleSaveSubmit = async () => {
  const formEl = ruleFormRef.value; // 获取 ref 的值
  if (!formEl) return;
  await formEl.validate((valid, fields) => {
    if (valid) {
      emits('save', { ...form }); // 发送表单数据到父组件  
    } else {
      console.log('error submit!', fields);
    }
  });
};
const handleCancel = () => {
  const formEl = ruleFormRef.value; // 获取 ref 的值
  emits('cancel', false); // 发送数据到父组件  
  formEl?.resetFields(); // 使用可选链
};
</script>
<template> 
    <div id="container">
        <!-- 修改信息的按钮 -->
        <el-button @click="updateForm">修改信息</el-button>
        <!-- FormModel 组件,接收 props 并监听 save 事件 -->
     <!-- dialogVisible v-model 的 语法糖 进行 双向 绑定   绑定了 isVisible-->
        <FormModel v-model:dialog-visible="isVisible" :dialog-config="dialogConfig" @save="handleSave" @cancel="handleCancel"/>
    </div>
</template>
<script lang="ts" setup>
import { ref, reactive } from 'vue';
import FormModel from '../src/views/A.vue'; // 确保路径正确  
// 使用 ref 来创建响应式的布尔值,初始为 false(对话框默认关闭)  
const isVisible = ref(false);
// 使用 reactive 来创建响应式的配置对象  
const dialogConfig = reactive({
    dialogTitle: "封装的第一个Dialog弹窗组件",
});
// 更新表单(打开对话框)的方法  
const updateForm = () => {
    // 每次点击修改信息按钮时,强制将isVisible设置为true,确保对话框能够正确显示  
    isVisible.value = true;
};
interface FormValue {
    name: string
}
// 处理保存事件的方法  
const handleSave = (data: FormValue) => {
    // 假设保存后需要关闭对话框,但也可以由子组件控制  
    isVisible.value = false;
  console.log(data)
};
const handleCancel = (show:boolean)=>{
    isVisible.value = show;
};
</script>



相关文章
|
2月前
|
JavaScript 前端开发 开发者
TypeScript :基本配置&数据的基本类型
本文介绍了TypeScript的安装、常见问题及解决方案、配置与使用方法。包括通过npm全局安装TypeScript、设置PowerShell执行策略、初始化项目、配置模块声明、处理数据类型等。详细步骤和代码示例帮助开发者快速上手。
|
2月前
|
存储 JavaScript 前端开发
TypeScript :使用mock提供数据&as const 的使用&tsconfig.json配置
本文介绍了如何在项目中使用 Mock 提供数据,包括安装依赖、配置 Vite 和 TypeScript,以及如何使用 `as const`、元组和 tsconfig.json 配置文件。通过这些配置,可以实现更灵活和高效的开发体验。
|
7月前
|
缓存 JavaScript 前端开发
【TypeScript技术专栏】TypeScript与GraphQL数据交互
【4月更文挑战第30天】本文探讨了在TypeScript中使用GraphQL进行数据交互的优势和方法。GraphQL作为一种API查询语言,解决了REST API的过度获取和欠获取问题,允许客户端按需请求数据。结合TypeScript,可以构建强类型、高效的前端数据层。文章涵盖了GraphQL简介、为何选择GraphQL、在TypeScript中的使用、查询和变异、相关工具库以及最佳实践。通过案例分析,展示了GitHub、Shopify和The New York Times等大公司如何成功应用这一技术组合。学习并掌握GraphQL和TypeScript将提升开发者的技术能力和项目效率。
53 0
|
7月前
|
JavaScript
TypeScript 实现扑克数据花色、数值获取和生成
TypeScript 实现扑克数据花色、数值获取和生成
|
JavaScript 前端开发
【TypeScript】原始数据的类型详解概念
【TypeScript】原始数据的类型详解概念
typescript28-枚举类型的值以及数据枚举
typescript28-枚举类型的值以及数据枚举
96 0
typescript28-枚举类型的值以及数据枚举
|
JSON 移动开发 JavaScript
使用TypeScript校验运行时数据
对于前端程序猿,常见的开发流程是: 1.前后端约定接口 2.后端给出接口文档 3.根据接口编写 TypeScript 类型定义 4.开发完成进行联调
592 0
使用TypeScript校验运行时数据
|
2月前
|
JavaScript 前端开发 安全
深入理解TypeScript:增强JavaScript的类型安全性
【10月更文挑战第8天】深入理解TypeScript:增强JavaScript的类型安全性
50 0
|
2月前
|
JavaScript 前端开发 开发者
深入理解TypeScript:类型系统与实用技巧
【10月更文挑战第8天】深入理解TypeScript:类型系统与实用技巧
|
3月前
|
存储 JavaScript
typeScript进阶(11)_元组类型
本文介绍了TypeScript中的元组(Tuple)类型,它是一种特殊的数组类型,可以存储不同类型的元素。文章通过示例展示了如何声明元组类型以及如何给元组赋值。元组类型在定义时需要指定数组中每一项的类型,且在赋值时必须满足这些类型约束。此外,还探讨了如何给元组类型添加额外的元素,这些元素必须符合元组类型中定义的类型联合。
48 0