IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> JavaScript知识库 -> vue3的那些事 -> 正文阅读

[JavaScript知识库]vue3的那些事

没有特别的幸运,那么就特别的努力!!!

vue3 + vite + ts + vant + axios + sass

vite官网:

搭建第一个 Vite 项目 (vite + vue + ts)

兼容性注意
Vite 需要 Node.js 版本 14.18+,16+。然而,有些模板需要依赖更高的 Node 版本才能正常运行,当你的包管理器发出警告时,请注意升级你的 Node 版本。

// 搭建第一个 Vite 项目 (vite + vue + ts)

// npm (本篇采用npm搭建)
npm init vite@latest 

// yarn
yarn create vite

// pnpm
pnpm create vite
# npm 6.x
npm create vite@latest vite-vue3 --template vue

# npm 7+, extra double-dash is needed:
npm create vite@latest vite-vue3 -- --template vue

# yarn
yarn create vite vite-vue3 --template vue

# pnpm
pnpm create vite vite-vue3 --template vue

项目启动


cd vite-vue3

npm install
npm run dev

代码规范 (格式化、提示)

eslint

# 自动生成配置文件并安装下面四个依赖
npx eslint --init

# 或者手动创建文件
# npm i eslint @typescript-eslint/parser @typescript-eslint/eslint-plugin eslint-plugin-vue -D

prettier

npm i prettier eslint-config-prettier eslint-plugin-prettier -D

创建prettier文件

// prettier.cjs

module.exports = {
  printWidth: 100,
  tabWidth: 2,
  useTabs: false, // 是否使用tab进行缩进,默认为false
  singleQuote: true, // 是否使用单引号代替双引号,默认为false
  semi: true, // 行尾是否使用分号,默认为true
  arrowParens: 'always',
  endOfLine: 'auto',
  vueIndentScriptAndStyle: true,
  htmlWhitespaceSensitivity: 'strict',
};

配置eslintrc

// eslintrc.cjs

module.exports = {
  root: true, // 停止向上查找父级目录中的配置文件
  env: {
    browser: true,
    es2021: true,
    node: true,
  },
  extends: [
    'eslint:recommended',
    'plugin:vue/vue3-essential',
    'plugin:@typescript-eslint/recommended',
    'plugin:prettier/recommended',
    'prettier', // eslint-config-prettier 的缩写
  ],
  parser: 'vue-eslint-parser', // 指定要使用的解析器
  // 给解析器传入一些其他的配置参数
  parserOptions: {
    ecmaVersion: 'latest', // 支持的es版本
    parser: '@typescript-eslint/parser',
    sourceType: 'module', // 模块类型,默认为script,我们设置为module
  },
  plugins: ['vue', '@typescript-eslint', 'prettier'], // eslint-plugin- 可以省略
  rules: {
    'vue/multi-word-component-names': 'off',
    '@typescript-eslint/no-var-requires': 'off',
  },
};

配置 tsconfig

// tsconfig.json

{
  "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,
    // 👆是初始化默认配置
    /*
      在ts中导入js模块会报错找不到类型声明
      解决方法一:
        仅设置 "allowJs": true 即可
        注:allowJs设置true时,下方include不可以加入'src/**\/*.js',否则报错'无法写入文件xx因为它会覆盖输入文件'
      方法二:
        仅在 env.d.ts 中加入 declare module '*.js'; 模块定义即可

      总结:和 "include": ["src/**\/*.js"] 没有任何关系
    */
    "allowJs": true, // 允许编译器编译JS,JSX文件
    "baseUrl": "./",
    // "typeRoots": [
    //   "node_modules/@types" // 默认会从'node_modules/@types'路径去引入声明文件
    // ],
    // "types": ["node"] // 仅引入'node'模块
    // "paths"是相对于"baseUrl"进行解析
    // 在vite.config里配置了路径别名resolve.alias,为了让编译 ts 时也能够解析对应的路径,我们还需要配置 paths 选项
    "paths": {
      "@/*": ["src/*"],
    }
  },
  "include": ["src/**/*.ts", "src/**/*.d.ts", "src/**/*.tsx", "src/**/*.vue"],
  // references属性是 TypeScript 3.0 的新特性,允许将 TypeScript 程序拆分结构化(即拆成多个文件,分别配置不同的部分)。
  "references": [{ "path": "./tsconfig.node.json" }]
}

tsconfig.node.json

{
  "compilerOptions": {
    "composite": true,
    "module": "ESNext",
    "moduleResolution": "Node",
    "allowSyntheticDefaultImports": true
  },
  "include": ["vite.config.ts", "config/index.ts"]
}

CSS 预处理器

less安装使用

// npm 安装
npm install less
npm install less-loader

// yarn 安装
yarn add less less-loader
// 使用
< style lang="less" scoped></ style>

sass安装使用

// npm 安装
npm install -D sass sass-loader

// yarn 安装
yarn add sass sass-loader
<style lang="scss" scoped>
.home {
  background-color: #eee;
  height: 100vh;
}
</style>

vant 安装

vant3官网地址:
安装

// npm 安装
npm i vant

// yarn 安装
yarn add vant

// 通过 pnpm 安装
pnpm add vant

常规用法

import { createApp } from 'vue'
import './style.css'
// 1. 引入你需要的组件
import { Button } from 'vant';
// 2. 引入组件样式
import 'vant/lib/index.css';
import App from './App.vue'

const app = createApp(App)

// 3. 注册你需要的组件
app.use(Button);

app.mount('#app');

按需引入组件样式

// 通过 npm 安装
npm i unplugin-vue-components -D

// 通过 yarn 安装
yarn add unplugin-vue-components -D

// 通过 pnpm 安装
pnpm add unplugin-vue-components -D

配置插件
vite 的项目,在 vite.config.js 文件中配置插件:

import vue from '@vitejs/plugin-vue';
import Components from 'unplugin-vue-components/vite';
import { VantResolver } from 'unplugin-vue-components/resolvers';

export default {
  plugins: [
    vue(),
    Components({
      resolvers: [VantResolver()],
    }),
  ],
};

使用组件

<template>
  <van-button type="primary" />
</template>

Rem 布局适配

// npm 安装
npm install -D postcss-pxtorem lib-flexible

// yarn 安装
yarn add postcss-pxtorem lib-flexible

根目录下面新建一个 postcss.config.js 文件

// postcss.config.js
module.exports = {
  plugins: {
    'postcss-pxtorem': {
      rootValue: 37.5,
      propList: ['*'],
    },
  },
};

底部适配 - 对于ios系统

<!-- 在 head 标签中添加 meta 标签,并设置 viewport-fit=cover 值 -->
<meta
  name="viewport"
  content="width=device-width, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0, viewport-fit=cover"
/>

<!-- 开启顶部安全区适配 -->
<van-nav-bar safe-area-inset-top />

<!-- 开启底部安全区适配 -->
<van-number-keyboard safe-area-inset-bottom />

vue-router

1.安装

npm i vue-router@4

2.创建路由

// src/router/index.ts

//现在创建router的方式与vue2.x的版本已经很不同了
import { createRouter, createWebHashHistory } from "vue-router";
import { routes } from "./routes";

const router = createRouter({
  history: createWebHashHistory(), //替代之前的mode,是必须的
  routes,
});

router.beforeEach((to, from, next) => {
  document.title = to.meta.title as string || '浙里普法'
  next()
})
export default router;

// src/router/routes.ts

import { RouteRecordRaw } from "vue-router";
export const routes: Array<RouteRecordRaw> = [
  {
    path: "/",
    redirect: "/index",
  },
  {
    path: "/index",
    name: "Index",
    component: () => import("../view/index.vue"),
    meta: {
      nav: true,
      title: '首页'
    }
  },

];

3.挂载路由

// src/main.ts
import { createApp } from 'vue';
import App from './App.vue';
import router from './router/index'; //引入vue-router

const app = createApp(App);

app.use(router); // 挂载到app上
app.mount('#app');

4.使用

<template>
  <router-view />
</template>

Axios

1.安装

// npm 安装
npm i axios

// yarn 安装
yarn add axios
// src/utils/http/axios.ts

import axios, { AxiosResponse, AxiosRequestConfig, AxiosError } from 'axios';
import type { Response } from './types';
// import { auth } from '@/utils';
import { Toast } from 'vant';
import router from '../../router';

axios.defaults.baseURL = '/api';
axios.defaults.timeout = 1000 * 60;
axios.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded;charset=UTF-8';

// 创建axios实例
const service = axios.create({
  // 根据不同env设置不同的baseURL
  baseURL: import.meta.env.VITE_APP_API_BASE_URL,
});

// axios实例拦截请求
service.interceptors.request.use(
  (config: AxiosRequestConfig) => {
    config.headers = {
      ...config.headers,
      // ...auth.headers(), // 你的自定义headers,如token等
    };
    return config;
  },
  (error: AxiosError) => {
    return Promise.reject(error);
  }
);

// axios实例拦截响应
service.interceptors.response.use(
  // 2xx时触发
  (response: AxiosResponse<Response>) => {
    // response.data就是后端返回的数据,结构根据你们的约定来定义
    const { code, message } = response.data;
    let errMessage = '';
    switch (code) {
      case 0:
        break;
      case 1: // token过期
        errMessage = 'Token expired';
        router.push('/login');
        break;
      case 2: // 无权限
        errMessage = 'No permission';
        break;
      // default:
      //   errMessage = message;
      //   break;
    }
    if (errMessage) Toast.fail(errMessage);
    return response;
  },
  // 非2xx时触发
  (error: AxiosError) => {
    Toast.fail('Network Error...');
    return Promise.reject(error);
  }
);

export type { AxiosResponse, AxiosRequestConfig };

export default service;
// src/utils/http/index.ts

import service, { AxiosRequestConfig } from './axios';
export * from './types';

export const request = <T = any>(config: AxiosRequestConfig): Promise<T> => {
  return new Promise((resolve, reject) => {
    service
      .request(config)
      .then((res) => {
        // 一些业务处理
        resolve(res.data);
      })
      .catch((err) => {
        console.log('request fail:', err);
      });
  });
};

const http = {
  get<T = any>(url: string, params = {}, config?: AxiosRequestConfig): Promise<T> {
    return request({ url, params, ...config, method: 'GET' });
  },
  post<T = any>(url: string, data = {}, config?: AxiosRequestConfig): Promise<T> {
    return request({ url, data, ...config, method: 'POST' });
  },
  put<T = any>(url: string, data = {}, config?: AxiosRequestConfig): Promise<T> {
    return request({ url, data, ...config, method: 'PUT' });
  },
  delete<T = any>(url: string, data = {}, config?: AxiosRequestConfig): Promise<T> {
    return request({ url, data, ...config, method: 'DELETE' });
  },
  // 上传文件,指定 'Content-Type': 'multipart/form-data'
  upload<T = any>(url: string, data = {}, config?: AxiosRequestConfig): Promise<T> {
    return request({
      url,
      data,
      ...config,
      method: 'POST',
      headers: { 'Content-Type': 'multipart/form-data' },
    });
  },
};

export default http;
// src/utils/http/types.ts

// 和后端约定好接口返回的数据结构
export interface Response<T = any> {
  data: string[];
  code: number | string;
  message: string;
  result: T;
}

示例页面

banner列表页面

<script setup>
import ResourceList from '@/components/ResourceList.vue'
import { monthlyResourceList } from '@/service/api/common'
import { onMounted, ref } from 'vue'
import { useRoute, useRouter } from "vue-router";

const $route = useRoute()
const $router = useRouter()
const list = ref([])
const loading = ref(false);
const finished = ref(false);
const refreshing = ref(false);
const params = ref({
  relationId: $route.query.id,
  relationType: 'banner',
  currentPage: 1,
  pageSize: 10
})
onMounted(() => {
  document.title = $route.query.name
  getColumnResourceList()
})
const getColumnResourceList = () => monthlyResourceList(params.value).then(res => {
  loading.value = true
  if (res.success) {
    loading.value = false
    list.value = [...list.value,...res.data]

    // 如果列表数据条数>=总条数,不再触发滚动加载
    if (list.value.length >= res.totalCount) {
      finished.value = true
    }
  }
})
const onRefresh = () => {
  params.value.currentPage = 1
  finished.value = false;
  refreshing.value = false
  list.value = []
  getColumnResourceList();
};
const onLoad1 = () => {
  params.value.currentPage++
  getColumnResourceList()
}
const toInfo = row => {
  const { type, resourceSource, resourceId, id: relationId, relationType = 'banner' } = row
  $router.push({
    path: '/detail',
    query: { type, resourceSource, resourceId, relationId, relationType }
  })
}

</script>

<template>
  <div class='monthInfo'>
    <van-pull-refresh v-model="refreshing" @refresh="onRefresh">
    <van-list
      v-model:loading="loading"
      :finished="finished"
      finished-text="没有更多了"
      :immediate-check="false"
      @load="onLoad1"
    >
      <div v-for="(item, i) in list" :key="i">
        <ResourceList :info="item" @click="toInfo(item)"></ResourceList>
      </div>
    </van-list>
    </van-pull-refresh>
    
  </div>
</template>

<style lang='scss' scoped>
.monthInfo {
  padding: 22px 16px;
}
</style>

项目地址

为了安全协议:项目地址api 已全部替换(望理解!!!)
https://gitee.com/hammer1010_admin/vue3-vite

希望能帮助到大家,同时祝愿大家在开发旅途中愉快!!!

拿着 不谢 请叫我“锤” !!!

  JavaScript知识库 最新文章
ES6的相关知识点
react 函数式组件 & react其他一些总结
Vue基础超详细
前端JS也可以连点成线(Vue中运用 AntVG6)
Vue事件处理的基本使用
Vue后台项目的记录 (一)
前后端分离vue跨域,devServer配置proxy代理
TypeScript
初识vuex
vue项目安装包指令收集
上一篇文章      下一篇文章      查看所有文章
加:2022-10-22 21:06:34  更:2022-10-22 21:08:46 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年5日历 -2024/5/17 15:06:20-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码