1. 使用腳手架創建項目
1.1 準備工作
- ? ? ? ? win+R,在彈出的數據框中輸入cmd,數據命令查看node以及npm版本?
- ? ? ? ? 下載vue cli
1.2 創建項目
1.2.1 創建一個英文目錄文件夾,cmd打開命令命令提示符
1.2.2 vue ui命令打開控制臺
1.2.3 創建項目
? ? ? ? 創建成功
?1.3 項目結構
1.4 將項目在VSCode打開,終端運行頁面
? ? ? ? ?使用命令npm run serve命令打開
1.5 修改服務端口號
? ? ? ? 在vue.config.js中修改服務端口號,防止與后端tomcat端口沖突
const { defineConfig } = require('@vue/cli-service')
module.exports = defineConfig({transpileDependencies: true,devServer:{port: 7070}
})
? ? ? ? ?保存文件,重啟項目端口號修改完畢
2. vue基礎回顧
2.1 文本插值
<template><div class="hello">{{ name }}</div>
</template><script>
export default {data() {return {name: 'I LOVE YOU'}}
}
</script><!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>
</style>
2.2 屬性綁定
? ? ? ? 為標簽的屬性綁定data方法中返回的屬性
<template><div class="hello">{{ name }}<input type="name" :value="age"></div>
</template><script>
export default {data() {return {name: 'I LOVE YOU',age: 18}}
}
</script><!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>
</style>
2.3 事件綁定
<template><div class="hello">{{ name }}<input type="name" :value="age"><!-- 點擊事件 --><button @click="dianji()">點擊</button></div>
</template><script>
export default {data() {return {name: 'I LOVE YOU',age: 18}},methods: {dianji() {alert('點擊了')}}
}
</script><!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>
</style>
2.4 雙向綁定
? ? ? ? 通過v-model將數據區的數據與輸入框數據雙向綁定
<template><div class="hello">{{ name }}<input type="name" :value="age"><!-- 點擊事件 --><button @click="dianji()">點擊</button><input type="text" v-model="name"></div>
</template><script>
export default {data() {return {name: 'I LOVE YOU',age: 18}},methods: {dianji() {alert('點擊了')}}
}
</script><!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>
</style>
2.5 條件渲染
<template><div class="hello"><div v-if="sex==1">男</div><div v-else-if="sex==2">女</div><div v-else>未知</div></div>
</template><script>
export default {data() {return {sex:2}},methods: {}
}
</script><!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>
</style>
2.6 axios
? ? ? ? Axios是一個基于promise的網絡請求庫,作用于瀏覽器和node.js中,用于發ajax異步請求,實現前后端交互
2.6.1 下載axios
npm install axios
2.6.2 在項目中使用axios
2.6.3 axios的API
- url:請求路徑
- data:請求體數據,最常見的是JSON格式
- config:配置對象,可以設置查詢參數,請求頭信息
?2.6.4 axios請求的跨域問題
? ? ? ? 正常情況下,前端數據一個服務,后端屬于一個服務,在不同的域里,所以會出現跨域問題,解決方法就是在vue.config.js文件中配置代理:
<template><button @click="request11()"></button></div>
</template><script>
// 導入axios
import axios from 'axios'export default {data() {return {sex:2}},methods: {request11(){axios.post('http://localhost:8080/user/login',{username:'admin', // json數據password:'123456'}).then(res=>{ // 成功回調console.log(res.data)}).catch(err=>{ // 錯誤回調console.log(err)})}}
}
</script>
const { defineConfig } = require('@vue/cli-service')
module.exports = defineConfig({transpileDependencies: true,devServer:{port: 7070,proxy:{// 配置請求代理,用于將特定請求轉發到后端服務器,解決跨域問題'/api':{// 將請求轉發到的目標服務器地址target:'http://localhost:8080',changeOrigin:true, // 是否更改請求的來源,通常用于處理虛擬主機的情況pathRewrite:{'^/api':'' // 移除請求路徑中的 '/api' 前綴,以便目標服務器正確處理請求}}}}
})
2.6.5 發送請求
- 方式一
<template><div class="hello"><div v-if="sex==1">男</div><div v-else-if="sex==2">女</div><div v-else>未知</div><button @click="request11()">按鈕</button></div>
</template><script>
// 導入axios
import axios from 'axios'export default {data() {return {sex:2}},methods: {request11(){ axios.post('http://localhost:8080/user/login',{username:'admin', // json數據password:'123456'}).then(res=>{ // 成功回調console.log(res.data)}).catch(err=>{ // 錯誤回調console.log(err)})},req(){axios.get('http://localhost:8080/user/getUserById',{// 攜帶請求頭headers:{token:'xxxxxxxxxxxxxxxxxxxxxxxxxx'}}).then(res=>{console.log(res.data)}).catch(err=>{console.log(err)})}}
}
</script><!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>
</style>
- 方式二
<button @click="handleSend()"></button>handleSend(){axios({url:'http://localhost:8080/user/login',method:'post',data:{username:'admin',password:'<PASSWORD>'}}).then(res=>{console.log(res.data)axios({url:'http://localhost:8080/user/info',method:'get',headers:{token:res.data.data.token}})}).catch(err=>{console.log(err)})}
3. 路由Vue-Router
? ? ? ? vue屬于單頁面應用,路由的作用就是根據瀏覽器路徑不同,用不同的視圖組件替換掉這個頁面內容。實現不同的路徑,對應不同的頁面展示
3.1 創建帶有路由的項目
? ? ? ? 創建好之后,package.json中有vue-router的依賴
? ? ? ? main.js中引入了router,說明這個項目具備了路由功能
3.2 路由配置
路由組成:
- VueRouter:路由器,根據路由請求在路由視圖中動態渲染對應的視圖組件
- <router-link>:路由鏈接組件,瀏覽器會解析成<a>
- <router-view>:路由視圖組件,用來展示與路由路徑匹配的視圖組件
index.js中維護路由
- ?App.vue,<router-link>標簽生成超鏈接
<router-view>:路由視圖組件不能刪掉!!!
???????路由視圖組件起到的是占位符的作用
3.3 路由跳轉
有兩種方式:
- 標簽式
- 編程式
標簽式就是上面演示的那種,編程式如下:
<template><div id="app"><nav><router-link to="/">Home</router-link> |<router-link to="/about">About</router-link><input type="button" value="編程式跳轉" @click="jump()"></nav><!-- <router-view>:路由視圖組件 --><router-view/></div>
</template><script>
export default {methods: {jump() {this.$router.push('/about')}}
}
</script><style>
#app {font-family: Avenir, Helvetica, Arial, sans-serif;-webkit-font-smoothing: antialiased;-moz-osx-font-smoothing: grayscale;text-align: center;color: #2c3e50;
}nav {padding: 30px;
}nav a {font-weight: bold;color: #2c3e50;
}nav a.router-link-exact-active {color: #42b983;
}
</style>
? ? ? ? 當用戶輸入的路徑不對時,都會重定向到404頁面,一張圖告訴你如何重定向到不存在的頁面:
4. 嵌套路由
? ? ? ? 嵌套路由是組件內要切換內容,就需要用到嵌套路由(子路由)
4.1 案例
????????以以下這個案例給大家分析:
實現步驟:
1)安裝并導入elementui,實現頁面布局(container布局容器)--ContainerView.vue
- 下載
使用命令下載elementui:npm i element-ui -S
- 在main.js中導入elementui
import Vue from 'vue'
import App from './App.vue'
import router from './router'
// 導入elementui
import ElementUI from 'element-ui';
import 'element-ui/lib/theme-chalk/index.css';Vue.config.productionTip = false
// 全局使用elementui
Vue.use(ElementUI);new Vue({router,render: h => h(App)
}).$mount('#app')
- ?創建視圖組件
<template><el-container><el-header>Header</el-header><el-container><el-aside width="200px">Aside</el-aside><el-main>Main</el-main></el-container>
</el-container>
</template><script>
export default {}
</script><style>.el-header, .el-footer {background-color: #B3C0D1;color: #333;text-align: center;line-height: 60px;}.el-aside {background-color: #D3DCE6;color: #333;text-align: center;line-height: 200px;}.el-main {background-color: #E9EEF3;color: #333;text-align: center;line-height: 160px;}body > .el-container {margin-bottom: 40px;}.el-container:nth-child(5) .el-aside,.el-container:nth-child(6) .el-aside {line-height: 260px;}.el-container:nth-child(7) .el-aside {line-height: 320px;}
</style>
- 在main.js中配置路由跳轉
2)提供子視圖組件,用于效果展示
- P1View.vue
<template><div>這是P1View</div>
</template><script>
export default {}
</script><style>
</style>
- ?P2View.vue
<template><div>這是P2View</div>
</template><script>
export default {}
</script><style>
</style>
- ?P3View.vue
<template><div>這是P3View</div>
</template><script>
export default {}
</script><style>
</style>
3)在src/router/index.js中配置路由映射規則(嵌套路由配置)
import Vue from 'vue'
import VueRouter from 'vue-router'
import HomeView from '../views/HomeView.vue'Vue.use(VueRouter)const routes = [// 維護路由表,某個路由路徑對應哪個視圖組件{path: '/',name: 'home',// 靜態加載component: HomeView},{path: '/about',name: 'about',// route level code-splitting// this generates a separate chunk (about.[hash].js) for this route// which is lazy-loaded when the route is visited.// 懶加載component: () => import(/* webpackChunkName: "about" */ '../views/AboutView.vue')},{path: '/test',component: () => import( '../views/404View.vue')},{path: '/c',component: () => import( '../views/container/containerView.vue'),// 重定向到p1redirect: '/c/p1',children:[{path: '/c/p1',component: () => import( '../views/container/P1View.vue')},{path: '/c/p2',component: () => import( '../views/container/P2View.vue')},{path: '/c/p3',component: () => import( '../views/container/P3View.vue')}]},{path:"*",redirect: '/404'}
]const router = new VueRouter({routes
})export default router
4)在布局容器視圖中添加<router-view>,實現子視圖組件展示
<template><el-container><el-header>Header</el-header><el-container><el-aside width="200px">Aside</el-aside><el-main><!-- 占位符 --><router-view/></el-main></el-container>
</el-container>
</template>
5)在布局容器視圖中添加<router-link>,實現路由請求
<template><el-container><el-header>Header</el-header><el-container><el-aside width="200px"><!-- 路由請求:生成超鏈接 --><router-link to="/c/p1">P1</router-link><br><router-link to="/c/p2">P2</router-link><br><router-link to="/c/p3">P3</router-link></el-aside><el-main><!-- 占位符 --><router-view/></el-main></el-container>
</el-container>
</template><script>
export default {}
</script><style>.el-header, .el-footer {background-color: #B3C0D1;color: #333;text-align: center;line-height: 60px;}.el-aside {background-color: #D3DCE6;color: #333;text-align: center;line-height: 200px;}.el-main {background-color: #E9EEF3;color: #333;text-align: center;line-height: 160px;}body > .el-container {margin-bottom: 40px;}.el-container:nth-child(5) .el-aside,.el-container:nth-child(6) .el-aside {line-height: 260px;}.el-container:nth-child(7) .el-aside {line-height: 320px;}
</style>
5. 狀態管理vuex
5.1 介紹
- vuex是一個專門為Vue.js應用程序開發的狀態管理庫
- vuex可以在多個組件之間共享數據,并且共享的數據是響應式的,即數據的變更能即使渲染到模板
- vuex采用集中式存儲管理所有組件的狀態
5.2 vuex核心概念
5.3 使用方式
5.3.1 創建攜帶vuex的項目
- index.js
import Vue from 'vue'
import Vuex from 'vuex'Vue.use(Vuex)// 集中管理多個組件共享的數據
export default new Vuex.Store({state: {},getters: {},mutations: {},actions: {},modules: {}
})
- main.js
import Vue from 'vue'
import App from './App.vue'
import store from './store'Vue.config.productionTip = falsenew Vue({store, // 創建vuex實例render: h => h(App)
}).$mount('#app')
5.3.2 定義展示共享數據
5.3.3 在mutations中定義函數,修改共享數據
5.3.4 在actions中定義函數,用于調用mutation
// import { set } from 'core-js/core/dict'
import Vue from 'vue'
import Vuex from 'vuex'
import axios from 'axios'Vue.use(Vuex)// 集中管理多個組件共享的數據
export default new Vuex.Store({// 共享數據state: {name:'未登錄游客'},getters: {},// 修改共享數據只能通過mutation實現,必須是同步操作mutations: {setName(state, name){state.name = name}},// 封裝異步操作,不能直接修改共享數據,只能通過mutation來實現actions: {setNameByAxios(context){axios({url:"/api/getUserInfo",method:"POST",data:{username:"admin",password:"123456"}}).then(res=>{if(res.data.code == 1){// 異步請求后,需要修改共享數據,只能通過mutation來實現// 在action中調用mutation中定義的setName方法context.commit("setName",res.data.username)}})}},modules: {}
})
? ? ? ?在vue.config.js 配置重定向
const { defineConfig } = require('@vue/cli-service')
module.exports = defineConfig({transpileDependencies: true,devServer: {port: 8081,proxy: {// 將含有/api的字段重定向成 http://localhost:8080'/api': {target: 'http://localhost:8080',changeOrigin: true,pathRewrite: {// 重寫路徑,將含有/api的字段替換成 (空)'^/api': ''}}}}
})
6. TypeScript
6.1 TypeScript介紹
TypeScript是微軟推出的開源語言
TypeScript是JavaScript的超集(js有的ts都有)
TypeScript在js基礎上做了類型支持
TypeScript文件擴展名為ts
TypeScript可編譯成標準的JavaScript,并且在編譯時進行類型檢查
6.2 TypeScript常用類型
6.2.1 創建攜帶TypeScripe的項目
????????類型標注的位置:
- 標注變量
- 標注參數
- 標注返回值
6.2.2 字符串類型、數據類型、布爾類型
// 字符串類型
let str: string = 'I LOVE YOU 1314';// 數字類型
let num: number = 1314;// 布爾類型
let bool: boolean = true;console.log(str, num, bool);console.log("-------------------------");// 字面量類型
function printTest(s:string,alignment:'left'|'center'|'right'){console.log(s,alignment)
}
// 調用函數
printTest('I LOVE YOU 1314','left');console.log("-------------------------");// interface 接口類型
interface Cat{name:string;// ? 可選屬性age?:number;
}
// 定義變量,并且指定為Cat類型
const c1:Cat = {name:'Tom',age:10}
const c2:Cat = {name:'Tom'}console.log("-------------------------");// class類 - 基本使用
class User{name:string;constructor(name:string){this.name = name;}study(){console.log('I am '+this.name);}
}
// 使用User類型
const user = new User('Tom');// 輸出類中的屬性
console.log(user.name);// 調用類中的方法
user.study();console.log("-------------------------");// class類 - 實現接口
interface Animal{name:string;eat():void;
}// 定義一個類實現Animal接口
class Bird implements Animal{name:string;constructor(name:string){this.name = name;}eat():void{console.log('I am eating');}
}
// 創建類型為Bird的對象
const bird = new Bird('小鳥');
console.log(bird.name);
bird.eat();// class類 - 繼承Bird類
class Parrot extends Bird{say(){console.log(this.name+' can say');}
}
const parrot = new Parrot('鸚鵡');
console.log(parrot.name);
parrot.eat();
parrot.say();