ホームページ  >  記事  >  WeChat アプレット  >  Taro + Vue3 を使用して小さなプログラムを開発するにはどうすればよいですか? (練習する)

Taro + Vue3 を使用して小さなプログラムを開発するにはどうすればよいですか? (練習する)

青灯夜游
青灯夜游転載
2022-01-13 10:28:216764ブラウズ

Taro3 Vue3 を使用して小さなプログラムを開発するにはどうすればよいですか?以下の記事では、Taro3 Vue3 を使って WeChat アプレットを開発する方法を紹介しますので、ご参考になれば幸いです。

Taro + Vue3 を使用して小さなプログラムを開発するにはどうすればよいですか? (練習する)

WeChat アプレットは、動作環境として WeChat を使用するアプリケーションです。その本質は、Hybrid テクノロジーのアプリケーションです。ハイブリッド アプリは混合モードです。モバイル アプリケーションなので、H5 に似ていますが、位置情報やカメラの呼び出しなど、H5 よりも多くのネイティブ機能を備えています。

小規模プログラムの開発方法は H5 と非常に似ており、JavaScriptHTMLCSS 言語も使用されます。

したがって、小規模なプログラム開発はフロントエンドエンジニアが身につけるべきスキルであると言えます。

ネイティブ ミニ プログラムの開発には一定の学習コストがかかります。現在、ミニ プログラムを開発するためのサードパーティ製のマルチターミナル フレームワークが市場に多数出回っています。究極のパフォーマンスと安定性を追求しない場合は、開発効率を考えると、ネイティブ ミニ プログラムは使用しないほうがよいでしょう。

サードパーティのマルチターミナル フレームワークの中で、tarouni-app が最も広く使用されています。一般的に、テクノロジを選択するとき、チームは # を使用します。 ##react、taro を使用する、チームは vue、および uni-app を使用するだけです。この 2 つに違いはなく、どちらも非常に使いやすいです。

しかし、多くの開発者は、taro3.0 以降で vue の使用がサポートされていることを知らないかもしれません。この記事では、Taro3 Vue3 を使用して WeChat アプレットを開発する方法を紹介します。

インターネットの情報をもとにこのプロジェクトの構築を完了した後、このプロジェクトを利用して小さなプログラムを開発しましたが、開発経験はこれまでに開発したすべてのプロジェクトを本当に上回っており、非常にスムーズでした(たぶん、vue3 のスクリプト設定を書くのはこれが初めてですが、とても使いやすいです)。

このプロジェクトの

github アドレス クローンに直接アクセスして使用できます。

ターゲット関数

    vue3を統合し、
  • スクリプトセットアップを使用します構文開発
  • 統合Typescript
  • コードインスペクションとフォーマットの最適化
  • グローバルな状態管理
  • ミニプログラムの下請け構成
  • ノッチスクリーンやその他のスタイルの問題と互換性のあるスタイルのカプセル化
  • httpメソッドカプセル化

主要なテクノロジー スタック

  • Taro3
  • Vue3
  • TypeScript
  • NutUi
  • Pinia

vue3 が最初にリリースされたとき、適切な UI フレームワークのサポートがなかったため、vue3 を学習する私の熱意は直接失墜しました。これまで、 quasarelement-plusant-design-vue などの優れたフレームワークが続々と vue3 をサポートしており、多くの vue3 プロジェクトが本番環境で使用されています。そのとき初めて、みんなが本当に vue3 を使っていることに気づきました。

たとえば、当社の隣のプロジェクト チームは再構築プロジェクトに vue3 を使用していましたが、そのときになって初めて、自分が vue3 の学習に少し遅れていることに気づきました (ヒント: フロントエンドは非常に複雑すぎます)

NutUI は、JD スタイルのモバイル コンポーネント ライブラリです。H5 およびミニ プログラム プラットフォームで使用できるアプリケーションを作成するための Vue 言語の使用をサポートし、開発者の開発効率と開発エクスペリエンスの向上を支援します。 。

NutUI については、Taro ドキュメント から知りました。Taro は、開発に NutUI を使用することを公式に推奨しています。彼らはすべて、JD.com の同じ開発チームのメンバーのようです。私は、次のような心構えでそれを使い始めました。試してみると、ユーザーエクスペリエンスは悪くありません。

Pinia は Vue の状態管理ライブラリであり、Vuex と同様、Vue の別の状態管理ソリューションであり、Vue2 と Vue3 をサポートしています。

私が初めてフロントエンドのステータス管理ツールに触れたのは、インターン時代に会社のバックエンド管理システムでした。dva を使用していました。それは拷問であり、ほとんど説得されました。やめる。だんだん慣れてきたのですが、reduxを使ってもvuexを使っても、書くのが面倒です。

这次尝试使用 Pinia,用起来确实很舒服,符合直觉,易于学习 ,有点类似于 recoil,但没有 recoil 那么多的概念和 API,主体非常精简,极易上手。Pinia 快速入门

vscode 需安装插件

  • Eslint
  • Prettier
  • Volar

vetur相同,volar是一个针对 vue 的 vscode 插件,不过与 vetur 不同的是,volar 提供了更为强大的功能。

Volar 介绍

搭建项目架构

初始化项目

初始化项目之前,需安装 taro,请参考 Taro 文档,完成 taro 安装

使用命令创建模板项目:

taro init myApp

Taro + Vue3 を使用して小さなプログラムを開発するにはどうすればよいですか? (練習する)

安装 cli 用来执行构建等操作,之后启动项目,会生成一个 dist 目录

yarn add @tarojs/cli
yarn dev:weapp

打开微信开发工具 工程目录需要指向构建出来的 dist 文件

Taro + Vue3 を使用して小さなプログラムを開発するにはどうすればよいですか? (練習する)

Taro + Vue3 を使用して小さなプログラムを開発するにはどうすればよいですか? (練習する)

Hello world 出现,项目成功跑起来了!

设置代码规范

  • 代码规范 ESlint
  • 代码格式化 Prettier
  • 提交前检查 husky

个人认为,eslint + prettier 足以应付大部分前端代码规范问题了,且配置起来很简单,有特殊需求也可继续配置。

安装依赖

yarn add @vue/eslint-config-prettier @vue/eslint-config-typescript eslint-plugin-prettier vue-tsc husky -D

设置代码规范和格式化规则

.eslintrc.js

module.exports = {
  root: true,

  env: {
    node: true,
    'vue/setup-compiler-macros': true
  },

  extends: ['plugin:vue/vue3-essential', 'eslint:recommended', '@vue/prettier', '@vue/typescript'],

  parserOptions: {
    parser: '@typescript-eslint/parser'
  },

  rules: {
    'prettier/prettier': [
      'error',
      {
        singleQuote: true,
        semi: false,
        trailingComma: 'none',
        arrowParens: 'avoid',
        printWidth: 100
      }
    ],
    'no-console': process.env.NODE_ENV === 'production' ? 'warn' : 'off',
    'no-debugger': process.env.NODE_ENV === 'production' ? 'warn' : 'off'
  }
}

.prettierrc

{
  "tabWidth": 2,
  "singleQuote": true,
  "semi": false,
  "trailingComma": "none",
  "arrowParens": "avoid",
  "endOfLine": "auto",
  "printWidth": 100
}

在 package.json 中 script 添加 Ts 检查命令和 Eslint 检查命令

"scripts":{
  "tsc": "vue-tsc --noEmit --skipLibCheck",
  "lint": "eslint --ext .vue --ext .js --ext .ts src/"
}

添加 husky 触发 Git 钩子,代码提交前检查

npx husky install

编辑 pre-commit 执行 Eslint 检查和 Ts 检查

#!/bin/sh
. "$(dirname "$0")/_/husky.sh"

echo "---eslint start---"
npm run lint
echo "---eslint end---"

echo "---ts lint start---"
npm run tsc
echo "---ts lint end---"

至此,项目的代码规范和格式规范配置完毕,多人协作也不是问题了。

引入 NutUI

yarn add @nutui/nutui-taro

在 .babelrc 或 babel.config.js 中添加配置:

module.exports = {
  // ...
  plugins: [
    [
      'import',
      {
        libraryName: '@nutui/nutui',
        libraryDirectory: 'dist/packages/_es',
        camel2DashComponentName: false
      },
      'nutui3-vue'
    ],
    [
      'import',
      {
        libraryName: '@nutui/nutui-taro',
        libraryDirectory: 'dist/packages/_es',
        camel2DashComponentName: false
      },
      'nutui3-taro'
    ]
  ]
}

按需引入,安装插件 babel-plugin-import

yarn add babel-plugin-import -D

样式处理 因为 nutui 的设计稿是 375 的 所以将框架的设计尺寸调整为 375

项目配置文件 config/index.js 中配置:

designWidth: 375

app.ts

import { createApp } from 'vue'
import { Button } from '@nutui/nutui-taro'

const app = createApp()

app.use(Button)

index.vue 中,nut-button 组件直接在 template 中写,不用再引入

<template>
  <view class="index">
    <text>{{ msg }}</text>
    <nut-button type="primary">主要按钮</nut-button>
  </view>
</template>

Taro + Vue3 を使用して小さなプログラムを開発するにはどうすればよいですか? (練習する)

说实话,配置起来还是有点麻烦,不过按照官网文档说明来配也没有踩坑,还行。

小程序分包配置

小程序主包超过 2M,就无法真机预览了,为了提前做好准备在一开始就进行分包处理。比如下面这个小程序的配置,分了四个包。

app.config.ts

pages: [&#39;pages/create/index&#39;, &#39;pages/find/index&#39;, &#39;pages/my/index&#39;],
subpackages: [
{
  root: &#39;pages/featureA&#39;,
  pages: [&#39;index/index&#39;]
},
{
  root: &#39;pagesSub/search&#39;,
  pages: [&#39;index&#39;]
},
{
  root: &#39;pagesSub/my&#39;,
  pages: [&#39;detail/index&#39;, &#39;about/index&#39;]
},
{
  root: &#39;pagesSub/book&#39;,
  pages: [&#39;detail/index&#39;, &#39;person/list/index&#39;, &#39;person/detail/index&#39;]
}
],

可以在小程序开发工具编辑器里的代码依赖分析,查看主包和分包的大小

Taro + Vue3 を使用して小さなプログラムを開発するにはどうすればよいですか? (練習する)

使用 script setup 语法封装小程序页面生命周期方法

hooks/life.ts

import { getCurrentInstance } from &#39;@tarojs/taro&#39;
import { onMounted } from &#39;vue&#39;

const Current = getCurrentInstance()

export function useDidShow(callback) {
    onMounted(callback) Current?.page?.onShow && (Current.page.onShow = callback)
}
export function usePullDownRefresh(callback) {
    Current?.page?.onPullDownRefresh && (Current.page.onPullDownRefresh = callback)
}

使用

import { useDidShow } from &#39;@/hooks/life&#39;

useDidShow(() => {
  // console.log(&#39;onShow&#39;)
})

安装 Pinia 进行状态管理

yarn add pinia
yarn add taro-plugin-pinia

项目配置文件 config/index.js 中配置:

plugins: [&#39;taro-plugin-pinia&#39;]

以管理用户信息和用户登录状态为例,实现一个用户登录功能

Taro + Vue3 を使用して小さなプログラムを開発するにはどうすればよいですか? (練習する)

需要处理的文件代码如下:

stores/auth.ts

import { defineStore } from &#39;pinia&#39;

interface UserInfoProp {
  nickName: string
  avatarUrl: string
}

const useAuth = defineStore({
  id: &#39;authInfo&#39;,
  state: () => ({
    userInfo: {
      nickName: &#39;&#39;,
      avatarUrl: &#39;&#39;
    },
    isLogin: false
  }),
  actions: {
    login() {
      this.isLogin = true
    },
    logout() {
      this.isLogin = false
    },
    setUserInfo(userInfo: UserInfoProp) {
      this.userInfo = userInfo
    }
  }
})
export { useAuth }

stores/index.ts

import { createPinia } from &#39;pinia&#39;
import { useAuth } from &#39;./auth&#39;

export const store = createPinia()

const storeObj = {
  auth: useAuth
}

// 封装成useStore的形式,这样一看引用就知道是store的数据
export function useStore(key: string) {
  return storeObj[key]()
}

个人中心 index.vue

<template>
  <main v-if="isLogin">
    <user-info />
  </main>
  <main v-else>
    <nut-button type="primary" @click="handleLogin">微信一键登录</nut-button>
  </main>
</template>

<script setup>
import Taro from &#39;@tarojs/taro&#39;
import { computed } from &#39;vue&#39;
import { useStore } from &#39;@/stores&#39;

import UserInfo from &#39;./userInfo.vue&#39;

const auth = useStore(&#39;auth&#39;)
const isLogin = computed(() => auth.isLogin)

const handleLogin = () => {
  setTimeout(() => {
    // 模拟后端请求得到token和userInfo
    Taro.setStorageSync(&#39;token&#39;, &#39;xxxx&#39;)
    auth.setUserInfo({
      nickName: &#39;林&#39;,
      avatarUrl:
        &#39;https://img12.360buyimg.com/imagetools/jfs/t1/143702/31/16654/116794/5fc6f541Edebf8a57/4138097748889987.png&#39;
    })
    auth.login()
  }, 500)
}
</script>

</script>

userInfo 组件

<template>
  <article>
    <nut-avatar size="large" :icon="userInfo.avatarUrl"></nut-avatar>
    <span class="ellipsis name">{{ userInfo.nickName }}</span>
  </article>
</template>

<script setup>
import Taro from &#39;@tarojs/taro&#39;
import { computed } from &#39;vue&#39;
import { useStore } from &#39;@/stores&#39;

const auth = useStore(&#39;auth&#39;)
const userInfo = computed(() => auth.userInfo)

</script>

总的来说, pinia 写起来是非常简洁的,这种类 react hooks 的写法,我是非常喜欢的

请求方法封装

http.ts

// 封装axios的请求,返回重新封装的数据格式
// 对错误的统一处理
import { HttpResponse } from &#39;@/common/interface&#39;
import Taro from &#39;@tarojs/taro&#39;
import publicConfig from &#39;@/config/index&#39;
import axios, {
  AxiosInstance,
  AxiosRequestConfig,
  AxiosResponse,
  Canceler
} from &#39;axios-miniprogram&#39;
import errorHandle from &#39;../common/errorHandle&#39;
const CancelToken = axios.CancelToken

class HttpRequest {
  private baseUrl: string
  private pending: Record<string, Canceler>

  constructor(baseUrl: string) {
    this.baseUrl = baseUrl
    this.pending = {}
  }

  // 获取axios配置
  getInsideConfig() {
    const config = {
      baseURL: this.baseUrl,
      headers: {
        &#39;Content-Type&#39;: &#39;application/json;charset=utf-8&#39;
      },
      timeout: 10000
    }
    return config
  }

  removePending(key: string, isRequest = false) {
    if (this.pending[key] && isRequest) {
      this.pending[key](&#39;取消重复请求&#39;)
    }
    delete this.pending[key]
  }

  // 设定拦截器
  interceptors(instance: AxiosInstance) {
    instance.interceptors.request.use(
      config => {
        console.log(&#39;config :>> &#39;, config)
        let isPublic = false
        publicConfig.publicPath.map(path => {
          isPublic = isPublic || path.test(config.url || &#39;&#39;)
        })
        const token = Taro.getStorageSync(&#39;token&#39;)
        if (!isPublic && token) {
          config.headers.Authorization = &#39;Bearer &#39; + token
        }
        const key = config.url + &#39;&&#39; + config.method
        this.removePending(key, true)
        config.cancelToken = new CancelToken(c => {
          this.pending[key] = c
        })
        return config
      },
      err => {
        errorHandle(err)
        return Promise.reject(err)
      }
    )

    // 响应请求的拦截器
    instance.interceptors.response.use(
      res => {
        const key = res.config.url + &#39;&&#39; + res.config.method
        this.removePending(key)
        if (res.status === 200) {
          return Promise.resolve(res.data)
        } else {
          return Promise.reject(res)
        }
      },
      err => {
        errorHandle(err)
        return Promise.reject(err)
      }
    )
  }

  // 创建实例
  request(options: AxiosRequestConfig) {
    const instance = axios.create()
    const newOptions = Object.assign(this.getInsideConfig(), options)
    this.interceptors(instance)
    return instance(newOptions)
  }

  get(url: string, config?: AxiosRequestConfig): Promise<AxiosResponse> | Promise<HttpResponse> {
    const options = Object.assign(
      {
        method: &#39;get&#39;,
        url: url
      },
      config
    )
    return this.request(options)
  }

  post(url: string, data?: unknown): Promise<AxiosResponse> | Promise<HttpResponse> {
    return this.request({
      method: &#39;post&#39;,
      url: url,
      data: data
    })
  }
}

export default HttpRequest

request.ts

import HttpRequest from &#39;./http&#39;
import config from &#39;@/config/index&#39;
const baseUrl = process.env.NODE_ENV === &#39;development&#39; ? config.baseUrl.dev : config.baseUrl.pro

const request = new HttpRequest(baseUrl)

export default request

以获取图书列表和图书详情为例

apis/book.ts

import request from &#39;../request&#39;

export function getBookList() {
  return request.get(&#39;books/getBookList&#39;)
}

export function getBookDetail(id: number) {
  return request.post(&#39;books/getBookDetail&#39;, {
    id
  })
}

请求方法封装还是用到了 axios,只是用的是 axios-miniprogram ,写法和 web 端基本一致,http.js 文件引用的一些模块太多,本文没有列出来,可以直接访问本项目 github 地址查看。

样式封装

iPhoneX 底部横线适配

assets/styles/common.scss

.safe-area-bottom {
  padding-bottom: constant(safe-area-inset-bottom);
  padding-bottom: env(safe-area-inset-bottom);
}

刘海儿屏适配

assets/styles/hairline.scss

@mixin hairline-common() {
  position: absolute;
  box-sizing: border-box;
  content: &#39; &#39;;
  pointer-events: none;
}

@mixin hairline() {
  @include hairline-common();
  top: -50%;
  right: -50%;
  bottom: -50%;
  left: -50%;
  border: 0 solid #eaeaea;
  transform: scale(0.5);
}

@mixin hairline-top($color, $left: 0, $right: 0) {
  @include hairline-common();
  top: 0;
  right: $right;
  left: $left;
  border-top: 1px solid $color;
  transform: scaleY(0.5);
}

@mixin hairline-bottom($color, $left: 0, $right: 0) {
  @include hairline-common();
  right: $right;
  bottom: 0;
  left: $left;
  border-bottom: 1px solid $color;
  transform: scaleY(0.5);
}

[class*=&#39;van-hairline&#39;] {
  &::after {
    @include hairline();
  }
}

.van-hairline {
  &,
  &--top,
  &--left,
  &--right,
  &--bottom,
  &--surround,
  &--top-bottom {
    position: relative;
  }

  &--top::after {
    border-top-width: 1px;
  }

  &--left::after {
    border-left-width: 1px;
  }

  &--right::after {
    border-right-width: 1px;
  }

  &--bottom::after {
    border-bottom-width: 1px;
  }

  &,
  &-unset {
    &--top-bottom::after {
      border-width: 1px 0;
    }
  }

  &--surround::after {
    border-width: 1px;
  }
}

多行文字省略

assets/styles/ellipsis.scss

@mixin multi-ellipsis($lines) {
  display: -webkit-box;
  overflow: hidden;
  text-overflow: ellipsis;
  -webkit-line-clamp: $lines;
  -webkit-box-orient: vertical;
}

@mixin ellipsis() {
  overflow: hidden;
  white-space: nowrap;
  text-overflow: ellipsis;
}

.ellipsis {
  @include ellipsis();
}

.multi-ellipsis--l2 {
  @include multi-ellipsis(2);
}

.multi-ellipsis--l3 {
  @include multi-ellipsis(3);
}

总结

至此,终于完成了 Taro + Vue3 的项目搭建,强烈建议直接访问项目 github 地址 clone 使用,有一些配置细节本文无法一一列举,就在项目中去发掘吧!

如果我的文章能帮助到你,那将是我的荣幸!

【相关学习推荐:小程序开发教程

以上がTaro + Vue3 を使用して小さなプログラムを開発するにはどうすればよいですか? (練習する)の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事はjuejin.cnで複製されています。侵害がある場合は、admin@php.cn までご連絡ください。