vue3.2+vite+vant4+sass搭建笔记

news2024/11/18 3:19:44

1、确定node版本

1、下载nvm安装包

官方下载地址:https://github.com/coreybutler/nvm-windows/releases

双击安装 

 

 

 

 

 

 

 2、在node官网下载安装多个node

3、切换node

 

 

2、创建项目 

 1、安装依赖

pnpm i

2、启动项目

npm run dev

 

3、配置@指向src 

import { defineConfig,loadEnv  } from 'vite'
import vue from '@vitejs/plugin-vue'
import Components from 'unplugin-vue-components/vite';
import { VantResolver } from 'unplugin-vue-components/resolvers';
import path from 'path';
const resolve = (dir) => path.resolve(__dirname, dir);

// https://vitejs.dev/config/
export default defineConfig(({mode})=>{
   // 获取当前环境的配置
   const config = loadEnv(mode, './')
   return {
    plugins: [vue(),
      Components({
        resolvers: [VantResolver()],
      }),
    ],
    resolve: {
      alias: {
        '@': resolve('src'),//作为 entries 的选项
      },
      extensions: ['.mjs', '.js', '.ts', '.jsx', '.tsx', '.json', '.vue'],
    },
   }
 
})

3、安装vant4 

1、安装

pnpm add vant

 2、按需引入

pnpm add unplugin-vue-components -D

 3、配置插件

在 vite.config.js 文件中配置插件

import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import Components from 'unplugin-vue-components/vite';
import { VantResolver } from 'unplugin-vue-components/resolvers';
// https://vitejs.dev/config/
export default defineConfig({
  plugins: [
    vue(),
    Components({
      resolvers: [VantResolver()],
    }),
  ],
  
})

4、使用组件

<van-button type="primary" >默认按钮</van-button>

 tips:函数组件样式有异常,在main.js中引入vant样式

import "vant/lib/index.css"

5、rem布局适配

1、安装插件

  • postcss-pxtorem 是一款 PostCSS 插件,用于将 px 单位转化为 rem 单位
  • lib-flexible 用于设置 rem 基准值
pnpm install postcss postcss-pxtorem --save-dev
pnpm i -S amfe-flexible

 

 2、PostCSS 示例配置:新建postcss.config.js

// postcss.config.js
module.exports = {
  plugins: {
    // postcss-pxtorem 插件的版本需要 >= 5.0.0
    'postcss-pxtorem': {
      rootValue({ file }) {
        return file.indexOf('vant') !== -1 ? 37.5 : 75;
      },
      propList: ['*'],
    },
  },
};

3、在main.js中引入 amfe-flexible

import 'amfe-flexible'

重启项目报错

 修改文件名后缀.cjs, postcss.config.cjs,重启项目即可

 

4、使用sass

1、安装

pnpm install --save-dev sass

2、新建src/styles文件夹下index.scss,定义默认颜色变量

$defaultColor:#1989fa;

3、vite配置

import { defineConfig,loadEnv  } from 'vite'
import vue from '@vitejs/plugin-vue'
import Components from 'unplugin-vue-components/vite';
import { VantResolver } from 'unplugin-vue-components/resolvers';
import path from 'path';
const resolve = (dir) => path.resolve(__dirname, dir);

// https://vitejs.dev/config/
export default defineConfig(({mode})=>{
   // 获取当前环境的配置
   const config = loadEnv(mode, './')
   return {
    plugins: [vue(),
      Components({
        resolvers: [VantResolver()],
      }),
    ],
    css:{
      preprocessorOptions: {
        scss: {
          additionalData: ` @import "@/styles/index.scss";   `
        }
      }
    },
    resolve: {
      alias: {
        '@': resolve('src'),//作为 entries 的选项
      },
      extensions: ['.mjs', '.js', '.ts', '.jsx', '.tsx', '.json', '.vue'],
    },
   }
 
})

4、使用scss变量

<script setup>
</script>

<template>
  <div>
    <van-button type="primary" >默认按钮</van-button>
    <div class="test">测试字体大小</div>
  </div>
</template>

<style scoped lang="scss">
.test{
  font-size: 40px;
  color: $defaultColor;
}
</style>

 5、配置环境变量

1、新建 .env.development、.env.production文件

.env.development内容如下

VITE_APP_BASE_URL='/api'
#VITE_APP_BASE_URL='http://192.168.1.33:8088'

2、使用环境变量vite.config.js

import { defineConfig,loadEnv  } from 'vite'
import vue from '@vitejs/plugin-vue'
import Components from 'unplugin-vue-components/vite';
import { VantResolver } from 'unplugin-vue-components/resolvers';
import path from 'path';
const resolve = (dir) => path.resolve(__dirname, dir);

// https://vitejs.dev/config/
export default defineConfig(({mode})=>{
   // 获取当前环境的配置
   const config = loadEnv(mode, './')
   return {
    plugins: [vue(),
      Components({
        resolvers: [VantResolver()],
      }),
    ],
    css:{
      preprocessorOptions: {
        scss: {
          additionalData: ` @import "@/styles/index.scss";   `
        }
      }
    },
    server: {
      proxy: {
        '/api': {
          // target: "http://192.168.1.33:8088",
          target: config.VITE_APP_BASE_URL,
          changeOrigin: true,
          rewrite: (path) => path.replace(/^\/api/, '')
        }
      }
   },
    resolve: {
      alias: {
        '@': resolve('src'),//作为 entries 的选项
      },
      extensions: ['.mjs', '.js', '.ts', '.jsx', '.tsx', '.json', '.vue'],
    },
   }
 
})

6、vite配置跨域
 

import { defineConfig,loadEnv  } from 'vite'
import vue from '@vitejs/plugin-vue'
import Components from 'unplugin-vue-components/vite';
import { VantResolver } from 'unplugin-vue-components/resolvers';
import path from 'path';
const resolve = (dir) => path.resolve(__dirname, dir);

// https://vitejs.dev/config/
export default defineConfig(({mode})=>{
   // 获取当前环境的配置
   const config = loadEnv(mode, './')
   return {
    plugins: [vue(),
      Components({
        resolvers: [VantResolver()],
      }),
    ],
    css:{
      preprocessorOptions: {
        scss: {
          additionalData: ` @import "@/styles/index.scss";   `
        }
      }
    },
    server: {
      proxy: {
        '/api': {
          // target: "http://192.168.1.33:8088",
          target: config.VITE_APP_BASE_URL,
          changeOrigin: true,
          rewrite: (path) => path.replace(/^\/api/, '')
        }
      }
   },
    resolve: {
      alias: {
        '@': resolve('src'),//作为 entries 的选项
      },
      extensions: ['.mjs', '.js', '.ts', '.jsx', '.tsx', '.json', '.vue'],
    },
   }
 
})

7、请求响应加密sm-crypto

1、安装

pnpm i sm-crypto --save

2、新建config/index.js,配置加密解密公钥私钥

export const PUBLICKEY='****************************************'
export const PRIVATEKEY='**************************'

3、新建utils/crypto.js,封装加密解密方法

import { sm2 } from 'sm-crypto';
import {PUBLICKEY,PRIVATEKEY} from '@/config/index'
//加密
export function doEncrypt(msgString) {
    let msg = msgString
    if (typeof msgString !== 'string') {
      msg = JSON.stringify(msgString)
    }
    // console.log(msg,'加密前')
    // 1 - C1C3C2;	0 - C1C2C3;	默认为1
    let cipherMode = 0
    let publicKey = PUBLICKEY
    // 加密结果
    let encryptData = sm2.doEncrypt(msg, publicKey, cipherMode)
    //Base64编码 自行选择是否使用
    //let baseEncode = Base64.encode(encryptData)
    // 加密后的密文前需要添加04,后端才能正常解密 (不添加04,后端处理也可以)
    let encrypt = '04' + encryptData
    return encrypt
}


// 解密
export function doDecryptStr(enStr) {
    let msg = enStr
    if (typeof enStr !== 'string') {
      msg = JSON.stringify(enStr)
   }
    // 1 - C1C3C2;	0 - C1C2C3;  默认为1
    let cipherMode = 0
    let privateKey = PRIVATEKEY
    let enval = enStr.substring(2)
    // 解密结果
    let doDecrypt = sm2.doDecrypt(enval , privateKey, cipherMode)
    // 解密后类型转换
    let objData = JSON.parse(doDecrypt)
    return objData
 
}

8、封装axios

1、安装axios、qs

pnpm i axios qs --save

2、新建utils/request.js,后台是.net,要求传参formData格式

import axios from 'axios'; // 引入axios
import qs from 'qs'
import { showToast,showLoadingToast,showFailToast, closeToast } from 'vant';
import {doEncrypt,doDecryptStr} from './crypto'
let toast=null
// 创建时自定义默认配置,超时设置为全局默认值0秒
let service = axios.create({
    baseURL: import.meta.env.VITE_APP_BASE_URL, // url = base url + request url
    // withCredentials: true, // send cookies when cross-domain requests
    timeout: 50000 ,// request timeout
    headers: {
      'Access-Control-Allow-Origin': '*',
      'Content-Type': 'application/x-www-form-urlencoded'
    //   'Content-Type': 'application/json'
    }
  })
  // 请拦截
  service.interceptors.request.use(
    config => {
      //loading
      toast=showLoadingToast({
      
        
        forbidClick: true,
        loadingType: 'spinner',
        message: '加载中',
      });
      let token = localStorage.getItem('token')
      if (token) {
        config.headers['token'] = token
      }
    //    console.log(config.data,'加密前参数')
       config.data=qs.stringify({json:doEncrypt(config.data)});
    //    console.log(config.data,'加密后参数')
      return config
    },
    error => {
      // do something with request error
      closeToast()//清除loading
      console.log(error) // for debug
      return Promise.reject(error)
    }
  )
  
  // 响应拦截
  service.interceptors.response.use(
    response => {
      closeToast()//清除loading
    //   console.log('response',response);
      let {data} = response
      if(data.Status!==1) return showFailToast(data.Msg);
      return doDecryptStr(data.Data)
    },
    error => {
      console.log('err' + error) // for debug
      showFailToast(error || "请求失败");
      // return Promise.reject(error)
    }
  )
  
  export default service

9、api集中管理

1、新建api文件夹,新建user.js

import request from '@/utils/request'
export function loginApi(data) {
  return request({
     url: '/login.asmx/UserLogin',
    method: 'post',
    data,
  })
}

2、页面调用

import {loginApi} from '@/api/user.js'
const login = async ()=>{
    let res = await loginApi({
        Account:"admin",
        Pwd:"0000"
    })
    console.log(res,'返回结果')
}
login()

10、安装路由

1、安装

pnpm install vue-router@4

2、新建router/index.js

import {createRouter,createWebHashHistory} from 'vue-router'
import Home from '@/views/home/Home.vue'
import About from '@/views/about/About.vue'
// 2. 定义一些路由
// 每个路由都需要映射到一个组件。
// 我们后面再讨论嵌套路由。
const routes = [
    { path: '/', component: Home },
     { path: '/about', component: About },
  ]
  
  // 3. 创建路由实例并传递 `routes` 配置
  // 你可以在这里输入更多的配置,但我们在这里
  // 暂时保持简单
  const router =createRouter({
    // 4. 内部提供了 history 模式的实现。为了简单起见,我们在这里使用 hash 模式。
    history: createWebHashHistory(),
    routes, // `routes: routes` 的缩写
  })

  export default router

3、使用

  <p>
    <!--使用 router-link 组件进行导航 -->
    <!--通过传递 `to` 来指定链接 -->
    <!--`<router-link>` 将呈现一个带有正确 `href` 属性的 `<a>` 标签-->
    <router-link to="/">Go to Home</router-link>
    <router-link to="/about">Go to About</router-link>
  </p>
  <!-- 路由出口 -->
  <!-- 路由匹配到的组件将渲染在这里 -->
  <router-view></router-view>

11、安装pinia

1、安装

pnpm install pinia --save

2、main.js引入 

import { createApp } from 'vue'

import App from './App.vue'
import router from './router'
import 'amfe-flexible'
import 'vant/lib/index.css'
import { createPinia } from 'pinia'
const pinia = createPinia()
const app= createApp(App)
app.use(router)
app.use(pinia)
app.mount('#app')

2、新建store/home.js

import { defineStore } from  'pinia'
 
export const homeStore = defineStore('home',{
    state:()=>{
        return {
            count:100,
            price:250
        }
    },
    getters:{
        doubleCount(){
            return this.count*2
        },
        doublePrice(){
            return this.price*2
        }
    },
    actions:{
        changeStoreData(){
            this.count+=1
            this.price+=1
        },
    }
})

3、使用 

<template>
    <div>
     
        <h1> 主页{{ msg }}</h1>
      <p>{{count}}</p>
      <p>{{doubleCount}}</p>
        <van-button size='large' type="primary" @click="changeData">改变数据</van-button>
            </div>
</template>

<script setup>
import { ref } from 'vue'
import { storeToRefs } from 'pinia';
import { homeStore } from '@/store/home.js';
import {loginApi} from '@/api/home.js'
const store = homeStore()
let { count,doubleCount,price,doublePrice } = storeToRefs(store)
defineProps({
  msg: String,
})

const changeData = ()=>{
  //1、直接修改count
//   count.value++
//    price.value++
  //2、$patch批量修改State的值
//   store.$patch({
//     count:500,
//     price:1000
//   })
  //3、$patch批量修改函数形式
//   store.$patch((state)=>{
//     state.count++
//     state.price++
//   })
  //4、通过原始对象修改整个实例
  //$state您可以通过将store的属性设置为新对象来替换store的整个状态
  //缺点就是必须修改整个对象的所有属性
//   store.$state={
//     count:0,
//     price:1
//   }
  //5、通过actions修改
    store.changeStoreData()
  
}

const login = async ()=>{
    let res = await loginApi({
        Account:"admin",
        Pwd:"0000"
    })
    console.log(res,'返回结果')
}
login()
</script>

<style lang="scss" scoped>
h1{
    font-size: 40px;
    color: $defaultColor;
}
</style>

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/492765.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

FAST协议解析2 FIX Fast Tutorial翻译【PMap、copy操作符】

FIX Fast Tutorial FIX Fast教程 &#xff08;译注&#xff1a;本篇是对https://jettekfix.com/education/fix-fast-tutorial/翻译和解释&#xff0c;除了文本的直接翻译外&#xff0c;我还针对各点按我的理解进行了说明和验证&#xff0c;所以可以看到译文下会有很多译注&am…

虹科方案 | HK-Edgility:将 SASE 带到边缘

通过上期的文章&#xff0c;我们了解到虹科HK-Edgility软件系统《面向未来的安全SD-WAN》的解决方案。本篇文章&#xff0c;我们将带您了解虹科系统在SASE的方案简介。 一、时代背景 向软件即服务 (SaaS) 和云原生应用程序的过渡&#xff0c;加上越来越多的远程用户生成和访问公…

快来参与:2023全国大数据与计算智能挑战赛正在报名中

全国大数据与计算智能挑战赛是由国防科技大学系统工程学院大数据与决策实验室组织的年度赛事活动&#xff0c;旨在深入挖掘大数据应用实践中亟需破解的能力生成难题、选拔汇聚数据领域优势团队、促进大数据领域的技术创新和面向需求的成果生成、推动形成“集智众筹、联合攻关、…

Spring项目的创建与使用

一、创建Spring项目 这里使用Maven方式创建Spring项目&#xff0c;分为以下三步&#xff1a; 创建一个普通的Maven项目添加spring框架支持添加启动类 注&#xff1a;这里创建的是一个spring的core项目&#xff0c;不是web项目&#xff0c;只需要main方法&#xff0c;不需要t…

Ubuntu显示美化 优化 常用插件

Ubuntu显示美化 优化 常用插件 1. 安装 Extension Manager2. 网速显示&#xff08;不显示总流量记得关掉&#xff09;3. 顶部透明度4. 左侧dock导航透明度5. 过渡动画2022-01-22 毛玻璃效果 和 程序启动背景墙效果2022-01-23 窗口预览&#xff08;类windos多窗口&#xff09;20…

C++11实现线程池

1.所有权的传递 适用移动语义可以将一个unique_lock赋值给另一个unique_lock,适用move实现。 void myThread1() {unique_lock<mutex> myUnique (testMutex1,std::defer_lock);unique_lock<mutex>myUnique1(std::move(myUnique));//myUnique 则实效 myUnique1 相当…

在Linux中进行Jenkins部署(maven-3.9.1+jdk11)

Jenkins部署在公网IP为x.x.x.x的服务器上 maven-3.9.1要安装在jdk11环境中 环境准备 第一步&#xff0c;下载jdk-11.0.19_linux-x64_bin.tar.gz安装包。 登录地址&#xff1a;Java Downloads | Oracle 下载jdk-11.0.19_linux-x64_bin.tar.gz安装包&#xff0c;然后使用Win…

电子温湿度记录仪

电子温湿度记录仪&#xff1a;实时监测环境温度和湿度电子温湿度记录仪是一种用于实时监测环境温度和湿度的设备。它广泛应用于医疗、制药、食品加工、仓储、博物馆、实验室等领域&#xff0c;以确保环境温湿度处于合适的范围内&#xff0c;以保持物品和设备的稳定性和安全性。…

信号的产生——tripuls函数

信号的产生——tripuls函数, 功能&#xff1a;产生非周期三角波信号&#xff0c;其调用格式如下&#xff1a; &#xff08;1&#xff09;ytripuls(t)&#xff0c; &#xff08;2&#xff09;ytripuls(t,w)&#xff0c; &#xff08;3&#xff09;ytripuls(t,w,s)&#xff0…

Java多线程入门到精通学习大全?深入了解线程:生命周期、状态和优先级!(第二篇:线程的基础知识学习)

本文详细介绍了线程的基础知识&#xff0c;包括什么是线程、线程的生命周期、线程的状态和线程优先级等。在了解这些知识后&#xff0c;我们能够更好地掌握线程的使用方式&#xff0c;提高程序的并发性和效率。如果您对线程有更深入的问题&#xff0c;也欢迎向我们提问。 1. 什…

华为MPLS跨域——后门链路实验配置

目录 配置PE与CE设备对接命令&#xff08;通过OSPF对接&#xff09; 配置后门链路 可以使用任意方式来跑跨域MPLS&#xff08;A、B、C1、C2都可以&#xff09;&#xff0c;不过关于传递Vpnv4路由的配置此处不做介绍&#xff1b;此处只介绍关于PE和CE对接的配置和关于后门链路…

node.js的核心模块

node的核心模块由一些精简而高效的库组成 文章目录 全局对象全局对象和全局变量processcosole utilutils.inheritsutils.inspect 事件机制事件发射器error 事件继承EventEmitter 文件系统访问fs.readFile(filename,[encoding],[callback(err,data)])fs.readFileSync(filename,…

NSSCTF (2)

[GKCTF 2020]cve版签到 查看响应头发现有几个可能利用的信息 1.hint 里面的Flag in localhost 2.apache 2.4.38 3. php 7.3.15 我们发现第一个是提示 第二个apache版本没有什么漏洞 但是php 7.3.15 存在cve漏洞 这里题目规定 *.ctfhub.com 所以我们 要以这个结尾 在 p…

05-事务管理

概念&#xff1a; 事务是一组操作的集合&#xff0c;它是不可分割的工作单位&#xff0c;这些操作要么同时成功&#xff0c;要么同时失败 操作&#xff1a; 开启事务&#xff08;一组操作开始前&#xff0c;开启事务) : start transaction / begin ; 提交事务&#xff08;这组操…

【LeetCode】1000题挑战(230/1000)

1000题挑战 没有废话&#xff0c;直接开刷&#xff01; 目录 1000题挑战 没有废话&#xff0c;直接开刷&#xff01; 第一题&#xff1a;242. 有效的字母异位词 - 力扣&#xff08;Leetcode&#xff09; 题目接口&#xff1a; 解题思路&#xff1a; 代码&#xff1a; …

罗马数字转整数:探究古代数字编码的奥秘

本篇博客会讲解力扣中“13. 罗马数字转整数”这道题的解题思路。 大家先来审下题&#xff1a;题目链接。 题干如下&#xff1a; 有几个输出样例&#xff1a; 提示如下&#xff1a; 大家先思考一下&#xff0c;再来听我讲解。 本题的关键是&#xff1a;如何把罗马数字转换…

文末赠书3本 | 盼了一年的Core Java最新版卷Ⅱ,终于上市了

文章目录 盼了一年的Core Java最新版卷Ⅱ&#xff0c;终于上市了&#xff01;Core Java基于Java 17全面升级Core Java最新版卷Ⅱ现已上市卷Ⅰ、卷Ⅱ有何不同&#xff1f;如何阅读《Java核心技术》从未远离工业界的Java大神带你学50位行业专家、技术媒体赞誉推荐如何选择版本文末…

Python基础入门(2)—— 什么是控制语句、列表、元组和序列?

文章目录 01 | &#x1f684;控制语句02 | &#x1f685;列表03 | &#x1f688;元组04 | &#x1f69d;序列05 | &#x1f69e;习题 A bold attempt is half success. 勇敢的尝试是成功的一半。 前面学习了Python的基本原则、变量、字符串、运算符和数据类型等知识&#xff0c…

树形结构——堆的构建

在学习完我们的树形结构之后我们再来使用树形结构的思想构建一个堆。使用堆可以对我们的数据进行排序&#xff0c;并且堆排序的效率要远优于我们之前学习过的冒泡排序。下面我们来逐步实现堆这个数据结构。 在构建堆之前我们需要先介绍以下我们树形结构构建的两种形式&#xff…

掌握这些GitHub搜索技巧,你的开发效率将翻倍!

作为开发it行业一员&#xff0c;学习借鉴他人项目是很有必要的&#xff0c;所以我们一般都会从github或者 Gitee 上面去参考借鉴他人的项目来学习增加自己的项目经验 但是一般我还是在github上看项目比较多&#xff0c;毕竟人家实力项目量摆在那里 &#xff0c;但是国内访问gi…