如今,小程序已经成了日常生活不可缺少的应用之一,掌握小程序开发对于前端来说,几乎是一个必备的技能。由于原生小程序语法开发体验差,缺乏生态插件等原因,已经诞生过许多第三方框架,如uniapp、taro、wepy、mpvue等,而随着时间的推移,uniapp及taro框架就如同现在vue及react两个主流前端框架一样,被大多数小程序开发者采用。
对于使用vue技术栈的同学来说,想必都知道vue3已经如火如荼,vue主流生态都在“争先恐后”升级至vue3版本,而作为vue语法开发小程序的uniapp框架,也早已经跟上这波潮流,推出了vue3 + vite + setup + typescript开发小程序版本,不论在开发体验还是性能上,都带来了质的飞跃。(详见官方社区文章《vue3和vite双向加持,uni-app性能再次提升》)
“新事物的诞生往往意味着新的开始”,在vue3 + vite + setup + typescript的未来趋势下,意味着我们需要对以前vue2版本学习的经验知识也要跟着做一番迭代,甚至推翻重来。
接下来将从初始化代码项目开始,一步步带你基于uniapp + vue3 + vite + setup + typescript去搭建初始化一个小程序项目,在这过程中会引导你思考如何去做封装优化相关API方法等。举个例子,路由跳转微信官方API写法如下:
wx.navigateTo({
url: '/pages/index/test?id=1',
})
这种写法平时写个demo倒还好,但在真实项目中涉及众多页面跳转,每次跳转都要写这么长的一段代码,这种体验是很差的。在路由封装模块章节中,经过封装的后的写法如下:
router.navigate('index', {id: 1})
这么一对比是不是一下子清爽很多了呢?
npm install -g @vue/cli@4
npx degit dcloudio/uni-preset-vue#vite-ts my-vue3-project
(如命令行创建失败,请直接访问 gitee下载模板)
使用script setup语法,需要配合volar插件使用,在vscode插件中搜索volar:
然后选择Vue Volar extension Pack插件(该插件包含了vue3项目常用到的各种插件)。至此,我们的准备工作就算完成了!
初始化项目的代码,还非常的简陋,此时我们不能急着立刻上手写业务代码,而是要先完成“基建”工作,只有基建搭好了,才方便后续项目代码的开发和维护。这些基建工作包括诸如:设置统一代码风格规范,路径别名,样式管理等,接下来就开始一步步实现。
正所谓“无规矩不成方圆”,一个好的项目代码,必定是有着一定的代码规范约束。目前主流方案是使用Eslint + Prettier进行设置。
在终端中输入:
npm i @typescript-eslint/eslint-plugin @typescript-eslint/parser eslint eslint-config-prettier eslint-plugin-import eslint-plugin-prettier eslint-plugin-vue vue-eslint-parser -D
安装完依赖后,我们在根目录下新建.eslintrc.js文件,内容如下:
module.exports = {
root: true,
env: {
browser: true,
node: true,
es6: true,
},
parser: 'vue-eslint-parser',
parserOptions: {
parser: '@typescript-eslint/parser',
ecmaVersion: 2020,
sourceType: 'module',
jsxPragma: 'React',
ecmaFeatures: {
jsx: true,
tsx: true,
},
},
plugins: ['@typescript-eslint', 'prettier', 'import'],
extends: [
'eslint:recommended',
'plugin:@typescript-eslint/recommended',
'plugin:vue/vue3-recommended',
'prettier',
],
overrides: [
{
files: ['*.ts', '*.tsx', '*.vue'],
rules: {
'no-undef': 'off',
},
},
],
rules: {
'no-restricted-syntax': ['error', 'LabeledStatement', 'WithStatement'],
camelcase: ['error', { properties: 'never' }],
'no-var': 'error',
'no-empty': ['error', { allowEmptyCatch: true }],
'no-void': 'error',
'prefer-const': [
'warn',
{ destructuring: 'all', ignoreReadBeforeAssign: true },
],
'prefer-template': 'error',
'object-shorthand': [
'error',
'always',
{ ignoreConstructors: false, avoidQuotes: true },
],
'block-scoped-var': 'error',
'no-constant-condition': ['error', { checkLoops: false }],
'no-redeclare': 'off',
'@typescript-eslint/no-redeclare': 'error',
'@typescript-eslint/ban-ts-comment': 'off',
'@typescript-eslint/ban-types': 'off',
'@typescript-eslint/explicit-module-boundary-types': 'off',
'@typescript-eslint/no-empty-function': 'off',
'@typescript-eslint/no-explicit-any': 'off',
'@typescript-eslint/no-non-null-assertion': 'off',
'@typescript-eslint/no-non-null-asserted-optional-chain': 'off',
'@typescript-eslint/no-var-requires': 'off',
'@typescript-eslint/no-unused-vars': [
'error',
{
argsIgnorePattern: '^_',
varsIgnorePattern: '^_',
},
],
'no-unused-vars': [
'error',
{
argsIgnorePattern: '^_',
varsIgnorePattern: '^_',
},
],
// vue
'vue/no-v-html': 'off',
'vue/require-default-prop': 'off',
'vue/require-explicit-emits': 'off',
'vue/multi-word-component-names': 'off',
// prettier
'prettier/prettier': 'error',
// import
'import/first': 'error',
'import/no-duplicates': 'error',
'import/order': [
'error',
{
groups: [
'builtin',
'external',
'internal',
'parent',
'sibling',
'index',
'object',
'type',
],
pathGroupsExcludedImportTypes: ['type'],
},
],
},
}
创建ESLint忽略文件配置 .eslintignore,来指定我们不需要进行检查的目录或文件
node_modules
dist
*.md
*.woff
*.ttf
.vscode
.idea
{
"semi": false,
"tabWidth": 2,
"trailingComma": "all",
"singleQuote": true,
"endOfLine": "auto"
}
**/*.svg
**/*.ico
package.json
package-lock.json
/dist
.DS_Store
.eslintignore
*.png
.editorconfig
.gitignore
.prettierignore
.eslintcache
*.lock
yarn-error.log
**/node_modules/**
修改vite.config.ts,这里我们先设置两个别名,一个是针对src下代码文件,一个是针对图片静态文件,内容如下:
import path from 'path'
import { defineConfig } from 'vite'
import uni from '@dcloudio/vite-plugin-uni'
// https://vitejs.dev/config/
export default defineConfig({
plugins: [uni()],
resolve: {
alias: {
'@': path.resolve(__dirname, 'src'),
'@img': path.resolve(__dirname, 'src/static/images'),
},
},
})
接着我们在.vue文件的template中可以这么写:
<image class="logo" src="@img/logo.jpg" />
假设我们要引入src -> router -> index.ts文件,在script里面这么写:
可以看到,此时ts会报找不到模块的错误提示,此时我们需要在tsconfig.json文件做相关修改:
在compilerOptions下添加
"paths": {
"@/*": ["src/*"]
}
即可。
css预处理比较成熟的有sass,less,stylus,大家可以根据自己选择对应的css预处理器。这里以sass为例:
先安装相关依赖
npm i sass sass-loader -D
接着在src目录下创建styles文件夹,存放样式相关文件。
例如:
$font-size: 28rpx;
$primary-color: #54d339;
例如
@mixin flex-row {
display: flex;
align-items: center;
}
@mixin flex-column {
display: flex;
flex-direction: column;
}
// 文字超出隐藏
@mixin text-eli {
overflow: hidden;
text-overflow: ellipsis;
display: -webkit-box;
-webkit-box-orient: vertical;
}
@import "./vars.scss";
@import "./mixins.scss";
page {
box-sizing: border-box;
font-size: $font-size;
}
view,
text {
font-size: $font-size;
box-sizing: border-box;
color: #333;
}
// 去除按钮默认边框
button::after {
border: none;
}
.flex-row {
@include flex-row();
}
.flex-row-between {
@include flex-row();
justify-content: space-between;
}
.flex-row-around {
@include flex-row();
justify-content: space-around;
}
.flex-row-center {
@include flex-row();
justify-content: center;
}
.flex-row-end {
@include flex-row();
justify-content: flex-end;
}
.flex-column {
@include flex-column();
}
.flex-column-center {
@include flex-column();
align-items: center;
justify-content: center;
}
.flex1 {
flex: 1;
height: 100%;
}
.text-line1 {
@include text-eli();
-webkit-line-clamp: 1;
}
.text-line2 {
@include text-eli();
-webkit-line-clamp: 2;
}
/* 间隔相关 */
.pad20 {
padding: 20rpx;
}
.mb32 {
margin-bottom: 32rpx;
}
.mb40 {
margin-bottom: 40rpx;
}
.mt60 {
margin-top: 60rpx;
}
.ml20 {
margin-left: 20rpx;
}
.ml40 {
margin-left: 40rpx;
}
/* 字体大小相关 */
.font24 {
font-size: 24rpx;
}
.font48 {
font-size: 48rpx;
}
.font36 {
font-size: 36rpx;
}
.font32 {
font-size: 32rpx;
}
.font-bold {
font-weight: bold;
}
.text-center {
text-align: center;
}
.text-white {
color: #fff;
}
.text-color-main {
color: $main;
}
.text-color-6 {
color: #666;
}
.text-color-9 {
color: #999;
}
.bg-white {
background-color: #fff;
}
.bg-gray {
background-color: $bg-gray;
}
<style lang="scss">
/*全局公共样式 */
@import "./styles/common.scss";
</style>
我们在vars.scss文件中定义的颜色变量,在页面中使用时,需要手动导入才能使用。那要怎么实现自动导入呢?
我们可以在vite.config.js中配置即可:
在return对象下新增:
css: {
preprocessorOptions: {
scss: {
additionalData: `@import "@/styles/vars.scss";`,
},
},
}
这样我们在页面中就可以直接使用vars中定义的颜色变量了。此时还没完,我们还可以借助一个插件帮助我们识别定义的变量: SCSS IntelliSense
在vscode中安装该插件后,如下图可以看到已经给出提示,开发体验又上升了一个台阶!
vue3 script setup 写法中,组件间通信有defineProps跟defineEmits这种编译器宏方法,无需导入就可以直接使用。而对于vue当中导出的代码,我们还是需要手动显示引入,如下:
import { computed, ref } from 'vue'
const count = ref(0)
那有没有办法像defineProps等编译器宏方法一样,无需手动导入就可以直接使用呢?对此,我们可以使用unplugin-auto-import npm包实现。
npm i -D unplugin-auto-import
import AutoImport from 'unplugin-auto-import/vite'
plugins: [
uni(),
AutoImport({
imports: ['vue', 'uni-app'],
dts: './auto-imports.d.ts', // 安装好依赖后,重新运行编译即可自动在根目录下生成此声明文件
}),
]
接着我们需要在tsconfig.ts文件include属性中引入声明文件,否则直接使用ts会报错。
"include": [
"src/**/*.ts",
"src/**/*.d.ts",
"src/**/*.vue",
"auto-imports.d.ts"
]
接着我们就可以直接在代码中无需导入直接使用vue中方法了:
// import { computed, ref } from 'vue' 这行代码不用写了
const count = ref(0)
至此,我们已经完成了项目代码初始化及基建工作(代码风格统一,样式管理,路由别名设置),并通过一些插件提升代码开发体验。当然这只是起始篇,接下来更有趣的请移步《状态管理篇》。
阅读量:2036
点赞量:0
收藏量:0