2024-08-23

在Vue 3和TypeScript中,父子组件传值可以通过props和emit进行。以下是一个简单的示例:

父组件 (ParentComponent.vue):




<template>
  <div>
    <child-component :parentData="parentData" @childEvent="handleChildEvent" />
  </div>
</template>
 
<script setup lang="ts">
import { ref } from 'vue';
import ChildComponent from './ChildComponent.vue';
 
const parentData = ref('Hello from parent');
 
const handleChildEvent = (value: string) => {
  console.log(`Received: ${value}`);
};
</script>

子组件 (ChildComponent.vue):




<template>
  <div>
    <p>{{ parentData }}</p>
    <button @click="sendToParent">Send to Parent</button>
  </div>
</template>
 
<script setup lang="ts">
import { defineProps, defineEmits } from 'vue';
 
const props = defineProps<{
  parentData: string;
}>();
 
const emit = defineEmits(['childEvent']);
 
const sendToParent = () => {
  emit('childEvent', 'Data from child');
};
</script>

在这个例子中,父组件通过props向子组件传递数据,并监听一个自定义事件childEvent。子组件通过点击按钮触发一个事件,并发送数据给父组件。这里使用了Vue 3的<script setup>语法,并且类型安全地使用了TypeScript。

2024-08-23

在TypeScript中,类型守卫(Type Guard)是一种机制,用来保证在复杂的类型环境中,变量的类型在特定的条件下得到缩小。类型守卫主要有以下几种形式:

  1. typeof 类型守卫:检查变量的类型。



function handle(x: string | number) {
    if (typeof x === "string") {
        // 在这个分支中,x 的类型被缩小为 string
    } else {
        // 在这个分支中,x 的类型被缩小为 number
    }
}
  1. instanceof 类型守卫:检查对象的类型。



class Animal {}
class Dog extends Animal {}
 
function checkType(animal: Animal) {
    if (animal instanceof Dog) {
        // 在这个分支中,animal 的类型被缩小为 Dog
    } else {
        // 在这个分支中,animal 的类型被缩小为 Animal
    }
}
  1. in 类型守卫:检查对象是否具有某个属性。



interface A {
    x: number;
}
interface B {
    y: string;
}
 
function checkKey(obj: A | B) {
    if ("x" in obj) {
        // 在这个分支中,obj 的类型被缩小为 A
    } else {
        // 在这个分支中,obj 的类型被缩小为 B
    }
}
  1. 具有谓词的自定义类型守卫:通过函数来判断类型。



function isLengthy(arg: string | number): arg is string {
    return typeof arg === "string" && arg.length > 0;
}
 
function handle(x: string | number) {
    if (isLengthy(x)) {
        // 在这个分支中,x 的类型被缩小为 string
    } else {
        // 在这个分支中,x 的类型被缩小为 number
    }
}

这些是TypeScript中常见的类型守卫方法。在实际应用中,可以根据需要选择合适的类型守卫来缩小变量的类型,从而在编译时进行类型检查。

2024-08-23

要发布一个TypeScript的npm包,你需要做以下几步:

  1. 初始化你的npm项目:



npm init
  1. 安装TypeScript和tsc(TypeScript编译器)作为开发依赖:



npm install typescript --save-dev
  1. 创建一个tsconfig.json文件来配置TypeScript编译选项:



{
  "compilerOptions": {
    "module": "commonjs",
    "target": "es5",
    "sourceMap": true,
    "outDir": "dist"
  },
  "include": [
    "src/**/*"
  ]
}
  1. 在你的package.json中添加一个脚本来运行编译过程:



{
  "scripts": {
    "build": "tsc"
  }
}
  1. 编写你的TypeScript模块,并将其放在src目录下。
  2. 运行编译过程:



npm run build
  1. 发布你的npm包。首先确保你已经登录到npm:



npm login
  1. 发布包到npm:



npm publish

确保你的npm账号有权限发布包到对应的npm registry。如果你的包有多个模块,你可以在单个npm包中发布它们,只要在你的tsconfig.json中正确配置"include"和"exclude"属性,并确保你的模块都导出了合适的值。

以下是一个简单的TypeScript模块示例:




// src/math.ts
export const add = (a: number, b: number): number => {
  return a + b;
};
 
export const subtract = (a: number, b: number): number => {
  return a - b;
};

在你的入口文件(例如index.ts)中导出所有你想暴露的模块:




// src/index.ts
export * from './math';

确保你的"main"字段在package.json中指向了正确的入口文件:




{
  "name": "your-package-name",
  "version": "1.0.0",
  "main": "dist/index.js",
  // ...
}

当你运行npm publish时,npm会使用你的tsconfig.json文件来编译TypeScript代码,并发布编译后的JavaScript文件。

2024-08-23

为了在Vite + Vue 3项目中集成ESLint、Prettier、Stylelint和Husky,你需要按照以下步骤操作:

  1. 安装所需依赖:



npm install eslint prettier eslint-config-prettier eslint-plugin-prettier eslint-plugin-vue stylelint husky lint-staged --save-dev
  1. 在项目根目录下创建.eslintrc.js,配置ESLint规则:



module.exports = {
  extends: [
    'plugin:vue/vue3-essential',
    'eslint:recommended',
    'plugin:prettier/recommended'
  ],
  rules: {
    // 自定义规则
  }
};
  1. 创建.prettierrc,配置Prettier规则:



{
  "semi": false,
  "singleQuote": true,
  "trailingComma": "es5",
  "bracketSpacing": true,
  "jsxBracketSameLine": false,
  "arrowParens": "avoid",
  "endOfLine": "auto"
}
  1. 创建.stylelintrc.js,配置Stylelint规则:



module.exports = {
  extends: 'stylelint-config-standard',
  rules: {
    // 自定义样式规则
  }
};
  1. package.json中添加lint-staged配置:



{
  "lint-staged": {
    "*.{js,vue,ts}": [
      "eslint --fix",
      "git add"
    ],
    "*.{css,scss,sass}": [
      "stylelint --fix",
      "git add"
    ]
  }
}
  1. 设置Husky以运行lint-staged,当提交前运行脚本:



{
  "husky": {
    "hooks": {
      "pre-commit": "lint-staged"
    }
  }
}

这样,你的Vite + Vue 3项目就配置了ESLint、Prettier、Stylelint和Husky,以确保代码风格和质量的一致性。在提交前,lint-staged会自动修复可修复的问题,并添加修改后的文件以包含在提交中。如果发现不符合规则的代码提交,将会中断提交过程,直到代码修正。

2024-08-23

React框架通常与TypeScript一起使用来构建更可维护和可扩展的JavaScript应用程序。以下是一个简单的React组件示例,使用TypeScript编写:




import React from 'react';
import PropTypes from 'prop-types'; // 使用PropTypes进行类型检查
 
// 函数组件
const Greeting: React.FC<{ name: string }> = ({ name }) => {
  return <h1>Hello, {name}!</h1>;
};
 
// 对组件的props进行类型声明和属性校验
Greeting.propTypes = {
  name: PropTypes.string.isRequired,
};
 
export default Greeting;

在这个例子中,我们创建了一个名为Greeting的函数组件,它接受一个名为name的属性,该属性被声明为字符串类型,并且是必需的。我们使用React.FC来表示这是一个使用TypeScript的函数组件,并且我们从prop-types库导入了PropTypes,用于进行类型检查。

请注意,prop-types库是可选的,但它提供了一种验证组件属性的方法。如果你想使用TypeScript的内建类型系统进行类型检查,你可以使用TypeScript来类型声明props,而不是使用PropTypes




import React from 'react';
 
type GreetingProps = {
  name: string;
};
 
const Greeting: React.FC<GreetingProps> = ({ name }) => {
  return <h1>Hello, {name}!</h1>;
};
 
export default Greeting;

在这个例子中,我们使用了TypeScript的类型声明来指定GreetingProps,然后将其作为通用类型应用到了Greeting组件上。这样,你就可以在编译时获得类型检查的好处,而不需要使用额外的库。

2024-08-23

以下是使用Yarn创建Vue 3项目的步骤:

  1. 确保你已经安装了Node.js和Yarn。
  2. 在命令行中运行以下命令来创建一个新的Vue 3项目:



yarn create vite
  1. 在创建过程中,选择vue-ts模板作为项目基础。
  2. 输入项目名称,例如my-vue3-project
  3. 选择Vue 3作为框架。
  4. 选择是否需要使用路由和状态管理。
  5. 最后,选择文件夹路径和是否将项目初始化为Git仓库。

以下是一个简化的命令序列示例:




yarn create vite
? Select a framework
  Vanilla
> Vue
  React
  React & Vanilla
  Angular
  Svelte
? Select a variant
  JavaScript
  TypeScript
> TypeScript
? Enter a project name (e.g. my-vue-app) my-vue3-project
? Select a template (Use arrow keys)
> Vue 3
  Vue 2
? Select a style preprocessor (PostCSS, Sass, Less)
? Select a linter / formatter (ESLint with Airbnb config)
? Select additional lint features (Lint on save, Lint and fix on commit)
? Where do you prefer placing config for Babel, PostCSS, ESLint, etc.?
> In dedicated config files
? Save this as a preset for future projects?

完成后,Yarn会自动安装依赖并设置项目。

现在,你有了一个使用Vite搭建、基于Vue 3和TypeScript的新项目。

2024-08-23

在Vue 3和TypeScript项目中,可以使用Vite作为构建工具来自动导入API和组件。以下是一个简化的例子,展示如何自动导入API和组件:

首先,确保你的项目设置允许从特定的路径自动导入文件。例如,在tsconfig.json中配置baseUrlpaths




{
  "compilerOptions": {
    "baseUrl": ".", // 设置基础路径为项目根目录
    "paths": {
      "@/*": ["src/*"] // 表示src目录下的任何文件都可以通过@/来访问
    }
    // ...其他配置
  }
}

然后,在.vitepress/config.ts或你的Vue项目中的vite.config.ts配置文件中,使用Vite的插件来实现自动导入:




import { defineConfig } from 'vite';
import vue from '@vitejs/plugin-vue';
import path from 'path';
 
export default defineConfig({
  plugins: [vue()],
  resolve: {
    alias: {
      '@': path.resolve(__dirname, 'src'), // 设置别名以简化导入路径
    },
  },
});

最后,在你的组件或者API使用文件中,可以直接从对应的路径导入:




// 自动导入API
import myApiFunction from '@/api/myApi.js';
 
// 自动导入组件
import MyComponent from '@/components/MyComponent.vue';
 
// 使用API或组件
myApiFunction();

确保你的项目结构和导入路径与配置相匹配,这样就可以实现自动导入API和组件。

2024-08-23



{
  "compilerOptions": {
    "target": "es5",                          /* 指定编译目标: 'ES3', 'ES5', 'ES2015', 'ES2016', 'ES2017',或 'ESNEXT'。*/
    "module": "commonjs",                     /* 指定模块系统: 'commonjs', 'amd', 'system', 'umd', 'es2015'或 'esnext'。*/
    "lib": ["es2015", "dom"],                  /* 指定要包含在编译中的库文件。 */
    "sourceMap": true,                         /* 生成相应的 '.map' 文件。*/
    "outDir": "./dist",                        /* 指定输出文件目录。*/
    "strict": true,                            /* 启用所有严格类型检查选项。*/
    "noUnusedLocals": true,                   /* 有未使用的变量时报错。*/
    "noUnusedParameters": true,               /* 有未使用的参数时报错。*/
    "pretty": true,                            /* 生成代码时,采用美观的打印格式。*/
    "experimentalDecorators": true,           /* 允许使用实验性的装饰器特性。*/
    "emitDecoratorMetadata": true              /* 为装饰器生成元数据。*/
  },
  "include": [
    "src/**/*"                                /* 包含'src'目录及其子目录下所有文件。*/
  ],
  "exclude": [
    "node_modules", "dist", "**/*.spec.ts"    /* 排除'node_modules','dist'目录及所有的'.spec.ts'测试文件。*/
  ]
}

这个tsconfig.json配置文件提供了一系列实用的编译选项,适用于大多数TypeScript项目。它指定了编译输出的版本目标、模块系统、引用库、源映射文件的生成、类型检查的严格程度等。同时,它还指定了包含和排除哪些文件目录。这个配置文件可以直接用于大多数TypeScript项目,并根据项目需求进行调整。

2024-08-23

在TypeScript中,元组(Tuple)类型允许你表示一个已知元素数量和类型的数组。

元组元素的数量和类型是固定的,并且可以不同。

下面是一个TypeScript中元组的简单示例:




// 定义一个元组,包含两个类型不同的元素:一个是字符串,另一个是数字
let tuple: [string, number];
 
// 初始化元组
tuple = ['hello', 10]; // 正确
 
// 错误的初始化,类型不匹配
// tuple = [10, 'hello']; // 错误:期望第一个元素是字符串,但是得到了数字
 
// 错误的初始化,元素数量不匹配
// tuple = ['hello']; // 错误:期望有两个元素,但是只提供了一个
 
// 访问元组中的元素
console.log(tuple[0]); // 输出:hello
console.log(tuple[1]); // 输出:10
 
// 修改元组中的元素
tuple[0] = 'world';
tuple[1] = 20;
 
console.log(tuple[0]); // 输出:world
console.log(tuple[1]); // 输出:20

在这个例子中,我们定义了一个元组tuple,它有两个元素,第一个是字符串类型,第二个是数字类型。我们初始化了这个元组,并且演示了如何访问和修改它的元素。

元组在定义数据库模型或处理来自外部源(如CSV文件)的数据时特别有用,因为这些数据的结构是已知的,但是长度和类型可能不同。

2024-08-23



// 定义请求配置的类型
interface RequestConfig {
  url: string;
  method?: 'GET' | 'POST';
  data?: object;
  header?: object;
}
 
// 封装uni-request的方法
function uniRequest(config: RequestConfig): Promise<any> {
  return new Promise((resolve, reject) => {
    uni.request({
      url: config.url,
      method: config.method || 'GET',
      data: config.data,
      header: config.header,
      success: (res) => {
        resolve(res);
      },
      fail: (err) => {
        reject(err);
      },
    });
  });
}
 
// 使用封装后的uniRequest方法
const getUserInfo = (userId: string): Promise<any> => {
  return uniRequest({
    url: `/api/user/${userId}`,
    method: 'GET',
  });
};
 
// 调用getUserInfo方法
getUserInfo('12345').then(response => {
  console.log(response.data);
}).catch(error => {
  console.error(error);
});

这个代码示例展示了如何在TypeScript中封装uni-request,并提供一个简单的getUserInfo方法,用于获取用户信息。这个例子遵循了良好的编码实践,包括使用TypeScript的接口(RequestConfig)来定义方法的配置对象,以及使用Promise处理异步操作。