Compare commits
No commits in common. "7bf0b5fb7f722bd2c165decdf2b65e3adeb915cb" and "3867b78d3fbb99251d0a71a1ac02b1dcb5a23366" have entirely different histories.
7bf0b5fb7f
...
3867b78d3f
@ -1,21 +1,16 @@
|
|||||||
## 初始化项目
|
## 初始化项目
|
||||||
|
|
||||||
```shell
|
```shell
|
||||||
npm init -y
|
npm init -y
|
||||||
```
|
```
|
||||||
|
|
||||||
## 选择打包编译工具
|
## 选择打包编译工具
|
||||||
|
|
||||||
webpack
|
webpack
|
||||||
|
|
||||||
vite(新项目个人推荐)
|
vite(新项目个人推荐)
|
||||||
|
|
||||||
## 选择技术栈(推荐使用typescript)
|
## 选择技术栈(推荐使用typescript)
|
||||||
|
|
||||||
vue 3 、vue-router 、axios/fetch 、pinia 、dayjs
|
vue 3 、vue-router 、axios/fetch 、pinia 、dayjs
|
||||||
|
|
||||||
## 安装依赖
|
## 安装依赖
|
||||||
|
|
||||||
```shell
|
```shell
|
||||||
npm install vue vue-router pinia dayjs
|
npm install vue vue-router pinia dayjs
|
||||||
yarn add vue vue-router pinia dayjs
|
yarn add vue vue-router pinia dayjs
|
||||||
@ -25,9 +20,7 @@ npm install vite @vitejs/plugin-vue typescript vue-tsc
|
|||||||
yarn add -D vite @vitejs/plugin-vue typescript vue-tsc
|
yarn add -D vite @vitejs/plugin-vue typescript vue-tsc
|
||||||
pnpm install vite @vitejs/plugin-vue typescript vue-tsc
|
pnpm install vite @vitejs/plugin-vue typescript vue-tsc
|
||||||
```
|
```
|
||||||
|
|
||||||
## html模板
|
## html模板
|
||||||
|
|
||||||
```html
|
```html
|
||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html lang="en">
|
<html lang="en">
|
||||||
@ -41,9 +34,7 @@ pnpm install vite @vitejs/plugin-vue typescript vue-tsc
|
|||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
```
|
```
|
||||||
|
|
||||||
## main.ts
|
## main.ts
|
||||||
|
|
||||||
```ts
|
```ts
|
||||||
import {createApp, defineComponent} from 'vue';
|
import {createApp, defineComponent} from 'vue';
|
||||||
|
|
||||||
@ -54,9 +45,7 @@ const App = defineComponent({
|
|||||||
const app = createApp(App)
|
const app = createApp(App)
|
||||||
app.mount('#vue-root-app')
|
app.mount('#vue-root-app')
|
||||||
```
|
```
|
||||||
|
|
||||||
## package.json的配置
|
## package.json的配置
|
||||||
|
|
||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
"name": "admin-fe",
|
"name": "admin-fe",
|
||||||
@ -71,111 +60,11 @@ app.mount('#vue-root-app')
|
|||||||
}
|
}
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|
||||||
## vite的配置
|
## vite的配置
|
||||||
|
|
||||||
[https://cn.vitejs.dev/guide/](https://cn.vitejs.dev/guide/)
|
|
||||||
|
|
||||||
```js
|
```js
|
||||||
import vue from '@vitejs/plugin-vue'
|
import vue from '@vitejs/plugin-vue'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
// 必须配置vue插件
|
// 必须配置vue插件
|
||||||
plugins: [vue()]
|
plugins: [vue()]
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
## 路由
|
|
||||||
|
|
||||||
#### 当页面比较少时,可以考虑直接使用if判断限制不使用组件
|
|
||||||
|
|
||||||
```vue
|
|
||||||
|
|
||||||
<template>
|
|
||||||
<div>
|
|
||||||
<h1>vue3 + vite + {{ username }} {{ currentPath }}</h1>
|
|
||||||
<input type="text" v-model="username">
|
|
||||||
|
|
||||||
<template v-if="currentPath == '/home'">
|
|
||||||
<Home/>
|
|
||||||
</template>
|
|
||||||
<User v-if="currentPath == '/user'"/>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script lang="ts">
|
|
||||||
import {ref} from "vue";
|
|
||||||
import Home from "./Home.vue";
|
|
||||||
import User from "./User.vue";
|
|
||||||
|
|
||||||
export default {
|
|
||||||
name: "App",
|
|
||||||
components: {User, Home},
|
|
||||||
setup() {
|
|
||||||
const username = ref<string>()
|
|
||||||
const currentPath = ref<string>(location.hash ? location.hash.substring(1) : '/home')
|
|
||||||
window.onhashchange = () => {
|
|
||||||
currentPath.value = location.hash ? location.hash.substring(1) : '/home'
|
|
||||||
}
|
|
||||||
return {
|
|
||||||
username,
|
|
||||||
currentPath,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style scoped>
|
|
||||||
|
|
||||||
</style>
|
|
||||||
```
|
|
||||||
|
|
||||||
#### 页面较多 则使用vue-router
|
|
||||||
|
|
||||||
[https://router.vuejs.org/zh/introduction.html](https://router.vuejs.org/zh/introduction.html)
|
|
||||||
|
|
||||||
```shell
|
|
||||||
// 1.定义路由
|
|
||||||
const routes = [
|
|
||||||
{
|
|
||||||
path: '路径',
|
|
||||||
component: 组件对象,
|
|
||||||
redirect: '要跳转的路径',
|
|
||||||
children:[ // 路由嵌套
|
|
||||||
{
|
|
||||||
path: '路径',
|
|
||||||
component: 组件对象,
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
]
|
|
||||||
// 2.创建路由对象
|
|
||||||
import {createRouter} from 'vue-router'
|
|
||||||
const router = createRouter({
|
|
||||||
routes: routes
|
|
||||||
})
|
|
||||||
// 3.使用路由
|
|
||||||
const app = createApp();
|
|
||||||
app.use(router); // 在应用使用router
|
|
||||||
```
|
|
||||||
|
|
||||||
显示路由及跳转
|
|
||||||
|
|
||||||
```vue
|
|
||||||
|
|
||||||
<template>
|
|
||||||
<router-view/>
|
|
||||||
<router-link to="要跳转的路径"></router-link>
|
|
||||||
</template>
|
|
||||||
```
|
|
||||||
|
|
||||||
### 前端分离的接口交互
|
|
||||||
|
|
||||||
#### 1.跨域
|
|
||||||
|
|
||||||
协议、访问域、端口只有一个不同都是跨域.
|
|
||||||
|
|
||||||
协议: http/https 端口: 冒号后面的数字
|
|
||||||
> 跨域除了上述原则之外,自定义请求头也会使跨域失败
|
|
||||||
|
|
||||||
#### 请求接口
|
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
<template>
|
<template>
|
||||||
<div>
|
<div>
|
||||||
<router-view/>
|
<h1>vue3 + vite + {{username}}</h1>
|
||||||
|
<input type="text" v-model="username">
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
@ -10,7 +11,10 @@ import {ref} from "vue";
|
|||||||
export default {
|
export default {
|
||||||
name: "App",
|
name: "App",
|
||||||
setup(){
|
setup(){
|
||||||
return {}
|
const username = ref<string>()
|
||||||
|
return {
|
||||||
|
username
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
@ -1,19 +0,0 @@
|
|||||||
:root {
|
|
||||||
--primary-color: #fff;
|
|
||||||
--primary-color-text: #333;
|
|
||||||
--font-size: 14px;
|
|
||||||
}
|
|
||||||
|
|
||||||
* {
|
|
||||||
margin: 0;
|
|
||||||
padding: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
body {
|
|
||||||
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, 'Source Han Sans SC', 'Microsoft YaHei', 'Microsoft YaHei UI', "Helvetica Neue", sans-serif;
|
|
||||||
scroll-behavior: smooth;
|
|
||||||
}
|
|
||||||
.container{
|
|
||||||
max-width: 1200px;
|
|
||||||
margin: auto;
|
|
||||||
}
|
|
@ -1,12 +1,5 @@
|
|||||||
import {createApp} from 'vue';
|
import {createApp} from 'vue';
|
||||||
import App from './App.vue'
|
import App from './App.vue'
|
||||||
import router from './router'
|
|
||||||
import {httpConfig} from "./util/http";
|
|
||||||
|
|
||||||
|
|
||||||
httpConfig.baseURL = "http://localhost:8080"
|
|
||||||
|
|
||||||
const app = createApp(App)
|
const app = createApp(App)
|
||||||
// 使用路由
|
|
||||||
app.use(router)
|
|
||||||
app.mount('#vue-root-app')
|
app.mount('#vue-root-app')
|
@ -1,10 +0,0 @@
|
|||||||
import {createRouter, createWebHistory} from 'vue-router'
|
|
||||||
import routes from "./routes";
|
|
||||||
|
|
||||||
const baseUrl = '' // 主要配置二级目录
|
|
||||||
const router = createRouter({
|
|
||||||
// 内部提供了 history 模式的实现。为了简单起见,我们在这里使用 hash 模式。
|
|
||||||
history: createWebHistory(baseUrl), // 此模式在部署时需要配置服务
|
|
||||||
routes
|
|
||||||
})
|
|
||||||
export default router
|
|
@ -1,22 +0,0 @@
|
|||||||
import {RouteRecordRaw} from "vue-router";
|
|
||||||
import Home from '../views/admin/Home.vue'
|
|
||||||
import Login from '../views/Login.vue'
|
|
||||||
import NotFound from '../views/NotFound.vue'
|
|
||||||
|
|
||||||
const routes: RouteRecordRaw[] = [
|
|
||||||
{
|
|
||||||
path: '/home',
|
|
||||||
component: Home
|
|
||||||
},
|
|
||||||
{
|
|
||||||
path: '/login',
|
|
||||||
component: Login
|
|
||||||
},
|
|
||||||
{
|
|
||||||
path:'/:pathMatch(.*)*',
|
|
||||||
component: NotFound
|
|
||||||
}
|
|
||||||
]
|
|
||||||
|
|
||||||
|
|
||||||
export default routes
|
|
@ -1,41 +0,0 @@
|
|||||||
export type HttpMethod = 'get' | 'post' | 'delete' | 'put'
|
|
||||||
|
|
||||||
export const httpConfig = {
|
|
||||||
baseURL: ''
|
|
||||||
}
|
|
||||||
export type ResponseModel<T> = {
|
|
||||||
code: number
|
|
||||||
message: string
|
|
||||||
data: T
|
|
||||||
trace?: string
|
|
||||||
}
|
|
||||||
|
|
||||||
class Http {
|
|
||||||
post<T>(url, data) {
|
|
||||||
return this.request<T>(url, 'post', data)
|
|
||||||
}
|
|
||||||
|
|
||||||
request<T>(url: string, method: HttpMethod, data: any = null) {
|
|
||||||
return new Promise<ResponseModel<T>>((resolve, reject) => {
|
|
||||||
|
|
||||||
fetch(httpConfig.baseURL + url, {
|
|
||||||
method,
|
|
||||||
body: JSON.stringify(data),
|
|
||||||
headers: {
|
|
||||||
'Content-Type': 'application/json;charset=utf-8'
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.then(res => res.json()) // 只要json的响应数据
|
|
||||||
.then((res: ResponseModel<T>) => {
|
|
||||||
if (res.code !== 0) {
|
|
||||||
reject(Error(res.message))
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
resolve(res.data)
|
|
||||||
}).catch(reject)
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const http = new Http();
|
|
||||||
export default http
|
|
@ -1,51 +0,0 @@
|
|||||||
<template>
|
|
||||||
<div class="login-wrapper">
|
|
||||||
<form @submit="onLogin">
|
|
||||||
<p>
|
|
||||||
<input placeholder="请输入账号" type="text" v-model="data.account">
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
<input placeholder="请输入密码" type="text" v-model="data.password">
|
|
||||||
{{ data.password }}
|
|
||||||
</p>
|
|
||||||
<button type="submit">登录</button>
|
|
||||||
</form>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script lang="ts">
|
|
||||||
import {reactive} from "vue";
|
|
||||||
import http from "../util/http";
|
|
||||||
|
|
||||||
export default {
|
|
||||||
name: "User",
|
|
||||||
setup() {
|
|
||||||
// vue 数据双向绑定(响应式原理)
|
|
||||||
// vue2 Object.definedProperty
|
|
||||||
// vue3 Proxy
|
|
||||||
const data = reactive({
|
|
||||||
account: '',
|
|
||||||
password: ''
|
|
||||||
})
|
|
||||||
|
|
||||||
function onLogin(e: Event) {
|
|
||||||
e.preventDefault()
|
|
||||||
http.post('/admin/user/login', data).then(result => {
|
|
||||||
console.log(result)
|
|
||||||
}).catch(err => {
|
|
||||||
console.log(err)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
return {
|
|
||||||
data, onLogin
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style scoped>
|
|
||||||
.login-wrapper {
|
|
||||||
|
|
||||||
}
|
|
||||||
</style>
|
|
@ -1,18 +0,0 @@
|
|||||||
<template>
|
|
||||||
<h1>Not Found</h1>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
import {useRoute} from 'vue-router'
|
|
||||||
export default {
|
|
||||||
name: "NotFound",
|
|
||||||
setup(){
|
|
||||||
const r = useRoute();
|
|
||||||
console.log(JSON.stringify(r))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style scoped>
|
|
||||||
|
|
||||||
</style>
|
|
@ -1,14 +0,0 @@
|
|||||||
<template>
|
|
||||||
<h1>Home</h1>
|
|
||||||
<router-link to="/user">User</router-link>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
export default {
|
|
||||||
name: "Home"
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style scoped>
|
|
||||||
|
|
||||||
</style>
|
|
Loading…
x
Reference in New Issue
Block a user