創(chuàng)建項目
npm create vue@latest
cd demo
npm install
npm run dev
插值語法
{{ name }}
指令語法
// 單向數(shù)據(jù)綁定
v-bind:href="url"
:href="url"
// 雙向數(shù)據(jù)綁定
v-model:value = "name"
el和data的兩種寫法
第一種寫法
const v = new vue({
el:"#root",
//data的第一種寫法:對象式
data:{
name:"尚硅谷"
}
//data的第二種寫法:函數(shù)式
data (){
return {
name: '尚硅谷'
}
}
})
第二種寫法
v.$mount("#root")
MVVM模型
M:模型(Model),對應data中的數(shù)據(jù)
V:視圖(View),模板
VM: 視圖模型(ViewModel),Vue實例對象
vue中的數(shù)據(jù)代理
- vue中的數(shù)據(jù)代理:通過vm對象來代理data對象中屬性的操作(讀/寫)
- vue中數(shù)據(jù)代理的好處:更加方便的操作data中的數(shù)據(jù)
- 基本原理:通過Object.defineProperty()把data對象中所有屬性添加到vm上。為每一個添加到vm上的屬性都指定一個getter/setter。在getter/setter內(nèi)部去操作(讀/寫)data中對應的屬性。
vue中的事件修飾符
prevent 阻止默認事件
stop 阻止事件冒泡
once 事件只觸發(fā)一次
capture 使用事件的捕獲模式
self 只有event.target是當前操作的元素時才觸發(fā)事件
passive 事件的默認行為立即執(zhí)行,無需等待事件回調(diào)執(zhí)行完畢
鍵盤事件 keyup keydown
vue中常用的按鍵別名:
回車 enter
刪除 delete
退出 esc
空格 space
換行 tab (特殊,必須配合keydown去使用)
上 up
下 down
左 left
右 right
e.key e.keyCode
Vue.cofig.keyCodes.自定義鍵名 = 鍵碼, 可以去定制按鍵別名
computed 和watch之間的區(qū)別
1.computed能完成的功能,watch都可以完成。
2.watch能完成的功能,computed不一定能完成,例如:watch可以進行異步操作。
兩個重要的小原則:
1.所被vue管理的函數(shù),最好寫成普通函數(shù),這樣this的指向才是vm 或 組件實例對象
2.所有不被vue所管理的函數(shù)(定時器的回調(diào)函數(shù)、ajax的回調(diào)函數(shù)等),最好寫成箭頭函數(shù),這樣this的指向才是vm 或 組件實例對象。
綁定class樣式
字符串寫法, :class="mood" 適用于:樣式的類名不確定,需要動態(tài)指定
數(shù)組寫法,:class="[a,b,c]" 適用于:要綁定的樣式個數(shù)不確定、名字也不確定
對象寫法,:class="classObj" 適用于:要綁定的個數(shù)確定、名字也確定,但要動態(tài)決定用不用
條件渲染
1.v-if
寫法:
(1) v-if="表達式"
(2) v-else-if="表達式"
(3) v-else="表達式"
適用于:切換頻率較低的場景
特點:不展示的DOM元素直接被移除
注意:v-if 可以和 v-else-if、v-else一起使用,但要求結構不能被“打斷”。
2.v-show
寫法:v-show="表達式"
適用于:切換頻率較高的場景
特點:不展示的DOM元素未被移除,僅僅是使用樣式隱藏掉
3.備注:使用v-if時,元素可能無法獲取到,而使用v-show一定可以獲取到
列表渲染
v-for指令
1.用于展示列表數(shù)據(jù)
2.語法:v-for="(item, index) in xxx" :key="yyy"
3.可遍歷:數(shù)組、對象、字符串(用的很少)、指定次數(shù)(用的很少)
面試題:react、vue中的key有什么作用?(key的內(nèi)部原理)
1.虛擬DOM中key的作用
key是虛擬DOM對象的標識,當狀態(tài)中的數(shù)據(jù)發(fā)生變化時,vue會根據(jù)【新數(shù)據(jù)】生成的【新的虛擬DOM】,隨后vue進行【新虛擬DOM】與【舊虛擬DOM】的差異比較,比較規(guī)則如下:
2.對比規(guī)則:
(1)舊虛擬DOM中找到了新虛擬DOM相同的key:
1.若虛擬DOM中內(nèi)容沒變,直接使用之前的真實DOM!
2.若虛擬DOM中內(nèi)容變了,則生成新的真實DOM,隨后替換掉頁面中之前的真實DOM。
(2).舊虛擬DOM中未找到與新虛擬DOM相同的key
創(chuàng)建新的真實DOM,隨后渲染到到頁面。
-
用index作為key可能會引發(fā)的問題:
- 若對數(shù)據(jù)進行:逆序添加、逆序刪除等破壞順序操作:
會產(chǎn)生沒有必要的真實DOM更新 == >界面效果沒問題,但效率低。
2.如果結構中還包含輸入類的DOM:
會產(chǎn)生錯誤DOM更新 == >界面有問題。
- 若對數(shù)據(jù)進行:逆序添加、逆序刪除等破壞順序操作:
開發(fā)中如何選擇key ?:
1.最好使用每條數(shù)據(jù)的唯一標識作為key,比如id、手機號、身份證號、學號等唯一值。
2.如果不存在對數(shù)據(jù)的逆序添加、逆序刪除等破壞順序操作,僅用于渲染列表用于展示,
使用index作為key是沒有問題的。
收集表單數(shù)據(jù)
若 :< input type="text"/>,則v-model收集的是value值,用戶輸入的就是value值。
若 :< input type="radio"/>,則v-model收集的是value值,且要給標簽配置value值。
若 :< input type="checkbox"/>
1.沒有配置input的value屬性,那么收集的就是checked(勾選or 未勾選,是布爾值)
2.配置input的value屬性:
(1)v-mode1的初始值是非數(shù)組,那么收集的就是checked(勾選or 未勾選,是布爾值)
(2)v-mode1的初始值是數(shù)組,那么收集的的就是value組成的數(shù)組
備注:v-model的三個修飾符:
lazy:失去焦點再收集數(shù)據(jù)
number:輸入字符串轉(zhuǎn)為有效的數(shù)字
trim:輸入首尾空格過濾
v-cloak指令(沒有值)
1.本質(zhì)是一個特殊屬性,vue實例創(chuàng)建完畢并接管容器后,會刪掉v-cloak屬性
2.使用css配合v-cloak可以解決網(wǎng)速慢時頁面展示出{{xxx}}的問題
v-once指令
1.v-once所在節(jié)點在初次動態(tài)渲染后 ,就視為靜態(tài)內(nèi)容了
2.以后數(shù)據(jù)的改變不會引起v-once所在結構的更新,可以用于優(yōu)化性能
v-pre
1.跳過其所在節(jié)點的編譯過程
2.可利用它跳過:沒有使用指令語法、沒有使用插值語法的節(jié)點,會加快編譯。
自定義指令
v-big-number="n"
'big-number'(){}
this都是window
需求1:定義一個v-big指令,和v-text功能類似,但會把綁定的數(shù)值放大10倍
big函數(shù)何時會被調(diào)用?
1.指令與元素成功綁定時(一上來)2.指令所在的模板被重新解析時。

<div id="test5">
<h2>當前n的值是 <span v-text="n"></span></h2>
<h2>放大10倍后n的值是 <span v-big="n"></span></h2>
<button @click="n++">點我n+1</button>
</div>
<script>
export default {
data(){
return {
n:1
}
},
directives: {
big(element,binding){
element.innerText = binding.value * 10
}
}
}
</script>
需求2:定義一個v-fbind指令,和v-bind功能類似,但可以讓其所綁定的input元素默認獲取焦點
<input type="text" v-fbind:value="n">
<script>
export default {
data(){
return {
n:1
}
},
directives: {
fbind: {
//指令與元素成功綁定時(一上來)
bind(element,binding){
element.value = binding.value
},
//指令所在元素被插入頁面時
inserted(element,binding){
element.focus()
},
//指令所在的模板被重新解析時
update(element,binding){
element.value = binding.value
}
}
}
}
</script>
定義全局指令
Vue.directive('fbind',{
//指令與元素成功綁定時(一上來)
bind(element,binding){
element.value = binding.value
},
//指令所在元素被插入頁面時
inserted(element,binding){
element.focus()
},
//指令所在的模板被重新解析時
update(element,binding){
element.value = binding.value
}
})
Vue.directive('big', function(element, binding){
element.innerText = binding.value * 10
})

生命周期
vue完成模板的解析并把真實的DOM元素放入頁面后(掛載完畢)調(diào)用mounted
生命周期:
1.又名:生命周期回調(diào)函數(shù)、生命周期函數(shù)、生命周期鉤子
2.是什么:vue在關鍵時刻幫我們調(diào)用的一些特殊名稱的函數(shù)
3.生命周期函數(shù)的名字不可更改,但函數(shù)的具體內(nèi)容是程序員根據(jù)需求編寫的
4.生命周期函數(shù)中的this指向是vm或組件實例對象
beforeCreate 此時:無法通過vm訪問到data中的數(shù)據(jù)、methods中的方法
created 此時:可以通過vm訪問到data中的數(shù)據(jù)、methods中配置的方法
beforeMount 此時:1.頁面呈現(xiàn)的是未經(jīng)Vue編譯的DOM結構 2.所有對DOM的操作,最終都不奏效
mounted 此時:1.頁面中呈現(xiàn)的是經(jīng)過Vue編譯的DOM 2.對DOM的操作均有效(盡可能避免)。至此初始化過程結束,一般在此進行:開啟定時器、發(fā)送網(wǎng)絡請求、訂閱消息、綁定自定義事件等初始化操作
beforeUpdate 此時:數(shù)據(jù)是新的,但頁面是舊的,即:頁面尚未和數(shù)據(jù)保持同步
updated 此時:數(shù)據(jù)是新的,頁面也是新的,即:頁面和數(shù)據(jù)保持同步
beforeDestroy 此時:vm中所有的:data、methods、指令等待,都處于可用狀態(tài),馬上要執(zhí)行銷毀過程,一般在此階段:關閉定時器、取消訂閱消息、解綁自定義事件等收尾操作
destroyed
activated 路由組件被激活時觸發(fā)
deactivated 路由組件失活時觸發(fā)
nextTick
vue3中 beforeUnmount和unmounted代替beforeDestroy 和destroyed
常用的生命周期鉤子:
1.mounted/發(fā)送ajax請求、啟動定時器、綁定自定義事件、訂閱消息等【初始化操作】。
2.beforeDestroy:清除定時器、解綁自定義事件、取消訂閱消息等【收尾工作】。
關于銷毀Vue實例
1.銷毀后借助Vue開發(fā)者工具看不到任何信息。
2.銷毀后自定義事件會失效,但原生DOM事件依然有效。
3.一般不會再beforeDestroy操作數(shù)據(jù),因為即便操作數(shù)據(jù),也不會再觸發(fā)更新流程了。
關于VueComponent:
1.school組件本質(zhì)是一個名為VueComponent的構造函數(shù),且不是程序員定義的,是Vue.extend生成的。
2.我們只需要寫<school/>或<school></school>,Vue解析時會幫我們創(chuàng)建schoo1組件的實例對象,
→即Vue幫我們執(zhí)行的:new·VueComponent(options)。
3.特別注意:每次調(diào)用Vue.extend,返回的都是一個全新的VueComponent !!!!
4.關于this指向:
(1).組件配置中:
data函數(shù)、methods中的函數(shù)、watch中的函數(shù)、computed中的函數(shù) 它們的this均是【VueComponent實例對象】。
(2).new Vue()配置中:
data函數(shù)、methods中的函數(shù)、watch中的函數(shù)、computed中的函數(shù) 它們的this均是【Vue實例對象】。
5.VueComponent的實例對象,以后簡稱vc(也可稱之為:組件實例對象)。
Vue的實例對象,以后簡稱vm。

vue腳手架
Vue腳手架隱藏了所有webpace相關的配置,若想查看具體的webpace配置,請執(zhí)行vue inspect > outputs.js
vue3中報錯
ref屬性
1.用來給元素或子組件注冊引用信息(id的替代者)
2.應用在html標簽上獲取的是真是DOM元素,應用在組件標簽上是組件實例對象(vc)
3.使用方式:
打標識: <h1 ref="xxx">....</h1> 或 <School ref="xxx"></School>
獲?。?this.$refs.xxx
配置項props
功能:讓組件接收外部傳過來的數(shù)據(jù)
(1).傳遞數(shù)據(jù):
<Demo name="xxx"/>
(2).接收數(shù)據(jù):
第一種方式(只接收):
props: ['name' ]
第二種方式(限制類型):
props : {
name : Number
}
第三種方式(限制類型、限制必要性、指定默認值):
props : {
name : {
type:String,//類型
required:true,//必要性
default:'老王’//默認值
}
備注:props是只讀的,Vue底層會監(jiān)測你對props的修改,如果進行了修改,就會發(fā)出警告,
若業(yè)務需求確實需要修改,那么請復制props的內(nèi)容到data中一份,然后去修改data中
的數(shù)據(jù)。
mixin混入
功能:可以把多個組件共用的配置提取成一個混入對象
使用方式:
第一步定義混合,例如:
{
data(){ .... },
methods : { .... }
......
}
第二步使用混入,例如:
(1).全局混入:Vue.mixin(xxx)
(2).局部混入:mixins:['xxx']
vue插件
功能:用于增強Vue
本質(zhì):包含install方法的一個對象,install的第一個參數(shù)是Vue,第二個以后的參數(shù)是插件使用者傳遞的數(shù)
據(jù)。
定義插件:
對象.install=function(Vue, options){
// 1. 添加全局過濾器
Vue.filter( .... )
// 2. 添加全局指令
Vue.directive( .... )
//3. 配置全局混入(合)
Vue.mixin( .... )
// 4. 添加實例方法
Vue.prototype. $myMethod = function () { ... }
Vue. prototype. $myProperty = xxxx
使用插件:Vue.use()
scoped樣式
作用:讓樣式在局部生效,防止沖突。
寫法:<style scoped>
瀏覽器本地存儲
localStorage
<h2>localStorage</h2>
<button onclick="saveData()">點我保存一個數(shù)據(jù)</button>
<button onclick="readData()">點我讀取一個數(shù)據(jù)</button>
<button onclick="deleteData()()">點我刪除一個數(shù)據(jù)</button>
<button onclick="deleteAllData()">清空數(shù)據(jù)</button>
<script>
let p = {name:'張三',age:18}
function saveData(){
localStorage.setItem('msg','hello')
localStorage.setItem('person',JSON.stringify(p))
}
function readData(){
const p = localStorage.getItem('person')
console.log(JSON.parse(p))
}
function deleteData(){
localStorage.removeItem('msg')
}
function deleteAllData(){
localStorage.clear()
}
</script>
sessionStorage
與localStorage用法一樣
sessionStorage存儲的內(nèi)容會隨著瀏覽器窗口關閉而消失。
localStorage存儲的內(nèi)容需要手動清除才會消失
組件自定義事件綁定

this.$emit('事件名')
組件自定義事件解綁
this.off(['事件1','事件2']) //解綁多個自定義事件
this.$off() //解綁所有的自定義事件

全局事件總線:任意組件間通信
Vue.prototype.x = 111 報錯,替換為
app.config.globalProperties.x = 111

消息訂閱與發(fā)布
vue3使用 mitt插件 ,參考案例:如何在Vue3中使用事件總線_vue3事件總線-CSDN博客
1.訂閱消息:消息名
2.發(fā)布消息:消息內(nèi)容
nextTick

solt插槽 vue3寫法
默認插槽
<slot></slot>
具名插槽
<slot name="center"></slot>
//v-slot:center 可簡寫為 #center
<template v-slot:center>
<img src="http://s3.ax1x.com/2021/01/16/srJlq0.jpg" alt="">
</template>
舊寫法

作用域插槽
<slot :game="game"></slot>
<games title="游戲" >
<template v-slot="atguigu">
<ul>
<li v-for="(item,index) in atguigu.game" :key="index">{{item}}</li>
</ul>
</template>
</games>
舊寫法


vuex
概念:專門在vue中實現(xiàn)集中式狀態(tài)(數(shù)據(jù))管理的一個vue插件,對vue應用中多個組件的共享狀態(tài)進行集中式的管理(讀/寫),也是一種組件間通信的方式,且適用于任意組件間通信
state
mutations
actions
getters
modules
開啟命名空間
namespaced:true,

路由
1.路由就是一組key-value的對應關系
2.多個路由,需要經(jīng)過路由器的管理
vue-router的理解
vue的一個插件庫,專門用來實現(xiàn)SPA應用心
對SPA應用的理解
- 單頁Web應用(single page web application, SPA)。
- 整個應用只有一個完整的頁面。
- 點擊頁面中的導航鏈接不會刷新頁面,只會做頁面的局部更新。
- 數(shù)據(jù)需要通過ajax請求獲取。
路由的理解
什么是路由?
- 一個路由就是一組映射關系(key-value)
- key 為路徑,value可能是function或componente
路由分類
- 后端路由:
- 理解:value是function,用于處理客戶端提交的請求。
- 工作過程:服務器接收到一個請求時,根據(jù)請求路徑找到匹配的函數(shù)來處
理請求,返回響應數(shù)據(jù)?!?/li>
- 前端路由:
- 理解:value是component,用于展示頁面內(nèi)容。
- 工作過程:當瀏覽器的路徑改變時,對應的組件就會顯示。
多級路由(多級路由)
1.配置路由規(guī)則,使用children配置項:
routes : [
{
path:'/about',
component : About,
},
{
path: '/home',
component : Home, //通過children配置子級路由
children:[
{
path:'new', //此處一定不要寫:/news
component : News,
}
{
path:'message',//此處一定不要寫:/message
component :Message
}
]
}
]
2.跳轉(zhuǎn)(要寫完整路徑):
<router-link to="/home/new9'>News</router-link>
路由的query參數(shù)
1.傳遞參數(shù)
<!-- 跳轉(zhuǎn)并攜帶query參數(shù),to的字符串寫法 -- >
<router-link:to="/home/message/detail?id=666&title=你好">跳轉(zhuǎn)</router-link>
<!-- 跳轉(zhuǎn)并攜帶query參數(shù),to的對象寫法 -- >
<router-link
: to="{
path: '/home/message/detail',
query : {
id:666,
title:'你好'
}
>跳轉(zhuǎn)</router-link>
2.接收參數(shù):
$route.query.id
$route.query.title
命名路由
1.作用:可以簡化路由的跳轉(zhuǎn)
2.如何使用:
1.給路由命名:
{
path:'/demo',
component:Demo,
children:[
{
path:'test',
component:Test,
children:[
{
name:'hello',
path:'welcome',
component:Hello
}
]
}
]
}
2.簡化跳轉(zhuǎn)
//簡化前,需要寫完整的路徑
<router-link to="/demo/test/welcome">跳轉(zhuǎn)</router-link>
//簡化后,直接通過名字跳轉(zhuǎn)
<router-link :to="{name:'hello'}">跳轉(zhuǎn)</router-link>
路由的params參數(shù)
1.配置路由,聲明接受params參數(shù)
{
path:'/demo',
component:Demo,
children:[
{
path:'test',
component:Test,
children:[
{
name:'hello',
path:'welcome/:id/:title', //使用占位符聲明接收params參數(shù)
component:Hello
}
]
}
]
}
2.傳遞參數(shù)
//跳轉(zhuǎn)并攜帶params參數(shù),to的字符串寫法
<router-link :to="`/demo/test/welcome/${m.id}/${m.title}`">{{ m.title }}</router-link>
//跳轉(zhuǎn)并攜帶params參數(shù),to的對象寫法
<router-link :to="{
name:'hello',
params:{
id:m.id,
title:m.title
}
}">{{ m.title }}</router-link>
特別注意:路由攜帶params參數(shù)時,若使用to的對象寫法,則不能使用path配置項,必須使用name配置!
3.接收參數(shù):
$route.params.id
路由的props配置
作用:讓路由組件更方便的收到參數(shù)
{
name:'detail',
path:'detail/:id',
component:Detail,
//props的第一種寫法,值為對象,該對象中的所有key-value都會以props的形式傳遞給detail組件
// props:{a:1,b:'hello'}
//props的第二種寫法,值為布爾值,若布爾值為真,就會把該路由組件收到的所有params參數(shù),以props的形式傳遞給detail組件
// props:true
//props的第三種寫法,值為函數(shù),該函數(shù)返回的對象中每一組key-value都會通過props傳遞給Detail組件
props(route){
return {
id:route.query.id,
title:route.query.title
}
}
//解構賦值寫法
props({query:{id,title}}){
return {id:id,title:title}
}
}
router-link的replace屬性
1.作用:控制路由跳轉(zhuǎn)時操作瀏覽器歷史記錄的模式
2.瀏覽器的歷史記錄有兩種寫入方式:分別為push和replace,push是追加歷史記錄,replace是替換當前記錄,路由跳轉(zhuǎn)時候默認為push
3.如何開啟replace模式:<router-link replace······>News</router-link>
編程式路由導航
1.作用:不借助<router-link></router-link>實現(xiàn)路由跳轉(zhuǎn),讓路由跳轉(zhuǎn)更加靈活
2.具體編碼:
this.$router.push({
name:'detail',
params:{
id:m.id,
title:m.title
}
})
this.$router.replace({
name:'detail',
params:{
id:m.id,
title:m.title
}
})
this.$router.forward() //前進
this.$router.back() //后退
this.$router.go() //可前進可后退
緩存路由組件
vue2寫法
<keep-alive>
<router-view></router-view>
</keep-alive>
vue3寫法
<router-view v-slot="{ Component }">
<keep-alive>
<component :is="Component"/>
</keep-alive>
</router-view>
兩個新的生命鉤子
1.作用:路由組件所獨有的兩個鉤子,用于捕獲路由組件的激活狀態(tài)
2.具體名字:
activated 路由組件被激活時觸發(fā)
deactivated 路由組件失活時觸發(fā)
路由守衛(wèi)
全局前置路由守衛(wèi) —— 初始化的時候被調(diào)用、每次路由切換之前被調(diào)用
router.beforeEach((to,from,next)=>{
if(to.meta.isAuth){ //判斷是否需要鑒定權限
if(localStorage.getItem('school') == 'atguigu'){
next()
} else{
alert('學校名不對,無權限查看!')
}
} else{
next()
}
})
后置路由守衛(wèi) —— 初始化的時候被調(diào)用、每次路由切換之后被調(diào)用
router.afterEach((to,from)=>{
document.title = to.meta.title || '硅谷'
})
獨享路由守衛(wèi)
beforeEnter:(to,from,next) => {
if(to.meta.isAuth){ //判斷是否需要鑒定權限
if(localStorage.getItem('school') == 'atguigu'){
next()
} else{
alert('學校名不對,無權限查看!')
}
} else{
next()
}
}
組件內(nèi)路由守衛(wèi)
//通過路由規(guī)則,進入該組件時被調(diào)用
beforeRouteEnter(to,from,next){
if(to.meta.isAuth){ //判斷是否需要鑒定權限
if(localStorage.getItem('school') == 'atguigu'){
next()
} else{
alert('學校名不對,無權限查看!')
}
} else{
next()
}
},
//通過路由規(guī)則,離開該組件時被調(diào)用
beforeRouteLeave(to,from,next){
next()
}
history模式與hash模式
1.對于一個url來說,什么是hash值 ?- #及其后面的內(nèi)容就是hash值。
2.hash值不會包含在HTTP請求中,即:hash值不會帶給服務器。
3.hash模式:
1.地址中永遠帶著#號,不美觀。
2.若以后將地址通過第三方手機app分享,若app校驗嚴格,則地址會被標記為不合法。
3.兼容性較好。
4.history模式:
1.地址干凈,美觀。
2.兼容性和hash模式相比略差。
3.應用部署上線時需要后端人員支持,解決刷新頁面服務端404的問題。
nodejs +express 部署
1.創(chuàng)建nodeDemo文件夾
-
開啟終端,執(zhí)行 npm init
起名之后一直回車,
3.npm install express
4.安裝成功后新建文件 server.js
image.png
const express = require('express')
const app = express()
app.get('/person',(req,res)=>{
//函數(shù)體
res.send({
name:'Tom',
age:18
})
})
app.listen(5005,(err)=>{
if(!err) console.log("服務器啟動成功了!")
})
5.node server
啟動服務器,訪問頁面可得到人的信息

- 新建static文件夾,index.html頁面
修改server.js
app.use(express.static(__dirname+'/static'))

Document
直接訪問網(wǎng)址可得到index.html的內(nèi)容
7.將項目打包好的dist文件里的內(nèi)容復制到static文件夾里面,就可以訪問項目
由于是history模式,點擊頁面切換之后刷新 頁面會報錯,
改成hash模式之后重新打包,啟動服務,項目訪問不會報錯。
如果非得用history模式打包的話,通過安裝中間件來訪問404頁面
npm install connect-history-api-fallback
安裝完之后在server.js上引入
const history = require('connect-history-api-fallback')
Vue UI 組件庫
移動端常用UI組件庫
- Vant 介紹 - Vant Weapp (gitee.io)
- Cube UI cube-ui Document (didi.github.io)
- Mint UI Mint UI (mint-ui.github.io)
PC端常用 UI 組件庫
- Element UI Element - 網(wǎng)站快速成型工具
- IView UI iView / View Design 一套企業(yè)級 UI 組件庫和前端解決方案 (iviewui.com)
3.Ant Design Vue 組件總覽 - Ant Design Vue (antdv.com)
