前要:前端路由的概念與原理
1)什么是路由
路由(英文:router)就是對(duì)應(yīng)關(guān)系
2)SPA與前端路由
SPA指的是一個(gè)web網(wǎng)站只有一個(gè)唯一的一個(gè)HTML頁面,
所有組件的展示與切換
都在唯一的一個(gè)頁面內(nèi)完成。
此時(shí),不同組件之間的切換
需要通過前端路由
來實(shí)現(xiàn)
總結(jié):在SPA項(xiàng)目中,
不同功能之間的切換
,要依賴于前端路由
來完成
3)什么是前端路由
通俗移動(dòng)的概念:
地址
與組件
之間的對(duì)應(yīng)關(guān)系
4)前端路由的工作方式
- 用戶點(diǎn)擊了頁面上的路由鏈接
- 導(dǎo)致了URL地址欄中的值發(fā)生了變化
- 前端路由監(jiān)聽到了地址的變化
- 前端路由把當(dāng)前地址對(duì)應(yīng)的組件渲染到瀏覽器中
一、Vue-router簡單使用
1)什么是vue-router
vue-router
是vue.js官方
給出的路由解決方案。它只能結(jié)合 vue 項(xiàng)目進(jìn)行使用,能夠輕松的管理 SPA 項(xiàng)目中組件的切換。
vue-router 的官方文檔地址:https://router.vuejs.org/zh/
2) vue-router 安裝和配置的步驟
因?yàn)槲沂峭ㄟ^命令創(chuàng)建vue項(xiàng)目的,當(dāng)時(shí)已經(jīng)選配好了,所以下面前三個(gè)步驟都不用自己配置
① 安裝 vue-router 包
在 vue2 的項(xiàng)目中,安裝 vue-router 的命令如下:
cnpm i vue-router@3.5.2 -S
② 創(chuàng)建路由模塊
在
src
源代碼目錄下,新建router/index.js
路由模塊,并初始化如下的代碼:
//1. 導(dǎo)入Vue 和 VueRouter的包
import Vue from 'vue'
import VueRouter from 'vue-router'
//2. 調(diào)用Vue.use() 函數(shù),把VueRouter安裝為Vue的插件
Vue.use(VueRouter)
//3. 創(chuàng)建路由的實(shí)例對(duì)象
const routes = new VueRouter()
//4. 向外共享路由的實(shí)例對(duì)象
export default router
③ 導(dǎo)入并掛載路由模塊
在
src/main.js
入口文件中,導(dǎo)入并掛載路由模塊。示例代碼如下:
import Vue from 'vue'
import App from './App.vue'
//1. 導(dǎo)入路由模塊
import router from './router'
import store from './store'
Vue.config.productionTip = false
//2. 掛載路由模塊
new Vue({
router, //也可以寫成 router:router
store,
render: h => h(App)
}).$mount('#app')
④ 聲明路由鏈接和占位符(router-view/router-link)
在
src/App.vue
組件中,使用 vue-router 提供的< router-link > (這個(gè)也可以不用)
和< router-view >
聲明路由鏈接(路由鏈接也可以不用)
和占位符:
'''
< router-link>:該標(biāo)簽是一個(gè)vue-router中已經(jīng)內(nèi)置的組件,它會(huì)被渲染成一個(gè)<a>標(biāo)簽。
< router-view>:該標(biāo)簽會(huì)根據(jù)當(dāng)前的路徑,動(dòng)態(tài)渲染出不同的組件。
網(wǎng)頁的其他內(nèi)容,比如頂部的標(biāo)題/導(dǎo)航,或者底部的一些版權(quán)信息等會(huì)和< router-view>處于同一個(gè)等級(jí)。
在路由切換時(shí),切換的是< router-view>掛載的組件,其他內(nèi)容不會(huì)發(fā)生改變。
'''
<template>
<div id="app">
<!--定義路由鏈接 || 也可以不用定義-->
//<router-link to="/">首頁</router-link>
//<router-link to="/login">登錄</router-link>
<!--定義路由的占位符-->
<router-view></router-view>
</div>
</template>
其實(shí)使用< a >鏈接也行,如
< a href="#/home">首頁</ a>
但更推薦使用< router-link>
并且這樣不需要寫#號(hào)
,在瀏覽器控制臺(tái)看到的還是< a>鏈接
router-link補(bǔ)充
- tag:tag可以指定router-link之后渲染成什么組件,比如,此時(shí)就是一個(gè)button了;
- replace:增加replace屬性,就相當(dāng)于replaceState;
- class:可以為標(biāo)簽增加樣式,比如選中的會(huì)自動(dòng)賦值router-link-active;
- active-class=“active”:選中的;也可以在router組件中配置linkActiveClass: ‘a(chǎn)ctive’;
⑤ 聲明路由的匹配規(guī)則
在
src/router/index.js
路由模塊中,通過routes數(shù)組
聲明路由的匹配規(guī)則。示例代碼如下:
//1.導(dǎo)入需要使用路由切換展示的組件
import IndexView from '@/views/indexView.vue'
import LoginView from "@/views/LoginView.vue";
//2.注冊(cè)路由
const routes = [
//在routers數(shù)組中,聲明路由的匹配規(guī)則
{
path: '/', // path表示要匹配的地址
name: 'index', // name 表示別名
component: IndexView, //component 表示要展示的路由組件
},
{
path: '/login',
name: 'login',
component: LoginView
},
]
3) vue-router 簡單使用
1.在views中創(chuàng)建一個(gè)頁面組件
<script>
export default {
name:'indexView',
}
</script>
<template>
<div>
<h1>首頁</h1>
</div>
</template>
<style scoped>
</style>
2.在router/index.js文件中導(dǎo)入并使用
# 導(dǎo)入Vue 和 VueRouter的包
import Vue from 'vue'
import VueRouter from 'vue-router'
//1.導(dǎo)入需要使用路由切換展示的組件
import IndexView from '@/views/indexView.vue'
# 調(diào)用Vue.use() 函數(shù),把VueRouter安裝為Vue的插件
Vue.use(VueRouter)
//2.注冊(cè)路由
const routes = [
//在routers數(shù)組中,聲明路由的匹配規(guī)則
{
path: '/', // path表示要匹配的地址
name: 'index', // name 表示別名
component: IndexView, //component 表示要展示的路由組件
},
]
# 創(chuàng)建路由的實(shí)例對(duì)象
const router = new VueRouter({
mode: 'history',
base: process.env.BASE_URL,
routes
})
# 向外共享路由的實(shí)例對(duì)象
export default router
3.在App.vue中定義路由的占位符,這樣就可以實(shí)現(xiàn)組件切換
<template>
<div id="app">
<!--定義路由的占位符-->
<router-view>
</router-view>
</div>
</template>
<style></style>
<script>
export default {
name: 'App',
data() {
return {}
},
created() {
console.log(this) // 只要使用了路由組件 this中就有了 route router
}
}
</script>
這樣啟動(dòng)vue項(xiàng)目后,在瀏覽器中輸入對(duì)應(yīng)的路由即可訪問了
二、登錄跳轉(zhuǎn)電影熱點(diǎn)榜單案例
1)注意事項(xiàng)一:axios
這里會(huì)涉及到從前端向后端發(fā)送ajax請(qǐng)求,所以需要安裝一個(gè)axios,命令cnpm install axios -S
(-S是會(huì)把這個(gè)依賴寫入到package.json中,不寫的話只能在當(dāng)前項(xiàng)目使用)
使用axios,和導(dǎo)入組件一樣的操作
import axios from 'axios' //一樣import后面不一定叫axios它只是一個(gè)重命名,可以隨意叫,為了好識(shí)別不亂改
2)注意事項(xiàng)二:跨域問題
1.在Django中安裝模塊
pip3 install django-cors-headers
2.在settings中注冊(cè)應(yīng)用和注冊(cè)中間件
INSTALLED_APPS = (
'corsheaders',
)
MIDDLEWARE = [
'corsheaders.middleware.CorsMiddleware'
]
3.最后把下面的代碼復(fù)制到settings文件夾中即可
CORS_ORIGIN_ALLOW_ALL = True
CORS_ALLOW_METHODS = (
'DELETE',
'GET',
'OPTIONS',
'PATCH',
'POST',
'PUT',
'VIEW',
)
CORS_ALLOW_HEADERS = (
'XMLHttpRequest',
'X_FILENAME',
'accept-encoding',
'authorization',
'content-type',
'dnt',
'origin',
'user-agent',
'x-csrftoken',
'x-requested-with',
'Pragma',
)
案例開始
這里為了方便,我使用restframework-jwt快速創(chuàng)建登錄,因?yàn)槭莏wt是基于auth表的登錄,所以先創(chuàng)建一個(gè)用戶,這里不就在演示了。
Django編寫后端登錄接口以及獲取電影熱點(diǎn)榜單接口urls.py
from rest_framework_simplejwt.views import token_obtain_pair
urlpatterns = [
path('login/', token_obtain_pair),
]
我這里為了好一些,就定制返回格式和定制全局異常處理
serializer.py
from rest_framework_simplejwt.serializers import TokenObtainPairSerializer
class LoginSerializer(TokenObtainPairSerializer):
def validate(self, attrs):
res = super().validate(attrs)
user = self.user
data = {'code': 100, 'message': '登錄成功', 'username': user.username}
data.update(res)
return data
'設(shè)置全局,在settings中配置一下'
SIMPLE_JWT = {
"TOKEN_OBTAIN_SERIALIZER": "app01.serializer.LoginSerializer",
}
excptions.py
from rest_framework.views import exception_handler
from rest_framework.response import Response
def common_exception_handler(exc, context):
res = exception_handler(exc, context)
if res:
msg = res.data.get('detail') or res.data or '系統(tǒng)異常,請(qǐng)聯(lián)系管理員'
return Response({'code': 999, 'msg': msg})
else:
return Response({'code': 888, 'msg': f"系統(tǒng)異常,請(qǐng)聯(lián)系管理員:{str(exc)}"})
'配置一下自定義的全局異常處理,在settings中配置一下'
REST_FRAMEWORK = {
'EXCEPTION_HANDLER': 'app01.excptions.common_exception_handler'
}
views.py配置訪問電影接口
from rest_framework.views import APIView
from rest_framework.response import Response
import json
class MovieView(APIView):
def get(self, request):
with open('./movie.json', 'rt', encoding='utf-8') as f:
res = json.load(f)
return Response(res)
'urls.py'
path('movies/', views.MovieView.as_view()),
Vue+axios編寫前端配置LoginView.vue組件
<script>
import axios from 'axios'
export default {
name:'LoginView',
data(){
return {
username:'',
password:'',
}
},
methods:{
handlerSubmit(){
//發(fā)送ajax請(qǐng)求
axios.post('http://127.0.0.1:8000/api/v1/login/',{
username:this.username,
password:this.password
}).then(response=>{
if(response.data.code===100){
//路由跳轉(zhuǎn) vue-router支持的
this.$router.push('/')
}else{
alert(response.data.msg)
}
})
}
}
}
</script>
<template>
<div>
<h1>登錄頁面</h1>
<hr>
<p>username: <input type="text" v-model="username" placeholder="請(qǐng)輸入用戶名"></p>
<p>password: <input type="password" v-model="password" placeholder="請(qǐng)輸入密碼"></p>
<button @click="handlerSubmit">登錄</button>
</div>
</template>
配置indexView.vue組件
<script>
import axios from 'axios'
export default {
name: 'indexView',
data() {
return {
filmlist: [],
}
},
created() {
axios.get('http://127.0.0.1:8000/api/v1/movies/').then(res => {
// console.log(res.data.status)
if (res.data.status === 0) {
this.filmlist = res.data.data.films
// console.log(res.data.data.films)
} else {
alert(res.msg)
}
})
}
}
</script>
<template>
<div>
<h1 style="margin-left:20px;">電影熱點(diǎn)榜單</h1>
<div id="zhu" v-for="film in filmlist">
<div style="float: left;">
<img :src="film.poster" alt="" style="width:66px;height:100px;">
</div>
<div style="float:left;margin-left:10px;margin-top:-20px;">
<span>
<h4 style="padding:0;margin-bottom:12px;">{{ film.name }}</h4>
<span>觀眾評(píng)分 {{ film.grade }}</span><br>
主演:<span v-for="people in film.actors">
{{ people.name }}
</span><br>
<span>中國大陸|{{ film.runtime }}</span>
</span>
</div>
</div>
</div>
</template>
<style scoped>
#zhu {
border-top: 1px solid rgb(158, 158, 158);
margin: 20px;
padding: 20px;
overflow: hidden;
}
</style>
配置App.vue占位
<template>
<div id="app">
<!--定義路由的占位符-->
<router-view>
</router-view>
</div>
</template>
在router/index.js中導(dǎo)入組件和注冊(cè)路由
// 導(dǎo)入Vue 和 VueRouter的包
import Vue from 'vue'
import VueRouter from 'vue-router'
//1.導(dǎo)入需要使用路由切換展示的組件
import IndexView from '@/views/indexView.vue'
import LoginView from "@/views/LoginView.vue";
//調(diào)用Vue.use() 函數(shù),把VueRouter安裝為Vue的插件
Vue.use(VueRouter)
//2.注冊(cè)路由
const routes = [
//在routers數(shù)組中,聲明路由的匹配規(guī)則
{
path: '/', // path表示要匹配的地址
name: 'index', // name 表示別名
component: IndexView, //component 表示要展示的路由組件
},
{
path: '/login',
name: 'login',
component: LoginView
},
]
// 創(chuàng)建路由的實(shí)例對(duì)象
const router = new VueRouter({
mode: 'history',
base: process.env.BASE_URL,
routes
})
// 向外共享路由的實(shí)例對(duì)象
export default router
這樣就實(shí)現(xiàn)了登錄后跳轉(zhuǎn)到電影熱點(diǎn)榜頁面了
三、scoped樣式
Scoped主要作用就是讓當(dāng)前樣式只允許當(dāng)前組件生效 別的組件無效
用個(gè)實(shí)例來說明一下
'TestView是沒有設(shè)置在style標(biāo)簽中設(shè)置scoped樣式的,我們配置好組件和路由去訪問別的路由地址看看'
<script>
export default {
name:'TestView'
}
</script>
<template>
<div>
<h1>hello world</h1>
</div>
</template>
<style> //這是
h1{background-color:lightblue}
</style>
可以發(fā)現(xiàn)當(dāng)我們切換別的路由組件時(shí),那個(gè)組件的樣式全局設(shè)置了,所以需要設(shè)置在style標(biāo)簽中設(shè)置scoped樣式
我們?cè)侔裺coped樣式加上看看
可以看到已經(jīng)不影響其他組件了。
四、混入(mixin)
混入(mixin)
提供了一種非常靈活的方式,來分發(fā)Vue組件中的可復(fù)用功能
。一個(gè)混入對(duì)象可以包含任意組件選項(xiàng)。
當(dāng)組件使用混入對(duì)象時(shí),所有混入對(duì)象的選項(xiàng)將被"混合"進(jìn)入該組件本身的選項(xiàng)。換句話說,
mixin是對(duì)vue組件的一種擴(kuò)展,將一些公用的常用數(shù)據(jù)或者方法,構(gòu)建成一個(gè)可被混入的數(shù)據(jù)結(jié)構(gòu),被不同的vue組件進(jìn)行合并,就可以在不同的vue組件中使用相同的方法或者基礎(chǔ)數(shù)據(jù)。
如果只是提取公用的數(shù)據(jù)或者通用的方法,并且這些數(shù)據(jù)或方法, 不需要組件間進(jìn)行維護(hù),就可以使用mixin(類似于js中封裝的一些公用的方法)
1) 定義混入
在src文件夾下創(chuàng)建一個(gè)mixin/index.js
export default {
data(){
return {
name:'王三多'
}
},
methods:{
getName(){
console.log('來自mixin/index的點(diǎn)擊事件')
alert('彭于晏')
}
}
}
2) 局部導(dǎo)入混入
在想要使用的組件中導(dǎo)入使用即可
<template>
<div>
<h1>混入的使用</h1>
<hr>
<button @click="getName">點(diǎn)我彈出名字</button>
<br>
<span>當(dāng)前組件的定義的名字:{{name}}----->{{age}}</span>
</div>
</template>
<script>
//局部使用混入
import mixin from '@/mixin'
export default {
name: 'MixinsView',
data(){
return{
name:'張三豐',
age:20,
}
},
mixins:[mixin], //可以導(dǎo)入多個(gè)混入,有多個(gè)想用直接在這個(gè)數(shù)組中追加即可
}
</script>
注意:
如果混入的對(duì)象與當(dāng)前組件使用混入的有同名選項(xiàng)時(shí),這些選項(xiàng)將以恰當(dāng)?shù)姆绞竭M(jìn)行"合并",如果發(fā)生沖突時(shí)以當(dāng)前組件數(shù)據(jù)優(yōu)先使用。
2) 全局導(dǎo)入混入
混入也可以進(jìn)行全局注冊(cè)。使用時(shí)格外小心!一旦使用全局混入,它將影響每一個(gè)之后創(chuàng)建的 Vue 實(shí)例。
在mian.js中導(dǎo)入
//混入的全局導(dǎo)入、可以導(dǎo)入多個(gè)混入,注意名稱需要不一樣
import mixin from '@/mixin'
Vue.mixin(mixin)
五、插件
1)介紹
什么是Vue插件,它和Vue組件有什么區(qū)別?
通常插件是一種遵循一定規(guī)范的應(yīng)用程序接口編寫出來的程序,是一個(gè)庫
。而組件則更傾向于一個(gè)單一的功能,一個(gè)控件或?qū)ο?/code>。Vue官網(wǎng)給我們的解釋是:插件通常用來為 Vue 添加全局功能、組件是可復(fù)用的 Vue 實(shí)例。
vue插件的作用:主要是用于增強(qiáng)功能,可以把它看做一個(gè)工具庫,可以提供很多強(qiáng)大的功能,比如一些強(qiáng)大的自定義指令、一些強(qiáng)大的工具方法、過濾器等。
插件是一種能為Vue添加全局功能的工具代碼
官網(wǎng)說到,插件的功能范圍沒有嚴(yán)格的限制——一般有下面幾種:
-
添加全局方法或者 property。如:vue-custom-element
-
添加全局資源:指令/過濾器/過渡等。如 vue-touch
-
通過全局混入來添加一些組件選項(xiàng)。如 vue-router
-
添加 Vue 實(shí)例方法,通過把它們添加到 Vue.prototype 上實(shí)現(xiàn)。
-
一個(gè)庫,提供自己的 API,同時(shí)提供上面提到的一個(gè)或多個(gè)功能。如 vue-router
2)插件的使用
本質(zhì):Vue.js 的插件包含一個(gè) install 方法的一個(gè)對(duì)象。這個(gè)方法的第一個(gè)參數(shù)是 Vue 構(gòu)造器,第二個(gè)參數(shù)是一個(gè)可選的選項(xiàng)對(duì)象(插件使用者傳遞的數(shù)據(jù))。
定義插件在src文件夾下新建一個(gè)文件夾plugins/index.js
-es5及以前
// 此類中必須要有 靜態(tài)方法 install 靜態(tài)方法中不能調(diào)用成員屬性或方法 this不能用
// static install(Vue,options){
-es6之后
export default {
install(Vue){
console.log(Vue)
//使用插件能干什么?
1.設(shè)置全局變量
Vue.prototype.$name='jack'
2.可以把a(bǔ)xios做成全局,這樣每個(gè)組件就可以直接使用this.$axios
Vue.prototype.$axios=axios
3.設(shè)置全局函數(shù),以后再任意組件中 this.add(1,2)調(diào)用方法
Vue.prototype.$add=(a,b)=>{
return a+b+99
}
4.使用混入,只要這樣設(shè)置后,就不用再全局里面注冊(cè)混入了,這樣任意組件一樣能用
Vue.mixin({
data(){
return{
name:'oscar',
age:22,
}
},
methods:{
ShowName(){
alert('名字為:'+this.name+' '+'年齡為:'+this.age)
}
}
})
}
}
注冊(cè)插件在main.js中注冊(cè)
import plugins from '@/plugins'
Vue.use(plugins)
在任意組件中使用即可
<script>
export default {
name:'PluginsView',
methods:{
handlerClick(){
// console.log(this.$axios)
console.log('自定義插件的屬性:'+this.$name)
console.log('自定義插件的方法:'+this.$add(9,1))
}
},
}
</script>
<template>
<div>
<h1>插件的使用</h1>
<hr>
<button @click="handlerClick">點(diǎn)擊查看控制臺(tái)</button>
<p/>
<button @click="ShowName">點(diǎn)我查看自定義插件混入</button>
</div>
</template>
文章來源:http://www.zghlxwxcb.cn/news/detail-816123.html
補(bǔ)充Python中和js中往類中放屬性
文章來源地址http://www.zghlxwxcb.cn/news/detail-816123.html
'python中'
class Person:
pass
Person.name='jack'
p=Person()
print(p.name)
'js中'
new Vue() //Vue類
Vue.prototype.$name='jack' //往類中放屬性,與python中有些區(qū)別
'這里的prototype就是原型,在屬性名前加$是為了防止被污染作區(qū)分'
this.$router //this代指Vue實(shí)例
this.$name //從對(duì)象中取
到了這里,關(guān)于Vue入門六(前端路由的概念與原理|Vue-router簡單使用|登錄跳轉(zhuǎn)案例|scoped樣式|混入(mixin)|插件)的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!