v-model指令
父组件: 子组件:defineProps<{age:number}>() defineEmits(['update:age']) v-model相当于 props和自定义事件的语法糖,实现父子组件双向通信
useAttrs()
在子组件中使用 const attrs中包含父组件传递过来的属性和自定义事件,前提是除去props已传递的,
ref和$parent
父组件获取子组件实例 用ref, 子组件访问父组件方法和属性,用$parent
<button @click="getParent($parent)">获取父组件</button>
function getParent(parent) {
console.log("父组件", parent.changeAName());
}
父子之间想获取对方属性方法都要在对方组件里用defineExpose()暴露出来,V3默认是外面不能访问组件内部的属性的
provide和inject 不是响应式数据
pinia官网:pinia.web3doc.top/
插槽
匿名插槽,具名插槽,作用域插槽(需要特别注意)
作用域插槽是:子组件将数据传递给父组件(看官网)
需要加上name属性,否则会被默认为匿名插槽,会和原本的匿名插槽冲突
工程化相关
1.安装pnpm
npm install pnpm -g
pnpm create vite
2.安装eslint
pnpm i eslint -D
生成配置文件:.eslint.cjs
npx eslint --init
eslint 配置文件
module.exports = {
//运行环境
"env": {
"browser": true,//浏览器端
"es2021": true,//es2021
},
//规则继承
"extends": [
//全部规则默认是关闭的,这个配置项开启推荐规则,推荐规则参照文档
//比如:函数不能重名、对象不能出现重复key
"eslint:recommended",
//vue3语法规则
"plugin:vue/vue3-essential",
//ts语法规则
"plugin:@typescript-eslint/recommended"
],
//要为特定类型的文件指定处理器
"overrides": [
],
//指定解析器:解析器
//Esprima 默认解析器
//Babel-ESLint babel解析器
//@typescript-eslint/parser ts解析器
"parser": "@typescript-eslint/parser",
//指定解析器选项
"parserOptions": {
"ecmaVersion": "latest",//校验ECMA最新版本
"sourceType": "module"//设置为"script"(默认),或者"module"代码在ECMAScript模块中
},
//ESLint支持使用第三方插件。在使用插件之前,您必须使用npm安装它
//该eslint-plugin-前缀可以从插件名称被省略
"plugins": [
"vue",
"@typescript-eslint"
],
//eslint规则
"rules": {
}
}
vue3环境代码校验插件
# 让所有与prettier规则存在冲突的Eslint rules失效,并使用prettier进行代码检查
"eslint-config-prettier": "^8.6.0",
"eslint-plugin-import": "^2.27.5",
"eslint-plugin-node": "^11.1.0",
# 运行更漂亮的Eslint,使prettier规则优先级更高,Eslint优先级低
"eslint-plugin-prettier": "^4.2.1",
# vue.js的Eslint插件(查找vue语法错误,发现错误指令,查找违规风格指南
"eslint-plugin-vue": "^9.9.0",
# 该解析器允许使用Eslint校验所有babel code
"@babel/eslint-parser": "^7.19.1",
------------------------------------
pnpm install -D eslint-plugin-import eslint-plugin-vue eslint-plugin-node eslint-plugin-prettier eslint-config-prettier eslint-plugin-node @babel/eslint-parser
最后修改eslint配置文件
// @see https://eslint.bootcss.com/docs/rules/
module.exports = {
env: {
browser: true,
es2021: true,
node: true,
jest: true,
},
/* 指定如何解析语法 */
parser: 'vue-eslint-parser',
/** 优先级低于 parse 的语法解析配置 */
parserOptions: {
ecmaVersion: 'latest',
sourceType: 'module',
parser: '@typescript-eslint/parser',
jsxPragma: 'React',
ecmaFeatures: {
jsx: true,
},
},
/* 继承已有的规则 */
extends: [
'eslint:recommended',
'plugin:vue/vue3-essential',
'plugin:@typescript-eslint/recommended',
'plugin:prettier/recommended',
],
plugins: ['vue', '@typescript-eslint'],
/*
* "off" 或 0 ==> 关闭规则
* "warn" 或 1 ==> 打开的规则作为警告(不影响代码执行)
* "error" 或 2 ==> 规则作为一个错误(代码不能执行,界面报错)
*/
rules: {
// eslint(https://eslint.bootcss.com/docs/rules/)
'no-var': 'error', // 要求使用 let 或 const 而不是 var
'no-multiple-empty-lines': ['warn', { max: 1 }], // 不允许多个空行
'no-console': process.env.NODE_ENV === 'production' ? 'error' : 'off',
'no-debugger': process.env.NODE_ENV === 'production' ? 'error' : 'off',
'no-unexpected-multiline': 'error', // 禁止空余的多行
'no-useless-escape': 'off', // 禁止不必要的转义字符
// typeScript (https://typescript-eslint.io/rules)
'@typescript-eslint/no-unused-vars': 'error', // 禁止定义未使用的变量
'@typescript-eslint/prefer-ts-expect-error': 'error', // 禁止使用 @ts-ignore
'@typescript-eslint/no-explicit-any': 'off', // 禁止使用 any 类型
'@typescript-eslint/no-non-null-assertion': 'off',
'@typescript-eslint/no-namespace': 'off', // 禁止使用自定义 TypeScript 模块和命名空间。
'@typescript-eslint/semi': 'off',
// eslint-plugin-vue (https://eslint.vuejs.org/rules/)
'vue/multi-word-component-names': 'off', // 要求组件名称始终为 “-” 链接的单词
'vue/script-setup-uses-vars': 'error', // 防止<script setup>使用的变量<template>被标记为未使用
'vue/no-mutating-props': 'off', // 不允许组件 prop的改变
'vue/attribute-hyphenation': 'off', // 对模板中的自定义组件强制执行属性命名样式
},
}
新建 .eslintignore
添加:
dist
node_modules
package.json新增两个运行脚本
"scripts": {
"lint": "eslint src",
"fix": "eslint src --fix",
}
- 安装prettier
npm install -D eslint-plugin-prettier prettier eslint-config-prettier
创建 prettierrc.json
添加:{
"singleQuote": true,
"semi": false,
"bracketSpacing": true,
"htmlWhitespaceSensitivity": "ignore",
"endOfLine": "auto",
"trailingComma": "all",
"tabWidth": 2
}
创建: .prettierignore忽略文件
添加:
/dist/*
/html/*
.local
/node_modules/**
**/*.svg
**/*.sh
/public/*
- husky -----前提是配置好了npm run format要做的事
需要利用husky在代码提交之前触发git hook(git在客户端的钩子),然后执行`pnpm run format`来自动的格式化我们的代码。(或者其他自己配置的会格式化代码的命令)
npx husky-init
会在根目录下生成个一个.husky目录,在这个目录下面会有一个pre-commit文件,这个文件里面的命令在我们执行commit的时候就会执行
在`.husky/pre-commit`文件添加如下命令:
#!/usr/bin/env sh
. "$(dirname -- "$0")/_/husky.sh"
npm run format 加这行
当我们对代码进行commit操作的时候,就会执行命令,对代码进行格式化,然后再提交。
- commitlint---强制commit 的格式
npm add @commitlint/config-conventional @commitlint/cli -D
新建`commitlint.config.cjs`(注意是cjs),然后添加下面的代码
module.exports = {
extends: ['@commitlint/config-conventional'],
// 校验规则
rules: {
'type-enum': [
2,
'always',
[
'feat',
'fix',
'docs',
'style',
'refactor',
'perf',
'test',
'chore',
'revert',
'build',
],
],
'type-case': [0],
'type-empty': [0],
'scope-empty': [0],
'scope-case': [0],
'subject-full-stop': [0, 'never'],
'subject-case': [0, 'never'],
'header-max-length': [0, 'always', 72],
},
}
在package.json中的scripts 添加命令 :
"commitlint": "commitlint --config commitlint.config.cjs -e -V"
然后:
npx husky add .husky/commit-msg
在生成的commit-msg文件中添加下面的命令
#!/usr/bin/env sh
. "$(dirname -- "$0")/_/husky.sh"
npm run commitlint
后边再commit信息的时候,就需要
'feat',//新特性、新功能
'fix',//修改bug
'docs',//文档修改
'style',//代码格式修改, 注意不是 css 修改
'refactor',//代码重构
'perf',//优化相关,比如提升性能、体验
'test',//测试用例修改
'chore',//其他修改, 比如改变构建流程、或者增加依赖库、工具等
'revert',//回滚到上一个版本
'build',//编译相关的修改,例如发布版本、对项目构建或者依赖的改动
- 封装SVG
npm install vite-plugin-svg-icons -D
在vite.config.ts中
import { createSvgIconsPlugin } from 'vite-plugin-svg-icons'
pligins插件中配置
plugins: [
createSvgIconsPlugin({
// Specify the icon folder to be cached
iconDirs: [path.resolve(process.cwd(), 'src/assets/icons')],
// Specify symbolId format
symbolId: 'icon-[dir]-[name]',
}),
],
入口文件导入
import 'virtual:svg-icons-register'
封装的SvgIcon组件,一种方式
<template>
<svg :class="className">
<use :xlink:href="prefix + name" :fill="currentColor"></use>
</svg>
</template>
**注册成全局组件**
import {type App, Component} from 'vue'
import SvgIcon from './SvgIcon.vue';
const allComponents:{[key: string]: Component} = {SvgIcon}
export default {
install(app: App){
console.log('app', app);
Object.keys(allComponents).forEach( key => {
app.component(key, allComponents[key])
})
}
}
// 注册全局组件
import globalComponents from "@/components";
createApp(App).use(router).use(globalComponents).mount("#app");