vue

Posted huangxuanya

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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: ‘普通弹出框‘
        })
"""
View Code

 

流式布局思想

"""
页面的尺寸改变动态改变页面布局,或是通过父集标签控制多个子标签,这种布局思想就称之为 - 流式布局思想

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>
View Code

 

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>
View Code

 

面向对象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>
Home.vue

 

需要认证信息的后台请求

注意:

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" >
                <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"]
            })
        ]
    }
};

 

以上是关于vue的主要内容,如果未能解决你的问题,请参考以下文章

VSCode自定义代码片段(vue主模板)

VSCode自定义代码片段11——vue路由的配置

VSCode自定义代码片段11——vue路由的配置

VSCode自定义代码片段11——vue路由的配置

VSCode自定义代码片段2——.vue文件的模板

VSCode自定义代码片段13——Vue的状态大管家