Mac快速搭建前端环境&创建前端项目

官网:

  1. vue:https://cn.vuejs.org/
  2. vue-router:https://www.axios-http.cn/
  3. pinia:https://pinia.vuejs.org/zh/getting-started.html
  4. axios:https://www.axios-http.cn/
  5. ant-design:https://www.antdv.com/

1 开发环境搭建

①安装node(nvm)

下载:https://nodejs.org/en
Mac可以安装配置nvm(管理node的工具)

  • https://github.com/nvm-sh/nvm
  • 如果安装过程中出现443,表明可能被墙了
  • 解决:打开网站https://www.ipaddress.com/
    查询一下 raw.githubusercontent.com对应的IP 地址,然后修改本机的vim /etc/hosts文件
185.199.108.133  raw.githubusercontent.com
### nvm安装及使用
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.7/install.sh | bash

# 配置环境变量
export NVM_DIR="$HOME/.nvm"
[ -s "$NVM_DIR/nvm.sh" ] && . "$NVM_DIR/nvm.sh"

# 完成后输入nvm,出现node version manger表示安装成功
nvm

# 使用:
## 1 安装node( nvm ls-remote  | grep 18 查看有哪些node版本)
nvm install 13.0.1
## 2 查看是否安装成功
nvm list | grep 13
## 3 切换版本
nvm use 13.0.1

在这里插入图片描述

②配置npm

# 配置npm
npm config set registry https://registry.npmmirror.com  #设置国内阿里云镜像源
npm config get registry  #查看镜像源

npm init: 项目初始化;
npm init -y:默认一路yes,不用挨个输入信息
npm install 包名:安装js包到项目中(仅当前项目有效)。指定 包名,或者 包名@版本号
npm install -g: 全局安装,所有都能用
可以去 npm仓库 搜索第三方库
npm update 包名:升级包到最新版本
npm uninstall 包名:卸载包
npm run:项目运行

③安装vite(脚手架)

vite:快速创建前端项目脚手架。包括react、vue等项目
官网:https://cn.vitejs.dev

npm create vite #根据向导选择技术栈

npm install #安装项目所有依赖

npm install axios #安装指定依赖到当前项目
npm install -g xxx # 全局安装

# 项目启动
npm run dev #启动项目

# 项目打包
## 前后分离方式:需要把 dist 文件夹内容部署到如 nginx 之类的服务器上。
## 前后不分离方式:把 dist 文件夹内容复制到 SpringBoot 项目 resources 下面
npm run build #构建后 生成 dist 文件夹

在这里插入图片描述

问题:如果出现报错:node:77305) Warning: require() of ES modules is not supported.,表明node版本过低不支持。通过nvm升级node版本即可。nvm use v18.20.2

④vue浏览器插件:Vue.js devtools

在这里插入图片描述
使用:
在这里插入图片描述

⑤VSCode/WebStorm

  • VSCode官网(轻量级):https://code.visualstudio.com/Download
    在这里插入图片描述
  • WebStorm官网:https://www.jetbrains.com/webstorm/download/#section=mac
    在这里插入图片描述

2 快速搭建简易登录页面

使用技术:vue+vue-router-pinia+axios+ant-design
官网:

  1. vue:https://cn.vuejs.org/
  2. vue-router:https://www.axios-http.cn/
  3. pinia:https://pinia.vuejs.org/zh/getting-started.html
  4. axios:https://www.axios-http.cn/
  5. ant-design:https://www.antdv.com/

🚀全部代码:https://github.com/ziyifast/ziyifast-code_instruction/tree/main/front_demo/vue/vue-all

2.1 创建vue项目

①vite创建vue基础项目
# 创建vue项目
npm create vite
# 进入项目并安装依赖
cd vue-all
npm install

# 启动项目
npm run dev

在这里插入图片描述

②引入ant-design
//安装依赖
npm i --save ant-design-vue@4.x

//main.js中注册使用
import { createApp } from 'vue';
import App from './App';
import Antd from 'ant-design-vue';
import 'ant-design-vue/dist/reset.css';

const app = createApp(App);

app.use(Antd).mount('#app');

2.2 使用ant-design快速搭建页面

在这里插入图片描述

①vue及路由配置
App.vue
<script>
</script>

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

<style scoped>
</style>
views/LoginVue.vue
<script>
import {login} from "@/api/user.js";
export default {
  data() {
    return {
      loginUser: {
        username: 'admin',
        password: 'admin',
      },
    };
  },
  methods: {
    userLogin(){
      login(this.loginUser).then(res => {
        console.log(res.status)
        if(res.status === 200){
          alert('登录成功')
          this.$router.push({path: `/userInfo/`})
        }
      }, error => {
        alert('登录失败')
      })
    }


  },
}
</script>

<template>
  <div class="loginContainer">
    <div class="loginHeader">
      <span style="color: #2b92e4">ziyi后台管理系统</span>
    </div>
    <div class="loginMainWrapper">
      <div class="loginWrapper">
        <div class="loginTipsWrapper" style="color: #ffffff">
          <span class="siteSummaryTitle">ziy后台管理系统</span>
          <div class="siteSummary">
            <ul>
              <li>
                <a-icon type="check-square" style="margin-right: 10px"/>
                <span>统一方便的资源管理</span></li>
              <li>
                <a-icon type="check-square" style="margin-right: 10px"/>
                <span>友好的界面展示,基于AntDesign组件库</span></li>
              <li>
                <a-icon type="check-square" style="margin-right: 10px"/>
                <span>前后端分离,便于维护</span></li>
            </ul>
          </div>
        </div>
        <div class="loginBoxWrapper" align="center">
          <a-form-model :model="loginUser" style="width: 100%">
            <a-form-model-item style="color: palevioletred;text-align: center">
              <h1>欢迎登录</h1>
            </a-form-model-item>
            <a-form-model-item>
              <a-input v-model:value="loginUser.username" placeholder="账号">
                <a-icon slot="prefix" type="user" style="color:rgba(0,0,0,.25)"/>
              </a-input>
            </a-form-model-item>
            <a-form-model-item>
              <a-input v-model:value="loginUser.password" type="password" placeholder="密码">
                <a-icon slot="prefix" type="lock" style="color:rgba(0,0,0,.25)"/>
              </a-input>
            </a-form-model-item>
            <a-form-model-item>
            </a-form-model-item>
            <a-form-model-item>
              <a-button type="primary" html-type="submit" style="width: 100%" @submit.prevent
                        @click="userLogin">立即登录
              </a-button>
              <a-button style="width: 100%;margin-top: 10px">注册账号</a-button>
            </a-form-model-item>
            <a-form-model-item style="text-align: center">
              <a-space size="large">
                <a-icon type="weibo" style="font-size: 2em;cursor: pointer;color:#f50"/>
                <a-icon type="qq" style="font-size: 2em;cursor: pointer;color:#2b92e4;"/>
                <a-icon type="github" style="font-size: 2em;cursor: pointer;color:#333;"/>
              </a-space>
            </a-form-model-item>
          </a-form-model>
        </div>
      </div>
      <div class="loginFooter">
        © 2020-2024 CoreCmd 版权所有. 川ICP备18063315-1 川公网安备 52158202001416</div>
    </div>
  </div>
</template>

<style scoped>
.loginContainer {
  width: 100%;
  position: relative;
  background-attachment: fixed;
  background-repeat: no-repeat !important;
  background-size: cover;
  background-position: center;
  padding-top: 105px;
  min-height: 100%;
}

.loginHeader {
  width: 100%;
  height: 64px;
  background-color: #ffffff;
  position: fixed;
  left: 0;
  right: 0;
  top: 0;
  z-index: 1000;
  box-shadow: 0 2px 15px rgba(0, 0, 0, .2);
  display: flex;
  align-items: center;
  justify-content: flex-start;
  flex-direction: row;
  padding: 10px;
}

.loginHeader span {
  font-size: 25px;
  font-weight: 700;
}

.loginMainWrapper {
  width: 100%;
  display: flex;
  justify-content: space-between;
  flex-direction: column;
  align-items: center;
}

.loginWrapper {
  width: 90%;
  display: flex;
  align-items: flex-start;
  justify-content: right;
  flex-direction: row;
  height: 100%;
}

.loginFooter {
  width: 100%;
  min-height: 64px;
  display: flex;
  justify-content: center;
  align-items: flex-start;
  flex-direction: row;
  text-align: center;
  color: #ffffff;
  margin-top: 40px;
}

.siteSummary ul {
  list-style: none;
  padding: 0;
}

.siteSummary ul li {
  margin-top: 10px;
  list-style: none;
}

@media screen and (min-width: 1200px) {
  .loginTipsWrapper {
    padding: 20px 30px;
    display: flex;
    align-items: flex-start;
    justify-content: center;
    flex-direction: column;
    min-height: 100%;
  }

  .loginBoxWrapper {
    background-color: #ffffff;
    padding: 20px;
    width: 400px;
    height: 100%;
    border-radius: 5px;
  }
}

@media screen and (min-width: 769px) and (max-width: 1200px) {
  .loginTipsWrapper {
    padding: 20px 30px;
    display: flex;
    align-items: flex-start;
    justify-content: center;
    flex-direction: column;
    height: 100%;
  }

  .loginBoxWrapper {
    background-color: #ffffff;
    padding: 20px;
    width: 400px;
    height: 100%;
    border-radius: 5px;
  }
}

@media screen and (max-width: 768px) {
  .loginTipsWrapper {
    display: none;
  }

  .loginBoxWrapper {
    background-color: #ffffff;
    padding: 20px;
    width: 100%;
    border-radius: 5px;
  }
}

.siteSummaryTitle {
  color: #ffffff;
  font-size: 1.5rem;
  font-weight: 700;
}

.siteSummary {
  margin-top: 25px;
  color: #ffffff;
  font-size: 1.2rem;
  font-weight: 300;
}
</style>
views/UserInfo.vue
<script setup>

</script>

<template>
  <h1>用户中心</h1>
</template>

<style scoped>

</style>
router/index.js
import {createRouter, createWebHistory} from 'vue-router'
import UserInfo from "@/views/UserInfo.vue";
import LoginVue from "@/views/LoginVue.vue";

const router = createRouter({
    history: createWebHistory(import.meta.env.BASE_URL),
    routes: [
        {
            path: '/', //默认展示登录页面
            name: 'login',
            component: LoginVue,
        },
        {
            path: '/userInfo',
            name: 'userInfo',
            component: UserInfo,
        }
    ]
})

export default router
②封装axios(util/http.js)
import axios from "axios";

//封装请求
const http = axios.create({
    baseURL: '/api',
    timeout: 5000,
    headers: {
        'Content-Type': 'application/json;charset=UTF-8'
    },
    withCredentials:true, //允许跨域
});


function get(url, params = {}) {
    return new Promise((resolve, reject) => {
        http.get(url, {
            params: params
        }).then(res => {
            resolve(res.data);
        }).catch(err => {
            reject(err.data)
        })
    })
}

function post(url, data = {}) {
    return new Promise((resolve, reject) => {
        http.post(url, data)
            .then(response => {
                resolve(response.data);
            })
            .catch(err => {
                reject(err)
            })
    })
}

export default http;
③user.js
import http from '../utils/http.js'

export const login = (params) => http.post(`/login`, params)

2.4 vite.config.js解决跨域

import {fileURLToPath, URL} from 'node:url'

import {defineConfig} from 'vite'
import vue from '@vitejs/plugin-vue'

// https://vitejs.dev/config/
export default defineConfig({
    plugins: [
        vue(),
    ],
    resolve: {
        alias: {
            '@': fileURLToPath(new URL('./src', import.meta.url))
        }
    },
    //配置代理
    server: {
        proxy: {
            '/api': {
                target: 'http://localhost:8080', // 后端服务器地址
                changeOrigin: true, // 是否改变请求域名
                rewrite: (path) => path.replace(/^\/api/, '')//将原有请求路径中的api替换为''
            }
        }
    }
})

2.4 后端接口(Golang版)

为了代码简洁,这里直接使用硬编码,不再进行连接查询数据库等操作

package main

import (
	"fmt"
	"github.com/kataras/iris/v12"
	"github.com/kataras/iris/v12/context"
	"net/http"
)

func main() {
	app := iris.New()
	app.Use(Cors)
	app.Post("/login", login())
	app.Listen(":8080")
}

func login() func(ctx *context.Context) {
	return func(ctx *context.Context) {
		tmp := make(map[string]interface{})
		err := ctx.ReadJSON(&tmp)
		if err != nil {
			ctx.StatusCode(http.StatusBadRequest)
			return
		}
		username := tmp["username"]
		password := tmp["password"]
		fmt.Println("username:", username, "password:", password)
		if username == "admin" && password == "admin" {
			ctx.StatusCode(http.StatusOK)
			return
		} else {
			ctx.StatusCode(http.StatusForbidden)
			return
		}
	}
}

func Cors(ctx iris.Context) {
	//后端解决跨域
	ctx.Header("Access-Control-Allow-Origin", "*")
	if ctx.Method() == "OPTIONS" {
		ctx.Header("Access-Control-Allow-Methods", "GET,POST,PUT,DELETE,PATCH,OPTIONS")
		ctx.Header("Access-Control-Allow-Headers", "Content-Type, Accept, Authorization")
		ctx.StatusCode(204)
		return
	}
	ctx.Next()
}

2.5 测试

①启动项目
# 在package.json目录下执行命令,运行前端
npm run dev

# 启动后端
go run main.go

前端:
在这里插入图片描述

后端:
在这里插入图片描述

②验证
  1. 访问浏览器
    在这里插入图片描述
  2. 点击登录按钮,请求后端
    在这里插入图片描述
  3. 登录成功,跳转用户中心页面
    在这里插入图片描述
Logo

开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!

更多推荐