09-小程序原生能力

6 阅读1分钟

📱 Taro+Vue3 入门(九):小程序原生能力调用

系列导读:小程序不只是网页,还可以调用登录、扫码、定位、支付等原生能力。 Taro 统一封装了各平台 API,Vue3 中调用方式完全一致。


🔐 1. 微信登录

<script setup lang="ts">
import Taro from '@tarojs/taro'
import { useAuthStore } from '@/stores/auth'
import { authApi } from '@/api/auth'

const authStore = useAuthStore()

async function handleWechatLogin() {
  try {
    const { code } = await Taro.login()
    const { token, user } = await authApi.loginByWechat(code)
    authStore.setAuth(token, user)
    Taro.switchTab({ url: '/pages/index/index' })
  } catch (e) {
    Taro.showToast({ title: '登录失败', icon: 'none' })
  }
}
</script>

<template>
  <view class="login-page">
    <image src="/assets/logo.png" class="logo" />
    <text class="title">欢迎使用好物商城</text>
    <nut-button type="primary" block @click="handleWechatLogin">
      微信一键登录
    </nut-button>
  </view>
</template>

📸 2. 图片选择与上传

<script setup lang="ts">
import { ref } from 'vue'
import Taro from '@tarojs/taro'

const images = ref<string[]>([])

async function chooseImage() {
  const res = await Taro.chooseImage({
    count: 9 - images.value.length,
    sizeType: ['compressed'],
    sourceType: ['album', 'camera'],
  })

  // 上传
  for (const filePath of res.tempFilePaths) {
    const uploadRes = await Taro.uploadFile({
      url: 'https://api.example.com/upload',
      filePath,
      name: 'file',
    })
    const { url } = JSON.parse(uploadRes.data)
    images.value.push(url)
  }
}

function removeImage(index: number) {
  images.value.splice(index, 1)
}
</script>

<template>
  <view class="image-picker">
    <view v-for="(img, i) in images" :key="i" class="image-item">
      <image :src="img" mode="aspectFill" />
      <view class="delete-btn" @tap="removeImage(i)">×</view>
    </view>
    <view v-if="images.length < 9" class="add-btn" @tap="chooseImage">
      <text>+</text>
    </view>
  </view>
</template>

📍 3. 定位

<script setup lang="ts">
import { ref } from 'vue'
import Taro from '@tarojs/taro'

const address = ref('')

async function getLocation() {
  try {
    const setting = await Taro.getSetting()
    if (!setting.authSetting['scope.userLocation']) {
      await Taro.authorize({ scope: 'scope.userLocation' })
    }

    const location = await Taro.getLocation({ type: 'gcj02' })
    console.log(location.latitude, location.longitude)
  } catch {
    Taro.showModal({
      title: '提示',
      content: '需要位置权限',
      success: (res) => { if (res.confirm) Taro.openSetting() },
    })
  }
}

async function chooseAddress() {
  const res = await Taro.chooseLocation({})
  address.value = res.address
}
</script>

<template>
  <nut-cell title="位置" :desc="address || '未选择'" is-link @click="chooseAddress" />
</template>

📋 4. 存储封装

// src/utils/storage.ts
import Taro from '@tarojs/taro'

export const storage = {
  set(key: string, value: any) {
    Taro.setStorageSync(key, JSON.stringify(value))
  },
  get<T>(key: string, defaultVal?: T): T | undefined {
    try {
      const raw = Taro.getStorageSync(key)
      return raw ? JSON.parse(raw) : defaultVal
    } catch { return defaultVal }
  },
  remove(key: string) { Taro.removeStorageSync(key) },
  clear() { Taro.clearStorageSync() },
}

📤 5. 分享

<script setup lang="ts">
import { useShareAppMessage, useShareTimeline } from '@tarojs/taro'

useShareAppMessage(() => ({
  title: '发现好物,推荐给你!',
  path: `/pages/detail/index?id=${productId.value}`,
  imageUrl: product.value?.image,
}))

useShareTimeline(() => ({
  title: product.value?.name || '',
  query: `id=${productId.value}`,
}))
</script>

<template>
  <button open-type="share">分享给好友</button>
</template>

✅ 本篇小结 Checklist

  • 掌握微信登录流程
  • 会实现图片选择和上传
  • 调用定位和地址选择
  • 实现分享功能

本文是「Taro+Vue3 入门」系列第 9 篇,共 10 篇。