taro vue3 ts nut-ui 项目

# 使用 npm 安装 CLI
$ npm install -g @tarojs/cli

查看 Taro 全部版本信息

可以使用 npm info 查看 Taro 版本信息,在这里你可以看到当前最新版本

npm info @tarojs/cli

项目初始化

使用命令创建模板项目:

taro init 项目名

taro init myApp

微信小程序自定义 TabBar

先安装 cnpm install pinia 以便解决 小程序的 页面首次加载

在 app.config.js 中设置

export default defineAppConfig({
  pages: [
    'pages/myPage01/index',
    'pages/myPage02/index',
  ],
  window: {
    backgroundTextStyle: 'light',
    navigationBarBackgroundColor: '#fff',
    navigationBarTitleText: 'WeChat',
    navigationBarTextStyle: 'black'
  },
  tabBar: {
    custom: true,
    color: '#000000',
    selectedColor: '#000000',
    backgroundColor: '#000000',
    list: [
      {
        pagePath: 'pages/myPage01/index',
        text: '页面01',
      },
      {
        pagePath: 'pages/myPage02/index',
        text: '页面02',
      },
    ],
  }
})

src 目录下 pages 文件夹,在里面新建页面

src 目录 下添加 custom-tab-bar 文件夹,在里面书写底部导航栏组件

src 目录 下添加 store 文件夹,在里面写 index.js

src 目录下添加 assets 文件夹,在里面添加 pic 和 tabbarIcon

custom-tab-bar 的 index.js

<template>
    <view class="custom-tab-bar" style="display: flex; justify-content: space-around; align-items: center; padding: 10rpx 24rpx; background: #fff;">
        <view v-for="(item, index) in tabList" @click="handleClick(item, index)">
            <view style="width: 96rpx; height: 64rpx;">
                <img style="width: 100%; height: 100%;" :src=" current === index ? item.activeImg : item.img" alt="">
            </view>
            <view style="font-size: 24rpx; width: 100%; text-align: center;">{{ item.title }}</view>
        </view>
    </view>
</template>

<script setup>
import Taro from '@tarojs/taro'
import { useTabBarStore } from "../store/index";
import { ref, reactive, computed } from 'vue'

const tabBarStore = useTabBarStore();

const current = computed(() => tabBarStore.getSelected)

const tabList = reactive([
    {
        title: '首页',
        pagePath: '/pages/myPage01/index',
        img: require('../assets/tabbarIcon/myPage01.png'),
        activeImg: require('../assets/tabbarIcon/myPage01Active.png')
    },
    {
        title: '我的',
        pagePath: '/pages/myPage02/index',
        img: require('../assets/tabbarIcon/myPage02.png'),
        activeImg: require('../assets/tabbarIcon/myPage02Active.png')
    },
])
const handleClick = (item, index) => {
    tabBarStore.setSelected(index);
    Taro.switchTab({ url: item.pagePath })
}
</script>

<style lang="scss" scoped></style>

store 的 index.js

import { defineStore } from "pinia";

export const useTabBarStore = defineStore("tabBar", {
  state: () => {
    return { selected: 0 };
  },
  getters: {
    getSelected(state) {
      return state.selected;
    },
  },
  actions: {
    setSelected(value) {
      this.selected = value;
    },
  },
});

在 app.js 引入 pinia

import { createApp } from 'vue'
import './app.scss'
import { createPinia } from "pinia";

const App = createApp({
  onShow (options) {},
  // 入口组件不需要实现 render 方法,即使实现了也会被 taro 所覆盖
})

App.use(createPinia())

export default App

设置分享功能 在 app.js 写入

// app.js
import Taro from "@tarojs/taro";
// 分享的时候 wx.getStorageSync("sharePageUrl") 获取分享页面,在每个要分享的页面  进行设置缓存中的 sharePageUrl
/**
 * 全局分享配置,页面无需开启分享
 * 使用隐式页面函数进行页面分享配置
 * 使用隐式路由获取当前页面路由,并根据路由来进行全局分享、自定义分享
 */
!(function () {
  //获取页面配置并进行页面分享配置
  var PageTmp = Page;
  Page = function (pageConfig) {
    Taro.showShareMenu({
      withShareTicket: true,
    });

    //1. 获取当前页面路由
    let routerUrl = "";
    wx.onAppRoute(function (res) {
      //app.js中需要在隐式路由中才能用getCurrentPages()获取到页面路由
      let pages = getCurrentPages(),
        view = pages[pages.length - 1];
      if (view) {
        routerUrl = view.route;
      }
    });

    //2. 全局开启分享配置
    pageConfig = Object.assign(
      {
        onShareAppMessage: function () {
          //根据不同路由设置不同分享内容(微信小程序分享自带参数,如非特例,不需配置分享路径)
          let shareInfo = {};
          let noGlobalSharePages = ["index/index"];
          //全局分享配置,如部分页面需要页面默认分享或自定义分享可以单独判断处理
          if (!routerUrl.includes(noGlobalSharePages)) {
            shareInfo = {
              title: "小鑫向上",
              imageUrl: wx.getStorageSync("shareUrl"),
            };
          }
          return shareInfo;
        },
        onShareTimeline: function (res) {
          console.log(res)
          console.log(routerUrl)
          let shareData = {
            title: "小鑫向上",
            path: wx.getStorageSync("sharePageUrl"), // 分享的路径
            // imageUrl: '',  // 分享的图片链接
          };
          return shareData;
        },
      },
      pageConfig
    );
    // 配置页面模板
    PageTmp(pageConfig);
  };
})();

封装API接口

在 src 下 新建 api 文件夹 下 继续创建 文件

baseUrl.js

const getBaseUrl = (url) => {
  let BASE_URL = "";
  if (process.env.NODE_ENV === "development") {
    // 开发环境 - 根据请求不同返回不同的BASE_URL
    // BASE_URL = "http://pig-gateway:9999";
    // BASE_URL = "http://127.0.0.1:3000"
    BASE_URL = "http://123.207.67.156:8889";
  } else {
    // 生产环境
    // BASE_URL = "http://127.0.0.1:3000"
    BASE_URL = "http://123.207.67.156:8889";
  }
  return BASE_URL;
};

export default getBaseUrl;

http.js

import Taro from "@tarojs/taro";
import getBaseUrl from "./baseUrl";
import interceptors from "./interceptors";

interceptors.forEach((interceptorItem) => Taro.addInterceptor(interceptorItem));

class httpRequest {
  baseOptions(params, method = "GET") {
    let { url, data } = params;
    const BASE_URL = getBaseUrl(url);
    let contentType = "application/json";
    contentType = params.contentType || contentType;
    let responseType = "";
    responseType = params.responseType || responseType;
    const option = {
      url: BASE_URL + url,
      data: data,
      method: method,
      header: {
        "content-type": contentType,
        Authorization: "Bearer " + Taro.getStorageSync("accessToken"),
      },
      responseType: responseType,
    };
    return Taro.request(option);
  }

  get(url, data = "", responseType) {
    let option = { url, data, responseType };
    return this.baseOptions(option);
  }

  post(url, data, contentType) {
    let params = { url, data, contentType };
    return this.baseOptions(params, "POST");
  }

  put(url, data = "") {
    let option = { url, data };
    return this.baseOptions(option, "PUT");
  }

  delete(url, data = "") {
    let option = { url, data };
    return this.baseOptions(option, "DELETE");
  }
}

export default new httpRequest();

interceptors.js

import Taro from "@tarojs/taro";

const HTTP_STATUS = {
  SUCCESS: 200,
  CREATED: 201,
  ACCEPTED: 202,
  CLIENT_ERROR: 400,
  AUTHENTICATE: 401,
  FORBIDDEN: 403,
  NOT_FOUND: 404,
  SERVER_ERROR: 500,
  BAD_GATEWAY: 502,
  SERVICE_UNAVAILABLE: 503,
  GATEWAY_TIMEOUT: 504,
  Failed_Dependency: 424,
};

const customInterceptor = (chain) => {
  const requestParams = chain.requestParams;
  return chain
    .proceed(requestParams)
    .then((res) => {
      // 只要请求成功,不管返回什么状态码,都走这个回调
      if (res.statusCode === HTTP_STATUS.NOT_FOUND) {
        return Promise.reject("请求资源不存在");
      } else if (
        res.statusCode === HTTP_STATUS.SERVER_ERROR ||
        res.statusCode === HTTP_STATUS.SERVICE_UNAVAILABLE
      ) {
        return Promise.reject("服务端错误");
      } else if (res.statusCode === HTTP_STATUS.GATEWAY_TIMEOUT) {
        return Promise.reject("请求超时");
      } else if (res.statusCode === HTTP_STATUS.BAD_GATEWAY) {
        return Promise.reject("网关错误");
      } else if (res.statusCode === HTTP_STATUS.FORBIDDEN) {
        return Promise.reject("没有权限访问");
      } else if (res.statusCode === HTTP_STATUS.CLIENT_ERROR) {
        return Promise.reject("请求错误");
      } else if (res.statusCode === HTTP_STATUS.AUTHENTICATE) {
        Taro.reLaunch({
          url: "/pages/login_package/login/index",
        });
        return Promise.reject("需要鉴权");
      } else if (res.statusCode === HTTP_STATUS.Failed_Dependency) {
        Taro.reLaunch({
          url: "/pages/login_package/login/index",
        });
        return Promise.reject("请求令牌已过期");
      } else if (res.statusCode === HTTP_STATUS.SUCCESS) {
        return res.data;
      }
    })
    .catch((err) => {
      Taro.showToast({
        icon:'error',
        title:err
      })
    });
};

// Taro 提供了两个内置拦截器
// logInterceptor - 用于打印请求的相关信息
// timeoutInterceptor - 在请求超时时抛出错误。
const interceptors = [customInterceptor];

export default interceptors;

servers.js

import HTTPREQUEST from "./http";
// import Taro from "@tarojs/taro";

// export const refreshToken = (postData) => {
//   return HTTPREQUEST.get("/dcms/app-api/sso/refreshToken", postData);
// };

// export const logout = () => {
//   return HTTPREQUEST.post("/dcms/app-api/sso/logout");
// };

// 查看商品分类
export const getGoodClass = (postData) => {
  // return HTTPREQUEST.get("/api/getGoodClass", postData);
  return HTTPREQUEST.get("/getGoodClass", postData);
};

// 查看商品详情
export const getGoodDetail = (postData) => {
  // return HTTPREQUEST.get("/api/getGoodDetail", postData);
  return HTTPREQUEST.get("/getGoodDetail", postData);
};

// 查看商品详情
export const useIdGetGoodDetail = (postData) => {
  // return HTTPREQUEST.get("/api/useIdGetGoodDetail", postData);
  return HTTPREQUEST.get("/useIdGetGoodDetail", postData);
};
相关推荐
2401_8827275737 分钟前
低代码配置式组态软件-BY组态
前端·后端·物联网·低代码·前端框架
NoneCoder40 分钟前
CSS系列(36)-- Containment详解
前端·css
anyup_前端梦工厂1 小时前
初始 ShellJS:一个 Node.js 命令行工具集合
前端·javascript·node.js
5hand1 小时前
Element-ui的使用教程 基于HBuilder X
前端·javascript·vue.js·elementui
GDAL1 小时前
vue3入门教程:ref能否完全替代reactive?
前端·javascript·vue.js
六卿1 小时前
react防止页面崩溃
前端·react.js·前端框架
z千鑫2 小时前
【前端】详解前端三大主流框架:React、Vue与Angular的比较与选择
前端·vue.js·react.js
m0_748256142 小时前
前端 MYTED单篇TED词汇学习功能优化
前端·学习
小马哥编程3 小时前
Function.prototype和Object.prototype 的区别
javascript
小白学前端6663 小时前
React Router 深入指南:从入门到进阶
前端·react.js·react