vue
复习
""" 1、vue-router插件 路由跳转: <router-link to="/path"></router-link> <router-link :to="{name: 'path'}"></router-link> this.$router.push('/path') this.$router.push({name: 'path'}) this.$router.go(-1) this.$router.go(1) 路由传参: 配置:path: '/path/:pk' => 请求:`/path/${pk}` => 取值:this.$route.params.pk 配置:path: '/path', name='path' => 请求:{name:'path', query={pk:值}} => 取值:this.$route.query.pk 2、vuex插件 完成任意组件间的数据交互(当页面刷新重新加载,仓库中的数据会重置) store.js配置: state: {num:0} 取值:this.$store.state.num 赋值:this.$store.state.num = 10 3、vue-cookies插件 下载 => 配置 => 使用 下载: cnpm install vue-cookies 配置main.js: import cookies from 'vue-cookies' Vue.prototype.$cookies = cookies 使用: this.$cookies.set('key', 'value', 1 * 24 * 3600) // 1 * 24 * 3600 = '1d' = 省略 this.$cookies.get('key') this.$cookies.remove('key') 4、axios插件 下载 => 配置 => 使用 下载: cnpm install axios 配置main.js: import axios from 'axios' Vue.prototype.$axios = axios 使用: this.$axios({ url: '后台接口链接', method: '请求方式', data: {数据包}, params: {链接拼接数据}, header: {请求头} }).then(function(response){ // 请求成功的回调函数 }).catch(function(error){ // 请求失败的回调函数 }) 5、element-ui插件 下载 => 配置 => 使用 下载: cnpm install element-ui 配置main.js: import ElementUI from 'element-ui'; import 'element-ui/lib/theme-chalk/index.css'; Vue.use(ElementUI); 使用: 在组件的template标签中,直接使用element-ui提供的众多 组件标签,在script标签中,直接用this访问element-ui提供的众多功能 <el-row></el-row> this.$message({ message: '普通弹出框' }) """
流式布局思想
""" 页面的尺寸改变动态改变页面布局,或是通过父集标签控制多个子标签,这种布局思想就称之为 - 流式布局思想 1) 将标签宽高设置成 百分比,就可以随屏幕(父集)缩放而缩放 2) 将标签宽高设置成 视图百分比,就可以随屏幕缩放而缩放 3) 将子集字体设置成 继承值,就可以通过父集统一控制子集 """
<!DOCTYPE html>
<html lang="zh">
<head>
<meta charset="UTF-8">
<title>流式布局</title>
<style>
/*body { margin: 0 }*/
.box {
width: 800px;
height: 200px;
background-color: orange;
/*页面宽度缩放,盒子始终居中*/
margin-left: auto;
margin-right: auto;
width: 80%;
/*vw: view width | vh: view height*/
width: 80vw;
width: 80vh;
}
/*em、rem*/
.sup {
font-size: 40px;
}
.sub {
/*font-size: inherit;*/
/*font-size: 1.5em;*/
/*width: 5em;*/
font-size: 2rem;
}
html {
font-size: 30px;
}
</style>
</head>
<body>
<div class="box"></div>
<div class="sup">
<div class="sub">字</div>
</div>
</body>
</html>
js函数
<!DOCTYPE html>
<html lang="zh">
<head>
<meta charset="UTF-8">
<title>js函数</title>
</head>
<body>
<h1>js函数</h1>
</body>
<script>
// 参数:你传你的,我收我的
function fn1(a, b, c, d) {
console.log(a, b, c, d);
console.log('fn1 run');
}
fn1(1, 2, 3);
let fn2 = function (...args) {
console.log(args);
console.log(args[0]);
console.log('fn2 run');
};
fn2(1, 2, 3, 4);
(function () {
console.log('fn3 run');
})();
let fn4 = () => {
console.log('fn4 run');
};
fn4();
// 有参有反
let fn5 = (a, b) => {
console.log(a, b);
return a + b;
};
let res = fn5(1, 2);
console.log(res);
// 箭头函数函数体如果只有返回值,可以简写
let fn6 = (a, b) => a + b;
res = fn6(10, 20);
console.log(res);
// 当形参只有一个,可以省略()
let fn7 = a => a * 2;
res = fn7(10);
console.log(res);
// 当形参为空的简写方式
let fn8 = () => 200;
res = fn8();
console.log(res);
</script>
</html>
面向对象js
ES6里可以包含ES5,但是ES5不能包含ES6
ES6:
面向对象与面向过程,使用class来定义类,ES6中有类属性,可供全局使用,但是类方法只能使用function,不能用箭头函数。如果箭头函数在class里就可以匹配到this,自身没有找上面
ES5:
基于对象与面向过程,ES5没有class,使用的是function,箭头函数不能匹配到对应的this,往上是windows,但是function可以匹配到this
<!DOCTYPE html>
<html lang="zh">
<head>
<meta charset="UTF-8">
<title>流式布局</title>
<style>
/*body { margin: 0 }*/
.box {
width: 800px;
height: 200px;
background-color: orange;
/*页面宽度缩放,盒子始终居中*/
margin-left: auto;
margin-right: auto;
width: 80%;
/*vw: view width | vh: view height*/
width: 80vw;
width: 80vh;
}
/*em、rem*/
.sup {
font-size: 40px;
}
.sub {
/*font-size: inherit;*/
/*font-size: 1.5em;*/
/*width: 5em;*/
font-size: 2rem;
}
html {
font-size: 30px;
}
</style>
</head>
<body>
<div class="box"></div>
<div class="sup">
<div class="sub">字</div>
</div>
</body>
</html>
前后端项目登录页面的搭建:
注意点:
1.后端的settings中的csrf要注掉
2.使用前端axios要在当前项目下载:cnpm install axios
3.后端解决跨域问题
// Django如何解决 - django-cors-headers模块
// 1) 安装:pip3 install django-cors-headers
// 2) 注册:
INSTALLED_APPS = [
...
'corsheaders'
]
// 3) 设置中间件:
MIDDLEWARE = [
...
'corsheaders.middleware.CorsMiddleware'
]
// 4) 设置跨域:
CORS_ORIGIN_ALLOW_ALL = True
4.路由重定向:当两个不同path的路由来访问同一个页面组件时可用,(‘/’和‘/home’都是跳转到主页)
{
path: '/',
name: 'home',
component: Home
},
{
path: '/home',
redirect: '/' // 路由的重定向
},
5.后端在request.GET中获取到数据,前端post请求。说明数据并不是由请求方式提供的,而是在哪提交的数据,params中发送数据在reqeust.GET可以获取
6.记录登录状态:localStorage.token = response.data.token
思路:
创建登录页面的样式,router.js注册路由,登录需要认证所以要通过beforeCreate组件钩子要查看lacalStorage是否存在token(是否登录),将用户输入的账号和密码获取到存为data,button按钮触发点击事件,获取到data中的用户输入的数据进行判断用户是否输入为空,为空返回错误信息,不为空使用axios的post请求方法发给后端url并且要通过params大字典携带数据,后端通过request.GET中取出数据,判断账号和密码是否正确,正确与否都返回不同数据的JsonRsponse大字典,前端通过then获取返回的数据通过status判断正确与否,成功就记录登录状态,跳转到主页。catch错误信息返回清空数据库.
前端代码:views/Login.vue
<template>
<div class="login">
<h1>登录页面</h1>
<hr>
<form action="">
<p>
<label for="username">账号:</label>
<input type="text" id="username" name="username" v-model="username">
</p>
<p>
<label for="password">密码:</label>
<input type="password" id="password" name="password" v-model="password">
</p>
<button type="button" @click="login">登录</button>
</form>
</div>
</template>
<script>
export default {
name: "Login.vue",
data () {
return {
username: '',
password: '',
}
},
beforeCreate() {
// 查看localStorage中是否存在token(是否登录),登录跳转主页
let token = localStorage.token;
if (token) {
this.$router.push('/')
}
},
methods: {
login () {
let username = this.username;
let password = this.password;
if (!(username && password)) {
alert('信息有误');
return false
}
this.$axios({
url: 'http://localhost:8000/login/',
method: 'post',
//后端是在request.GET中拿到数据,数据并不是由请求方式提供的,而是你提交的数据在哪提交的
//这里是在params中提交的,所以在request.GET中拿到数据
params: {
username,
password
}
}).then(response => {
let status = response.data.status;
if (status == 0) {
alert('登录成功');
// 记录登录状态
localStorage.token = response.data.token;
localStorage.username = response.data.username;
// 跳转主页
this.$router.push('/');
} else {
alert('登录失败')
}
}).catch(() => {
alert('登录异常')
});
// 清空输入框
this.username = '';
this.password = '';
}
}
}
</script>
<style scoped>
.login {
text-align: center;
}
button {
/*display: block;*/
width: 220px;
}
</style>
先配置路由
后端views.py
from django.http import JsonResponse def login(request): print(request.GET) username = request.GET.get('username') password = request.GET.get('password') if username == 'abc' and password == '123': return JsonResponse ({ 'status':0, 'msg':'登录成功', 'token':'token.abc.123', 'username':username, }) return JsonResponse({ 'status':1, 'msg':'登录失败' })
注销用户的搭建:
注意点:
1.丢弃登录状态 localStorage.clear()
2.authorization:this.token使用authorization不会报错,在后端通过http_authorization_token的key值获取值,因为wsgi以http将其打包成http_变量的形式的数据
3.watch:监听token值的变化
4.
beforeCreate() {
//这是根据文件的所在路径去访问了,之前的写法是this._checkToken()但是这样写会报错,
// 因为beforeCreate()生命周期是数据未加载前,所以还没有数据this_checkToken()
let token = localStorage.token;
if (!token){
this.$router.push('/login')
} //在数据还未加载之前就把token的存储到localStorage里面
},
思路:
设计登录主页后用户登录就显示用户名和一个注销功能。
先设计登录页面的样式,然后到url注册,展示用户名是通过localStorage中存储的用来判断。使用组件钩子beforeCreate数据未加载之前查看token是否存在,判断是否登录。然后点击注销按钮触发点击事件将localStorage.clear()清空,然后watch()监听token值是否改变。
前端views/Home.vue
<template>
<div class="home">
<div class="header">
<h1>主页</h1>
<span v-if="token">
<b>{{ username }}</b>
|
<b @click="logout">注销</b>
</span>
<span v-else>
<b>请登录</b>
</span>
</div>
</div>
</template>
<script>
export default {
name: 'home',
data() {
return {
token: localStorage.token ? localStorage.token : '',
username: localStorage.username ? localStorage.username : '',
}
},
components: {},
beforeCreate() {
// 查看localStorage中是否存在token(是否登录),未登录跳转登录页面
this.$options.methods._checkToken();
},
methods: {
logout() {
// 丢弃登录状态,就可以完成注销(不需要后台参与)
localStorage.clear();
this.token = '';
this.username = '';
},
watch: {
token() {
this._checkToken();
}
},
}
</script>
<style scoped>
h1 {
float: left;
}
span {
float: right;
}
.header:after {
content: '';
display: block;
clear: both;
}
.header {
line-height: 80px;
}
</style>
需要认证信息的后台请求
注意:
1.后端settings中要进行配置
MEDIA_ROOT = os.path.join(BASE_DIR, 'media')
1-2.url也要写:
re_path(r'^media/(?P<path>.*)', serve, {'document_root': settings.MEDIA_ROOT}),
1-3 手动创建文件夹media/img/放入图片
点击button触发点击事件,将路由后缀传入通过ajxos 的get请求携带header携带token给后端,后端
META中获取token进行判断传值,前端获取到infos,赋值给data中的infos:[]. 然后v-for循环获取信息展示
前端views/Home.vue
<template>
<div class="home">
<div class="header">
<h1>主页</h1>
<span v-if="token">
<b>{{ username }}</b>
|
<b @click="logout">注销</b>
</span>
<span v-else>
<b>请登录</b>
</span>
</div>
<hr>
<div class="ctx">
<p>
<button @click="changeInfo('/phone/')">phone</button>
<button @click="changeInfo('/tv/')">tv</button>
</p>
<div v-for="info in infos" :key="info.url">
<img width="200" :src="info.url" alt="">
<p>{{ info.title }}</p>
</div>
</div>
</div>
</template>
<script>
export default {
name: 'home',
data() {
return {
token: localStorage.token ? localStorage.token : '',
username: localStorage.username ? localStorage.username : '',
infos: [],
}
},
components: {},
beforeCreate() {
// 查看localStorage中是否存在token(是否登录),未登录跳转登录页面
this.$options.methods._checkToken();
},
methods: {
logout() {
// 丢弃登录状态,就可以完成注销(不需要后台参与)
localStorage.clear();
this.token = '';
this.username = '';
},
_checkToken() {
let token = localStorage.token;
if (!token) {
this.$router.push('/login')
}
},
changeInfo(path) {
this.$axios({
url: `http://localhost:8000${path}`,
method: 'get',
headers: {
authorization: this.token
}
}).then(response => {
console.log(response.data);
this.infos = response.data.results;
})
}
},
watch: {
token() {
this._checkToken();
}
},
// created() {
// this.$axios({
// url: 'http://localhost:8000/phone/',
// method: 'get',
// headers: {
// authorization: this.token
// }
// }).then(response => {
// console.log(response.data);
// this.infos = response.data.results;
// })
// }
}
</script>
<style scoped>
h1 {
float: left;
}
span {
float: right;
}
.header:after {
content: '';
display: block;
clear: both;
}
.header {
line-height: 80px;
}
</style>
后端views.py
from django.shortcuts import render # Create your views here. from django.http import JsonResponse def login(request): print(request.GET) username = request.GET.get('username') password = request.GET.get('password') if username == 'abc' and password == '123': return JsonResponse ({ 'status':0, 'msg':'登录成功', 'token':'token.abc.123', 'username':username, }) return JsonResponse({ 'status':1, 'msg':'登录失败' }) def tv(request): token = request.META.get('HTTP_AUTHORIZATION') if not token: return JsonResponse({ 'status':1, 'msg':'没有权限' },json_dumps_params={'ensure_ascii':False}) return JsonResponse({ 'status':0, 'msg':'ok', 'results':[ { 'url': 'http://localhost:8000/media/img/003.jpg', 'title': '电视一号' }, { 'url': 'http://localhost:8000/media/img/004.jpg', 'title': '电视二号' } ] },json_dumps_params={'ensure_ascii':False}) def phone(request): token = request.META.get('HTTP_AUTHORIZATION') if not token: return JsonResponse({ 'status': 1, 'msg': '没有权限' }, json_dumps_params={'ensure_ascii': False}) return JsonResponse({ 'status': 0, 'msg': 'ok', 'results': [ { 'url': 'http://localhost:8000/media/img/001.jpg', 'title': '手机一号' }, { 'url': 'http://localhost:8000/media/img/002.jpg', 'title': '手机二号' } ] }, json_dumps_params={'ensure_ascii': False})
VUE与bs,jq的环境搭建
jq:
当前项目终端输入命令:cnpm install jquery
然后在根目录下创建vue.config.vue
const webpack = require("webpack");
module.exports = {
configureWebpack: {
plugins: [
new webpack.ProvidePlugin({
$: "jquery",
jQuery: "jquery",
"window.jQuery": "jquery",
Popper: ["popper.js", "default"]
})
]
}
};


浙公网安备 33010602011771号