JD-H5开发

目录

写配置

写界面


写配置

创建vue项目

npm init vite@latest beimao-h5 -- --template vue-ts

 我们使用的是-h5

npm i @nutui/nutui

在src里面的main文件中

import { createApp } from 'vue'

import './style.css'

import App from './App.vue'

// 注意:这种方式将会导入所有组件

import NutUI from "@nutui/nutui";

// 采用按需加载时  此全局css样式,需要删除

import "@nutui/nutui/dist/style.css";

createApp(App).use(NutUI).mount("#app");

插件在package.json

{
  "name": "beimao-h5",
  "private": true,
  "version": "0.0.0",
  "type": "module",
  "scripts": {
    "dev": "vite",
    "build": "vue-tsc --noEmit && vite build",
    "preview": "vite preview"
  },
  "dependencies": {
    "@nutui/nutui": "^3.1.22",
    "axios": "^0.27.2",
    "dayjs": "^1.11.3",
    "path": "^0.12.7",
    "pinia": "^2.0.14",
    "pinia-plugin-persist": "^1.0.0",
    "ts-md5": "^1.2.11",
    "vue": "^3.2.37",
    "vue-router": "^4.0.16"
  },
  "devDependencies": {
    "@vitejs/plugin-vue": "^3.0.0",
    "typescript": "^4.6.4",
    "vite": "^3.0.0",
    "vue-tsc": "^0.38.4"
  }
}

 加入后进行安装

 npm install

在src的main.ts里面进行加入东西


import { createApp } from 'vue'

import App from './App.vue'
//导入我们的路由文件
import Router from  './router/index'
//导入store
import store from './store/index'
// 注意:这种方式将会导入所有组件
import NutUI from "@nutui/nutui";
// 采用按需加载时  此全局css样式,需要删除
import "@nutui/nutui/dist/style.css";
const app = createApp(App)
//使用京东 NutUI
.use(NutUI)
//实用路由
app.use(Router)
//使用store
app.use(store);
app.mount('#app')

根据里面的内容,加入相应的文件夹以及ts文件

加入router文件夹,在里面创建index.ts文件,这里面是路由

import { createRouter, createWebHashHistory } from "vue-router";

const routes = [
    {
        path: '/',
        name: "home",
        component: () => import("@/views/Index.vue"),
       
    },
    {
        path: '/category',
        name: "category",
        component: () => import("@/views/Category.vue"),
       
    },
]

const router = createRouter({
    history: createWebHashHistory('/'),
    routes
})

export default router

 建立store文件夹,在里面创建index.ts文件以及appStore.ts文件

index.ts文件

import { createPinia } from 'pinia'
import piniaPluginPersist from 'pinia-plugin-persist'

const store = createPinia()
store.use(piniaPluginPersist)

export default store

appStore.ts文件

import { defineStore } from 'pinia'

const appStore = defineStore({
  id: 'app',
  state: () => {
    return {
      user: { id: 0, userId: "" },
      token: "",
    }
  },
  getters: {

  },
  actions: {

  },
  // 开启数据缓存
  persist: {
    enabled: true,
    strategies: [
      {
        key: 'com.beiyou.h5',
        storage: localStorage,
      }
    ]
  }
})

export default appStore;

建立views文件夹,里面建立Index.vue

Index.vue

<template>
  <div>你好苍老师</div>
</template>

在在外层的vite.config.ts文件中进行配置文件

import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import path from "path";
// https://vitejs.dev/config/
export default defineConfig({
  plugins: [vue()],
  server: {

    port: 4000, // 你需要定义的端口号

    proxy: {
      "/api": {
        target: "http://localhost:8080/",
        changeOrigin: true,
      },

    },
  },
  resolve: {
    // 配置路径别名
    alias: {
      '@': path.resolve(__dirname, './src'),
    }
  },
})

当path爆红的时候,安装path

        npm install path

删除components里面的文件

在src文件夹下面的App文件里面修改内容

<template>
  <div>
    home
  </div>
</template>
<script setup lang="ts">

</script>

建立http文件夹管理页面拦截

        建立index.ts

import axios, {
    AxiosRequestConfig,
    AxiosRequestHeaders,
    AxiosResponse,
  } from "axios";

  import { storeToRefs } from "pinia";
  import appStore from "@/store/appStore";
  let { token } = storeToRefs(appStore());
  
  const state = {
    ok: 0,//请求成功状态码
    401: "ERR_BAD_REQUEST"
  };
  
  //返回数据规则
  interface IResponseData<T> {
    status: number;
    message?: string;
    data: T;
    code: string;
  }
  
  //请求默认配置规则
  type TOption = {
    baseURL: string;
    timeout: number;
  };
  
  //默认配置
  const config = {
    baseURL: "",
    timeout: 30 * 1000,
    withCredentials: true,
  };
  
  
  let loading: any = null;
  
  class Http {
    service: any;
    constructor(config: TOption) {
      //实例化请求配置
      this.service = axios.create(config);
  
      //请求拦截
      this.service.interceptors.request.use(
        (config: AxiosRequestConfig) => {
         // loading = ElLoading.service({ fullscreen: true, text: '加载中...' });
   
          if (token.value) {
            (config.headers as AxiosRequestHeaders).Authorization = token.value;
          }
          return config;
        },
        (error: any) => {
          loading.close();
          return Promise.reject(error);
        }
      );
  
      //响应拦截
      this.service.interceptors.response.use(
        (response: AxiosResponse) => {
         // loading.close();
  
     
          const data = response.data;
  
          const { code } = data;
  
          if (code == undefined) {
            //如果没有返回状态码,直接返回数据,针对于返回数据为blob类型    
            return response;
          } else if (code !== 0) {
            //ElMessage.error(data.message);
            return Promise.reject(data);
          }
          // code == 0 的时候,提取我们只关注的Api数据data
          // console.log(response);
          return response.data.data;
        },
        (error: any) => {
          loading.close();
          if (error.code === state[401]) {
           // ElMessage.error("请求失败:" + error.message);
            setTimeout(() => {
              localStorage.removeItem('com.beiyou.h5')
              window.location.href = '/#/login'
            }, 1000);
          }
          return Promise.reject(error);
        }
      );
    }
  
    get<T>(url: string, params?: object, data = {}): Promise<IResponseData<T>> {
      return this.service.get(url, { params, ...data });
    }
  
    post<T>(url: string, params?: object, data = {}): Promise<IResponseData<T>> {
      return this.service.post(url, params, data);
    }
  
    put<T>(url: string, params?: object, data = {}): Promise<IResponseData<T>> {
      return this.service.put(url, params, data);
    }
  
    delete<T>(
      url: string,
      params?: object,
      data = {}
    ): Promise<IResponseData<T>> {
      return this.service.delete(url, { params, ...data });
    }
  }
  
  export default new Http(config);
  

 

有些配置爆红在tsconfig.json里面加入

  "baseUrl": ".",

    "paths": {

      "@/*": [

        "src/*"

      ]

    }

加入后的整体样子 

{
  "compilerOptions": {
    "target": "ESNext",
    "useDefineForClassFields": true,
    "module": "ESNext",
    "moduleResolution": "Node",
    "strict": true,
    "jsx": "preserve",
    "sourceMap": true,
    "resolveJsonModule": true,
    "isolatedModules": true,
    "esModuleInterop": true,
    "lib": [
      "ESNext",
      "DOM"
    ],
    "skipLibCheck": true,
    "baseUrl": ".",
    "paths": {
      "@/*": [
        "src/*"
      ]
    }
  },
  "include": [
    "src/**/*.ts",
    "src/**/*.d.ts",
    "src/**/*.tsx",
    "src/**/*.vue"
  ],
  "references": [
    {
      "path": "./tsconfig.node.json"
    }
  ]
}

 上面就是配置好的全部文件以及文件里面的构成 

 这里为止我们该有的配置已经配置完毕,接下来就是写界面

写界面

在src的App.vue里面写入

<template>

 <router-view></router-view>
  <nut-tabbar @tab-switch="tabSwitch" :bottom="true">
    <nut-tabbar-item tab-title="首页" icon="home"></nut-tabbar-item>
    <nut-tabbar-item tab-title="分类" icon="category"></nut-tabbar-item>
    <nut-tabbar-item tab-title="发现" icon="find"></nut-tabbar-item>
    <nut-tabbar-item tab-title="购物车" icon="cart"></nut-tabbar-item>
    <nut-tabbar-item tab-title="我的" icon="my"></nut-tabbar-item>
  </nut-tabbar>
</template>

<script setup lang="ts">
import { useRoute, useRouter } from "vue-router";
const route = useRoute();
const router = useRouter();
const tabSwitch = (item: any, index: any) => {
  console.log(item, index);
  if (index === 1) {
    router.push({ name: "category" });
  }
   if (index === 0) {
    router.push({ name: "home" });
  }
};
</script>

 <template>

 <router-view></router-view>

  <nut-tabbar @tab-switch="tabSwitch" :bottom="true">

    <nut-tabbar-item tab-title="首页" icon="home"></nut-tabbar-item>

    <nut-tabbar-item tab-title="分类" icon="category"></nut-tabbar-item>

    <nut-tabbar-item tab-title="发现" icon="find"></nut-tabbar-item>

    <nut-tabbar-item tab-title="购物车" icon="cart"></nut-tabbar-item>

    <nut-tabbar-item tab-title="我的" icon="my"></nut-tabbar-item>

  </nut-tabbar>

</template>

<script setup lang="ts">

import { useRoute, useRouter } from "vue-router";

const route = useRoute();

const router = useRouter();

const tabSwitch = (item: any, index: any) => {

  console.log(item, index);

  if (index === 1) {

    router.push({ name: "category" });

  }

   if (index === 0) {

    router.push({ name: "home" });

  }

};

</script>

解析:

         <router-view></router-view>:支持页面跳转

        :bottom="true":让下面的首页等在底部

这里就要在路由里面加入一个分支,是category的路由分支

   {
        path: '/category',
        name: "category",
        component: () => import("@/views/Category.vue"),
       
    },

 在views里面创建Category.vue文件写入

<template>这是分类页</template>

开始正式写vue

        在主页面加入一个滚动的公告栏 

 <nut-noticebar text="华为畅享9新品即将上市" :scrollable="true" :background="`rgba(251, 248, 220, 1)`" :color="`#D9500B`"></nut-noticebar>

        在公告栏下面加入一个轮播图

 <nut-swiper :init-page="page" :pagination-visible="true" pagination-color="#426543" auto-play="3000">
     <nut-swiper-item v-for="item in list" :key="item">
        <img :src="item" alt="" />
      </nut-swiper-item>
  </nut-swiper>

轮播图的script

 import { reactive, toRefs, onMounted } from 'vue';
  export default {
    setup() {
      const state = reactive({
        page: 2,
        list: [
          'https://storage.360buyimg.com/jdc-article/NutUItaro34.jpg',
          'https://storage.360buyimg.com/jdc-article/NutUItaro2.jpg',
          'https://storage.360buyimg.com/jdc-article/welcomenutui.jpg',
          'https://storage.360buyimg.com/jdc-article/fristfabu.jpg'
        ]
      });
      onMounted(() => {
        setTimeout(() => {
          state.list.splice(1, 1);
        }, 3000);
      });
      return { ...toRefs(state) };
    }
  };

轮播图的样式

<style lang="scss" scoped>
  .nut-swiper-item {
    line-height: 150px;
    img {
      width: 100%;
      height: 100%;
    }
  }
</style>

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值