当前位置:网站首页>JD-H5开发
JD-H5开发
2022-07-22 03:10:00 【懒起来】
目录
写配置
创建vue项目
npm init [email protected] 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>
边栏推荐
- Sliding window frame
- 小乌龟上传远程仓库
- Check for degenerate boxes检查退化框
- Ouu probiotics intensive cultivation of gastrointestinal health, award-winning tmall international Micro Ecological Innovation Conference
- Joyous Torch Festival of the Yi Nationality
- Basic concept of Nacos and single machine startup
- ES6——模块
- 深度卷积和普通卷积的对比
- 10个自动化测试框架,测试工程师用起来
- “码”上赢门票——TDengine开发者大会购票福利第二弹
猜你喜欢
2面字节,被面试官抬着走出去,分享给大家
记一次jmeter压测实战总结
EACCES: permission denied, unlink ‘/usr/local/bin/code‘
“码”上赢门票——TDengine开发者大会购票福利第二弹
How to improve the efficiency of test case review?
Monte Carlo tree search (MCTS) explanation
零基础学习CANoe Panel(2)—— 控件布局
MySQL workbench tutorial
Chapter 3 - creating and maintaining MySQL data tables
C语言动态分配内存
随机推荐
C语言动态分配内存
[fiddlertx plug-in] use Fiddler to capture Tencent classroom video download
Cloud native ide: the first general and powerful codeless development platform of IVX
img.shape[-2:]/len(img.shape[-2:]):GeneralizedRCNN:original_image_sizes中的 torch._assert
rsync下行同步+inotify实时同步部署
深度学习之 8 深度模型优化与正则化
ctfshow MengXIn 下
Liunx环境
卷妹的面试小抄每日更新Day1
golang语言cli库
Detailed teaching of address book in C language
Cookies and sessions
Upload pictures to the IIS server of this machine, and the results are returned in the form of web address, which can be accessed directly
Statistics, calculate the data ratio of each department in SQL
EACCES: permission denied, unlink ‘/usr/local/bin/code‘
【FiddlerTX插件】使用Fiddler抓包腾讯课堂视频下载
C语言力扣第38题之外观数列。三种方法(遍历法、递归法与狼灭法)
单片机外围器件学习攻略,小bai必看
C语言编写九九乘法表,实现不同三角形形状表格输出
C language question bank part.1