Vue记录

文章目录

1 Vue概述

Vue是一款前端渐进式框架,可以提高前端开发效率。

Vue通过MVVM模式,能够实现视图与模型的双向绑定。
简单来说,就是数据变化的时候, 页面会自动刷新, 页面变化的时候,数据也会自动变化.

导入:
Vue是一个类似于Jquery的一个JS框架,所以,如果想使用Vue,则在当前页面导入Vue.js文件即可。

<!-- 在线导入 -->
<!-- 开发环境版本,包含了用帮助的命令行警告 -->
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<!-- 生产环境版本,优化了尺寸和速度 -->
<script src="https://cdn.jsdelivr.net/npm/vue"></script>
<!-- 本地导入 -->
<script src="node_modules/vue/dist/vue.js"></script>

1.1 小案例

<div id="app">
    <h1>用户名:<input type="text" v-model="name"/></h1> <br/>
    <h1>您输入的用户名是: {{name}}</h1>
</div>

<script type="text/javascript">
    //创建一个Vue对象
    var app = new Vue({
        //指定,该对象代表<div id="app">,也就是说,这个div中的所有内容,都被当前的app对象管理
        el: "#app",
        //定义vue中的数据
        data: {
            name: ""
        }
    });
</script>

1.2 完整案例

1.2.1 项目架构、页面样式

在这里插入图片描述
在这里插入图片描述

1.2.1 pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.5.5</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.example</groupId>
    <artifactId>testspringboot</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>testspringboot</name>
    <description>Demo project for Spring Boot</description>
    <properties>
        <java.version>1.8</java.version>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-thymeleaf</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>fastjson</artifactId>
            <version>1.2.73</version>
        </dependency>

    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

</project>

1.2.2 application.yml

server:
  port: 18088

spring:
  mvc:
    static-path-pattern: /static/**
  web:
    resources:
      static-locations: classpath:/static,classpath:/public,classpath:/resources,classpath:/META-INF/resources

# 自定义参数
diyData:
  syPubKey: MIIBIjANBgkqhk

1.2.3 controller

package com.fri.hz.controller;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.chinaoly.encrypt.Encrypt;
import com.chinaoly.generate.GenerateKeyPaire;
import com.chinaoly.sign.Sign;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.*;

import java.security.NoSuchAlgorithmException;
import java.util.HashMap;
import java.util.Map;

@RestController
@RequestMapping("/api")
public class showPersonInfo {

    @Value("${diyData.syPubKey}")
    private String syPubKey;

    @PostMapping("/showPersonInfo")
    public JSONObject showPersonInfo(@RequestBody JSONObject data){
        System.out.println("查询" + data.getString("checkedIdCard"));
        String url = openPersonInfoPage(data.getString("idCard"), data.getString("name"),
                data.getString("orgCode"), data.getString("orgName"),
                data.getString("mobile"), data.getString("policeNo"),
                data.getString("ip"), data.getString("checkedIdCard"));
        JSONObject res = new JSONObject();
        res.put("url", url);
        return res;
    }

1.2.4 index.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>新疆协查人员电子档案</title>
    <link rel="stylesheet" type="text/css" href="../static/css/index.css">
    <style>
        . {
            margin: 0;
            padding: 0;
        }
        body, #app, .el-form, .el-form-item, .el-button{
            width: 100%;
        }
        .el-form-item__label{
            width: 40% !important;
        }
        .el-form-item__content{
            width: 30% !important;
        }
    </style>
</head>
<body>
    <h1 style="text-align: center">新疆协查人员电子档案</h1>
    <div id="app">
        <el-form :inline="true" :label-position="labelPosition" label-width="80px" :model="formLabelAlign">
            <el-form-item label="查询人身份证号码">
                <el-input v-model="formLabelAlign.idCard"></el-input>
            </el-form-item>
            <el-form-item label="查询人姓名">
                <el-input v-model="formLabelAlign.name"></el-input>
            </el-form-item>
            <el-form-item label="单位编码">
                <el-input v-model="formLabelAlign.orgCode"></el-input>
            </el-form-item>
            <el-form-item label="单位中文名称">
                <el-input v-model="formLabelAlign.orgName"></el-input>
            </el-form-item>
            <el-form-item label="查询人手机号码">
                <el-input v-model="formLabelAlign.mobile"></el-input>
            </el-form-item>
            <el-form-item label="查询人警号">
                <el-input v-model="formLabelAlign.policeNo"></el-input>
            </el-form-item>
            <el-form-item label="查询人IP地址">
                <el-input v-model="formLabelAlign.ip"></el-input>
            </el-form-item>
            <el-form-item label="被查询人身份证号码">
                <el-input v-model="formLabelAlign.checkedIdCard"></el-input>
            </el-form-item>
            <el-form-item style="text-align: center">
                <el-button type="primary" @click="checkFun">查询</el-button>
            </el-form-item>
        </el-form>
    </div>

    <script src="../static/js/jquery1.8.0.js"></script>
    <script src="../static/js/vue.js"></script>
    <script src="../static/js/index.js"></script>
    <script type="text/javascript">
        //创建一个Vue对象
        var app = new Vue({
            //指定,该对象代表<div id="app">,也就是说,这个div中的所有内容,都被当前的app对象管理
            el: "#app",
            //定义vue中的数据
            data: {
                labelPosition: 'right',
                formLabelAlign: {
                    idCard: '',
                    name: '',
                    orgCode: '',
                    orgName: '',
                    mobile: '',
                    policeNo: '',
                    ip: '',
                    checkedIdCard: ''
                }
            },
            methods: {
                //定义show方法,弹出提示框
                checkFun() {
                    var param = {
                        idCard: this.formLabelAlign.idCard,
                        name: this.formLabelAlign.name,
                        orgCode: this.formLabelAlign.orgCode,
                        orgName: this.formLabelAlign.orgName,
                        mobile: this.formLabelAlign.mobile,
                        policeNo: this.formLabelAlign.policeNo,
                        ip: this.formLabelAlign.ip,
                        checkedIdCard: this.formLabelAlign.checkedIdCard
                    }
                    $.ajax({
                        type: "post",
                        url:"/api/showPersonInfo",   //控制器路径
                        contentType: "application/json;charset=utf-8",
                        data: JSON.stringify(param),
                        cache: false,
                        success: function (msg) {
                            //新页面打开地址
                            window.open(msg.url);
                            console.log("---over---");
                        }
                    });
                }
            }
        });
    </script>
</body>
</html>

2 Vue基本语法

2.1 钩子函数

钩子函数:其实就是Vue提前定义好的事件,其作用类似于Servlet的init方法和distory方法。

语法:

var app = new Vue({
    el:"#app",
    //钩子函数created,该方法在页面显示之后,自动执行
    created() {
        console.log("created...");
    }
});

补充:Vue声明周期和钩子函数
(1)什么是vue生命周期?
Vue 实例从创建到销毁的过程,就是生命周期。也就是从开始创建、初始化数据、编译模板、挂载Dom→渲染、更新→渲染、卸载等一系列过程,我们称这是 Vue 的生命周期。

(2)vue生命周期的作用是什么?
Vue生命周期中有多个事件钩子,让我们在控制整个Vue实例过程时更容易形成好的逻辑。

(3)vue生命周期总共有几个阶段?
可以总共分为8个阶段:创建前/后, 载入前/后,更新前/后,销毁前/后。

(4)第一次页面加载会触发哪几个钩子?
第一次页面加载时会触发 beforeCreate, created, beforeMount, mounted 这几个钩子

(5)DOM 渲染在 哪个周期中就已经完成?
DOM 渲染在 mounted 中就已经完成了。
在这里插入图片描述
(6)简单描述每个周期具体适合哪些场景?
生命周期钩子的一些使用方法:
beforecreate : 可以在此阶段加loading事件,在加载实例时触发;
created : 初始化完成时的事件写在这里,如在这结束loading事件,异步请求也适宜在这里调用;
mounted : 挂载元素,获取到DOM节点;
updated : 如果对数据统一处理,在这里写上相应函数;
beforeDestroy : 可以做一个确认停止事件的确认框;
nextTick : 更新数据后立即操作dom;

2.2 插值表达式

插值表达式:用户把vue中所定义的数据,显示在页面上。插值表达式允许用户输入"JS代码片段"

语法: {{ 变量名/对象.属性名 }}

<div id="app">
    <h1>欢迎来到-->{{ name }}</h1>
</div>
<script type="text/javascript">
    //创建vue对象
    var app = new Vue({
        //让vue接管div标签
        el:"#app",
        //定义数据,里边包含一个属性name,值为"白大锅"
        data:{
            name:"白大锅"
        }
    });
</script>

2.3 显示数据(v-text和v-html)

v-text和v-html专门用来展示数据,其作用和插值表达式类似。v-text和v-html可以避免插值闪烁问题。
当网速比较慢时,使用=={ undefined{} }来展示数据, 有可能会产生插值闪烁问题。
插值闪烁: 在数据未加载完成时,页面会显示出原始的
{undefined{}}==,过一会才会展示正常数据.

语法:

v-text:<span v-text="msg"></span>		<!-- 相当于<span>{{msg}}</span> -->
v-html:<span v-html="msg"></span>		<!-- 相当于<span>{{msg}}</span> -->

v-text:把数据当作纯文本显示
v-html:遇到html标签,会正常解析

2.4 数据双向绑定数据(v-model)

Vue的双向绑定可以实现:数据变化的时候,页面会自动刷新;页面变化的时候,数据也会自动变化.

注意:

  1. 双向绑定,只能绑定“文本框、单选按钮、复选框、文本域、下拉列表”等。
  2. 文本框/单选按钮/textarea,绑定的数据是字符串类型。
  3. 单个复选框,绑定的是boolean类型。
  4. 多个复选框,绑定的是数组。
  5. select单选对应字符串,多选对应也是数组。

2.4.1 绑定文本框

<div id="app">
    用户名: <input type="text" v-model="username"/>
</div>
<script type="text/javascript">
    var app = new Vue({
        el:"#app",
        data:{
            //该属性值和文本框的value属性值,保持一致
            username:""
        }
    });
</script>

2.4.2 绑定单个复选框

<div id="app">
    <input type="checkbox" v-model="agree">同意<br>
</div>
<script type="text/javascript">
    var app = new Vue({
        el:"#app",
        data:{
            agree:true
        }
    });
</script>

2.4.3 绑定多个复选框

<div id="app">
    <input type="checkbox" value="Java" v-model="language">Java<br>
    <input type="checkbox" value="C++" v-model="language">Python<br>
    <input type="checkbox" value="Swift" v-model="language">Swift<br>
</div>
<script type="text/javascript">
    var app = new Vue({
        el:"#app",
        data:{
            //数组中的值,就是被选中的元素的value属性值
            language:["Java","C++"]
        }
    });
</script>

2.4.4 单选框

在这里插入图片描述

2.5 事件处理(v-on)

2.5.1 事件绑定(v-on)

Vue中也可以给页面元素绑定事件.

<!--完整写法-->
<button v-on:事件名="函数名/vue表达式">点我</button>
<!--简化写法-->
<button @事件名="函数名/vue表达式">点我</button>

注意: Vue支持html中所有已知事件。如:@click,@submit等,只不过事件的名字不带on。

<div id="app">
    <button @click="show">点我</button>
</div>
<script type="text/javascript">
    //创建vue对象
    var app = new Vue({
        //获取id为app的元素,该元素被vue对象所管理.只有被vue对象管理的标签,其内部才允许书写vue语法
        el:"#app",
        //定义vue的方法
        methods:{
            //定义show方法,弹出提示框
            show() {
                alert("Hello Vue!!!");
            }
        }
    });
</script>

2.5.2 事件修饰符

事件修饰符:主要对事件的发生范围进行限定。

语法: <button @事件名.事件修饰符="函数名/vue表达式">点我</button>

分类:

  • .stop:阻止事件冒泡, 也就是当前元素发生事件,但当前元素的父元素不发生该事件
  • .prevent:阻止默认事件发生
  • .capture:使用事件捕获模式, 主动获取子元素发生事件, 把获取到的事件当自己的事件执行
  • .self:只有元素自身触发事件才执行。(冒泡或捕获的都不执行)
  • .once:只执行一次

<button @click.once=“show”>点我

2.6 循环遍历(v-for)

2.6.1 遍历数组

v-for="item in items"
v-for="(item,index) in items"
items:要迭代的数组
item:存储数组元素的变量名
index:迭代到的当前元素索引,从0开始。

<div id="app">
    <ul>
        <li v-for="(user, index) in users">
            {{index}}--{{user.name}}--{{user.age}}--{{user.gender}}
        </li>
    </ul>
</div>
<script>
    var app = new Vue({
        el:"#app",//el即element,要渲染的页面元素
        data: {
            users:[
                {"name":"白卓冉","age":8,"gender":"男"},
                {"name":"白大锅","age":12,"gender":"女"},
                {"name":"白仙女","age":4,"gender":"男"}
            ]
        }
    });
</script>

2.6.2 遍历对象

v-for="value in object"
v-for="(value,key) in object"
v-for="(value,key,index) in object"
value:对象的值
key:对象的键
index:索引,从0开始

<div id="app">
    <ul>
        <li v-for="(value,key,index) in person">
            {{index}}--{{key}}--{{value}}
        </li>
    </ul>
</div>
<script>
    var app = new Vue({
        el:"#app",//el即element,要渲染的页面元素
        data: {
            person:{"name":"白大锅", "age":3, "address":"中国"}
        }
    });
</script>

2.6.3 key

:key,一般配合v-for一起使用。用来在特定情况下,保证被遍历的数组中的元素的顺序。

<div id="app">
    <button @click="add">添加</button>
    <ul>
        <li v-for="name in list" :key="name">
            <input type="checkbox"> {{name}}
        </li>
    </ul>
</div>
<script>
    var app = new Vue({
        el: '#app',
        data: {
            list: ["孙悟空", "猪八戒", "沙和尚"]
        },
        methods: {
            add() {
                //注意这里是unshift,向数组的头部添加一个元素
                this.list.unshift("唐僧");
            }
        }
    });
</script>

2.7 判断语法(v-if、v-else和v-show)

v-if与v-show可以根据条件的结果,来决定是否显示指定内容。
v-if:条件不满足时,元素不会存在。
v-show:条件不满足时,元素不会显示(但仍然存在)。

<div id="app">
    <button @click="show = !show">点我</button>
    <h1 v-if="show">Hello v-if.</h1>
    <h1 v-show="show">Hello v-show.</h1>
</div>
<script>
    var app = new Vue({
        el:"#app",
        data: {
            show:true
        }
    });
</script>

v-if 和 v-else-if 的使用

<div id="app">
    <p v-if="score>=90">优秀</p>
    <p v-else-if="score>=60">及格</p>
    <p v-else>不及格</p>
</div>

2.8 显示数据(v-bind)

v-bind的作用和插值表达式差不多,只不过,v-bind主要用于动态设置标签的属性值。

<!--完整写法-->
<标签名 v-bind:标签属性名="vue实例中的数据属性名"/>
<!--简化写法-->
<标签名 :标签属性名="vue实例中的数据属性名"/>
<div id="app">
    <input type="button" :value="msg"/>
</div>
<script type="text/javascript">
    var app = new Vue({
        el:"#app",
        data:{
            msg:"我是按钮"
        }
    });

</script>

2.9 Vue页面跳转(两种方法)

(1)index.js配置路由
在这里插入图片描述
(2)Home主页
在这里插入图片描述
(3)Login登陆页
在这里插入图片描述
注意:下面前两种方法须在vue-cli项目中使用

2.9.1 方法一(标签实现)

<router-link to="/Home">gotoHome</router-link>

2.9.2 方法二(this.$router.push()实现)

this.$router.push('/Login');

2.9.3 location.href实现

<div id="app">
    <button @click="hreftwo" >点我到第二个页面</button>
</div>

<script>
    var app = new Vue({
        el: "#app",
        data: {
            user: {}
        },
        methods:{ //跳转页面
            hreftwo(){
                console.log('跳转页面');
                location.href = "/login"; // LoginPage.html
            }
        }
    });
</script>
@Controller
public class WebPageController {

    @GetMapping(value = "/login")
    public String loginPage() {
        return "html/LoginPage";
    }
}

3 Vue其他语法

3.1 计算属性

计算属性:就是一个提前定义好的方法,该方法可以看作是一个特殊的值,可以在插值表达式中使用。

var app = new Vue({
    el:"#app",
    //计算属性必须放在Vue的computed中
    computed:{
        //定义计算属性
        属性名(){
            return "返回值";
        }
    }
});
<div id="app">
    <h1>{{birth}}</h1>
    <h1 v-text="birth"></h1>
    <h1 v-html="birth"></h1>
</div>
<script type="text/javascript">
    var app = new Vue({
        el:"#app",
        computed:{
            //定义一个birth方法,该方法就是一个计算属性,可以在插值表达式中使用
            birth(){
                let date = new Date();
                let year = date.getFullYear();
                let month = date.getMonth()+1;
                let day = date.getDay();
                return year + "-" + month + "-" + day;
            }
        }
    });
</script>

3.2 watch监控

watch可以监听简单属性值及其对象中属性值的变化。
watch类似于onchange事件,可以在属性值修改的时候,执行某些操作。

<div id="app">
    <h1><input v-model="message"></h1>
    <h1><input v-model="person.name"><input v-model="person.age"></h1>
</div>
<script type="text/javascript">
    var app = new Vue({
        el:"#app",
        data:{
            message:"白大锅",
            person:{"name":"heima", "age":13}
        },
        //watch监听
        watch:{
            //监听message属性值,newValue代表新值,oldValue代表旧值
            message(newValue, oldValue){
                console.log("新值:" + newValue + ";旧值:" + oldValue);
            },
            //监控person对象的值,对象的监控只能获取新值
            person: {
                //开启深度监控;监控对象中的属性值变化
                deep: true,
                //获取到对象的最新属性数据(obj代表新对象)
                handler(obj){
                    console.log("name = " + obj.name + "; age=" + obj.age);
                }
            }
        }
    });
</script>

4 Vue组件

4.1 基本使用

组件:类似于模版、模块。在项目需要重用某个模块(头部、尾部、新闻…)的时候,可以将模块抽取成组件,其它页面中注册组件并引用。

<div id="app">
    <!--使用组件(组件名称),如果组件名称中有大写字母,如"myList",则这里需要书写<my-list>-->
    <counter></counter>
    <counter></counter>
</div>
<script type="text/javascript">
    //定义组件
    const counterTemp = {
        //定义组件的模版
        template:`<button @click='num++'>你点击了{{num}}次</button>`,
        //定义组件中使用到的数据属性
        data(){
            return {
                num:0
            }
        }
    };

    //全局注册组件:在所有的vue实例中都可以使用组件
    //参数1:组件名称,参数2:具体的组件
    //Vue.component("counter", counterTemp);

    var app = new Vue({
        el:"#app",
        //局部注册组件: 只能在当前Vue实例中使用
        components:{
            //组件名称:具体组件
            counter: counterTemp
        }
    });
</script>

注意:

  1. 组件的模版中,只能书写一个根标签
  2. 组件的定义必须放在Vue创建对象之前,否则报错

4.2 父组件向子组件通信

子组件无法直接使用父组件中的数据,如果需要使用,则必须由父组件把数据传递给子组件才可以.
让子组件中的属性与父组件中的属性进行关联绑定,然后子组件使用该属性,这样才能做到数据传递

<div id="app">
    <!-- 把父组件中的count传递给子组件的number属性,把父arr传递给子ids,把父p传递给子person -->
    <aaa :number="count" :ids="arr" :person="p"></aaa>
</div>

<script>
    var aaa = {
        //定义组件的模版
        template: `<h2>{{num}}---{{number}}--{{ids}}--{{person}}</h2>`,
        //定义组件中使用到的数据属性
        data() {
            return {
                num: 0
            }
        },
        //给组件添加属性
        props: {
            //普通属性number
            number: "",
            //数组属性ids
            ids: [],
            //对象属性person
            person: {}
            /*
            *  //以上属性还可以书写为以下格式
            *  items:{
            *        //数据类型,如果是数组则是Array,如果是对象则是Object
            *       type:Array,
            *       //默认值
            *       default:[]
            *  }
            */
        },
        created(){
            this.num = this.number;
        }
    };

    //注册:全局注册
    Vue.component("aaa", aaa);

    var app = new Vue({
        el: "#app",
        data: {
            count: 5,
            arr: [1, 2, 3],
            p: {username: "zhangsan", age: 23}
        }
    });
</script>

4.3 子组件向父组件通信

子组件无法直接给父组件传递数据。也无法操作父组件中的数据,更无法调用父组件中的方法。所以,所谓的子组件向父组件通讯,其实就是想办法让子组件调用父组件的方法,进而响应到父组件中的数据。

<div id="app">
    <h1>父组件中:app_num={{app_num}}</h1>
    <!-- 把父组件的add方法,绑定给子组件的aaa属性,绑定方法使用@属性名="方法名" -->
    <!-- 把父组件的rem方法,绑定给子组件的bbb属性,绑定方法使用@属性名="方法名 -->
    <!-- 把父组件的app_num变量,绑定给子组件的counter_num属性,绑定变量使用:属性名="方法名 -->
    <counter @aaa="add" @bbb="rem" :counter_num="app_num"></counter>
</div>

<script>
    //定义一个组件(模版)
    let counter = {
        template: `
             <div>
                   <h1>子组件中:counter_num={{counter_num}}</h1>
                   <input type="button" @click="fun1" value="+"/>
                   <input type="button" @click="fun2" value="-"/>
            </div>
                `,
        props:{
            //定义属性counter_num,用来接收父组件传递的数据
            counter_num:null,
            //定义aaa属性,用来绑定父组件的方法,当然,该定义也可以省略
            aaa:function(){},
            //定义bbb属性,用来绑定父组件的方法,当然,该定义也可以省略
            bbb:function(){},
        },
        methods:{
            fun1(){
                //找到aaa属性所绑定的那个方法,执行那个方法
                return this.$emit("aaa");
            },
            fun2(){
                //找到bbb属性所绑定的那个方法,执行那个方法
                return this.$emit("bbb");
            }
        }
    }

    var app = new Vue({
        el: '#app',
        data: {
            app_num: 0
        },
        components: {
            counter
        },
        methods:{
            add(){
                this.app_num++;
            },
            rem(){
                this.app_num--;
            }
        }
    });
</script>

5 axios异步请求

5.1 axios概述

axios是一个基于promise的HTTP库,主要用于:发送异步请求获取数据。

常见的方法:

  • axios(config)
  • axios.get(url, [config])
  • axios.post(url, [data])

<script src="../../static/js/vue.js"></script>
<script src="../../static/js/axios.min.js"></script>

发送数据config常用参数:

{
    url: '请求的服务器',
    method: '请求方式', // 默认是 get
    // GET请求参数
    params: {
        参数名: 参数值
    },
    // POST请求参数,如果使用axios.post,则参数在url之后直接书写,不需要该位置传递参数
    data: {
        参数名: 参数值
    },
    // 响应数据格式,默认json
    responseType: 'json'
}

响应数据常用参数:

{
    data: {},     //真正的响应数据(响应体)
    status: 200,   //响应状态码
    statusText: 'OK',   //响应状态描述
    headers: {},   //响应头
    config: {}    //其他配置信息
}

5.2 Get请求

<script>
    var app = new Vue({
        el: "#app",
        data: {
            user: {}
        },
        //当页面加载完毕后
        created() {
            axios.get('http://localhost:8899/api/testGet', {
                params: {
                    name: 'zhangsan',
                    age: 23
                }
            }).then(res => {
                console.log(res);
                this.user = res.data.code;
            }).catch(err => {
                console.log(err);
            })
        }
    });
</script>
@RestController
@RequestMapping("/api")
public class Controller {

    @GetMapping("/testGet")
    public JSONObject loginCon (@RequestParam("name") String name, @RequestParam("age") int age) {
        System.out.println("testGet name:" + name + "---age:" + age);
        JSONObject data = new JSONObject();
        data.put("code", 0);
        return data;
    }

}

5.3 Post请求

<script>
    var app = new Vue({
        el: "#app",
        data: {
            user: {}
        },
        //当页面加载完毕后
        created() {
            var params = new URLSearchParams();
            params.append('name', 'zhangsan');
            params.append('age', 23);
            //发送POST请求axios.post("请求路径",{ 参数 });
            axios.post("http://localhost:8899/api/testPost", params).then(res => {
                console.log(res);
                this.user = res.data.code;
            }).catch(err => {
                console.log(err);
            });
        }
    });
</script>
@RestController
@RequestMapping("/api")
public class Controller {

    @PostMapping("/testPost")
    public JSONObject loginCon1(@RequestParam("name") String name, @RequestParam("age") int age) {
        System.out.println("testPost name:" + name + "---age:" + age);
        JSONObject data = new JSONObject();
        data.put("code", 0);
        return data;
    }

}

5.4 跨域请求

跨域请求:在前端js中如果发送异步请求的话,请求的地址与当前服务器的ip或者端口号不同都是跨域请求。
跨域请求需要在服务提供方,开启允许跨域请求。
在这里插入图片描述

6 前端工程化vue-cli

vue.js有著名的全家桶系列,包含了vue-router,vuex,vue-resource,再加上构建工具vue-cli,就是一个完整的vue项目的核心构成。
vue-cli这个构建工具大大降低了webpack的使用难度,支持热更新,有webpack-dev-server的支持,相当于启动了一个请求服务器,给你搭建了一个测试环境,只关注开发就OK。

6.1 安装vue-cli

(1)使用npm(需要安装node环境)全局安装webpack,打开命令行工具输入:npm install webpack -g或者(npm install -g webpack),安装完成之后输入webpack -v,如果出现相应的版本号,则说明安装成功。
(2)全局安装vue-cli,在cmd中输入命令:npm install --global vue-cli,安装完成之后输入vue -V(注意这里是大写的“V”),如果出现相应的版本号,则说明安装成功。

6.2 用vue-cli来构建项目

(1)首先新建一个文件夹(dxl_vue)作为项目存放地,然后使用命令行cd进入到项目目录输入:vue init webpack project_name

project_name是自定义的项目名称,命令执行之后,会在当前目录生成一个以该名称命名的项目文件夹。输入命令后,会跳出几个选项让你回答:可直接回车

  • ①Project name (baoge): -----项目名称,直接回车,按照括号中默认名字(注意这里的名字不能有大写字母,如果有会报错Sorry, name can no longer contain capital letters)。

  • ②Project description (A Vue.js project): ----项目描述,也可直接点击回车,使用默认名字

  • ③Author (): ----作者,输入你的大名

  • ④Runtime + Compiler: recommended for most users 运行加编译,既然已经说了推荐,就选它了

  • ⑤Install vue-router? (Y/n) 是否安装vue-router,这是官方的路由,大多数情况下都使用,这里就输入“y”后回车即可。

  • ⑥Use ESLint to lint your code? (Y/n) 是否使用ESLint管理代码,ESLint是个代码风格管理工具,是用来统一代码风格的,一般项目中都会使用。

  • ⑦Setup unit tests with Karma + Mocha? (Y/n) 是否安装单元测试,我选择安装y回车

  • ⑧Setup e2e tests with Nightwatch(Y/n)? 是否安装e2e测试 ,我选择安装y回车
    回答完毕后,就开始构建项目了。

(2)配置完成后,可以看到目录下多出了一个项目文件夹baoge,然后cd进入这个文件夹,安装依赖:npm install。(如果安装速度太慢。可以安装淘宝镜像,打开命令行工具,输入:npm install -g cnpm --registry=https://registry.npm.taobao.org,然后使用cnpm来安装)。未执行此命令,也安装了,故此步骤可省略

npm install:安装所有的模块,如果是安装具体的哪个模块,在install后面输入模块的名字即可。而只输入install就会按照项目的根目录下的package.json文件中依赖的模块安装(这个文件里面是不允许有任何注释的),每个使用npm管理的项目都有这个文件,是npm操作的入口文件。因为是初始项目,还没有任何模块,所以我用npm install安装所有的模块。安装完成后,目录中会多出来一个node_modules文件夹,这里放的就是所有依赖的模块。
在这里插入图片描述
(3)启动项目:npm run dev
如果浏览器打开之后,没有加载出页面,有可能是本地的8080端口被占用,需要修改一下配置文件config里的index.js。
在这里插入图片描述
还有,如果本地调试项目时,建议将build里的assetsPublicPath的路径前缀修改为’./‘(开始是’/‘),因为打包之后,外部引入js和css文件时,如果路径以’/'开头,在本地是无法找到对应文件的(服务器上没问题)。所以如果需要在本地打开打包后的文件,就得修改文件路径。如果端口没有被占用,会直接成功(服务启动成功后浏览器会默认打开一个“欢迎页面”)。
注意:在进行vue页面调试时,一定要去谷歌商店下载一个vue-tool扩展程序。

(4)vue-cli的webpack配置分析
从package.json可以看到开发和生产环境的入口
在这里插入图片描述
可以看到dev中的设置,build/webpack.dev.conf.js,该文件是开发环境中webpack的配置入口。
在webpack.dev.conf.js中出现webpack.base.conf.js,这个文件是开发环境和生产环境,甚至测试环境,这些环境的公共webpack配置。可以说,这个文件相当重要。
还有config/index.js 、build/utils.js 、build/build.js等,具体请看这篇介绍:https://segmentfault.com/a/1190000008644830

(5)打包上线
注意,自己的项目文件都需要放到src文件夹下。在项目开发完成之后,可以输入npm run build来进行打包工作。
打包完成后,会生成dist文件夹,如果已经修改了文件路径,可以直接打开本地文件查看。项目上线时,只需要将dist文件夹放到服务器就行了

6.3 多页面跳转

可查看2.9前两种方式

6.4 自定义全局变量

(1)自定义存储数据的Config组件
在这里插入图片描述

const serverPath="http://127.0.0.1:8080";
export default{
	serverPath
}

(2)在main.js中注册组件
在这里插入图片描述
import global from './components/Config'
Vue.prototype.global = global

(3)使用方法:可以在其他组件中使用this.global.serverPath调用具体内容

6.5 axios请求

(1)安装axios:npm install vue-axios --save
(2)在main.js中注册axios
在这里插入图片描述
import axios from 'axios'
Vue.prototype.$axios = axios

(3)使用方法与“5 axios异步请求”中介绍相同,注意使用this.$axios
在这里插入图片描述

6.6 登陆验证token

(1)router > index.js

import Vue from 'vue'
import Router from 'vue-router'
import Home from '@/components/Home'
import Login from '@/components/Login.vue'

Vue.use(Router)

//解决VUE路由跳转出现Redirected when going from “/x“ to “/y“ via a navigation guard.报错
const originalPush = Router.prototype.push
Router.prototype.push = function push(location, onResolve, onReject) {
    if (onResolve || onReject) return originalPush.call(this, location, onResolve, onReject)
    return originalPush.call(this, location).catch(err => err)
}

const router = new Router({
    routes: [
    { path: '/', redirect: '/Login'},
    { path: '/Login', name: 'Login', component: Login},
    { path: '/Home', name: 'Home', component: Home}
   ]
})

//判断路由,是否登陆
router.beforeEach((to, from, next) => {
    var userInfo = window.localStorage.getItem('token'); 
    if(userInfo){ 
        next();
    } else {
        if(to.path == '/login'){ 
            next();
        } else {
            next('/login');
        }
    }
});

export default  router;

(2)Login页面
axios登陆成功后保存用户信息:window.localStorage.setItem("token", this.username);

(3)退出登录时,清空用户信息,并返回登陆页面

 clearToken(){
 	window.localStorage.setItem("token", '');
  	this.$router.push('/Login');
 }

6.7 组件使用

6.7.1 组件引入

在这里插入图片描述
在这里插入图片描述

6.7.2 父级向组件中传值

通过组件中定义props传值,在父级function中修改值,可直接影响组件中的值。
在这里插入图片描述
在这里插入图片描述
可以使用watch钩子函数,监测数值是否发生改变。
在这里插入图片描述

6.7.3 组件向父级传值

子传父,下级向上级汇报需要自己主动发送,也就是事件发射。
this.$emit('resurl', 'submitValue -- success!');就是事件发射。
第一个参数:父组件那边接收的事件名称
第二个参数:传递的值
在这里插入图片描述
在这里插入图片描述
resurl:子组件发射的事件名称
resurlValue:@resurl='resurlValue’中resurlValue不能带括号

7 Hbuilder构建vue项目

7.1 新建项目

在这里插入图片描述

7.2 修改端口号

(1)根目录下新建 vue.config.js
(2)复制如下内容:

module.exports = {  
	devServer: {    
		port: 8081,   // 端口号  
	},
};

7.3 安装Element-ui

(1)控制台:npm i element-ui -S
(2)main.js:

import ElementUI from 'element-ui';
import 'element-ui/lib/theme-chalk/index.css';
Vue.use(ElementUI);

(3)App.vue:

<div class="block">
	<el-date-picker
	  v-model="value1"
	  type="date"
	  placeholder="选择日期">
	</el-date-picker>
</div>

7.4 定义全局变量

(1)新建Config组件

<script>
	const serverPath="http://127.0.0.1:8090";
	export default{
		serverPath
	}
</script>

(2)在main.js中声明该组件
import Config from './components/Config'
Vue.prototype.Config = Config
(3)使用
<h1>{{this.Config.serverPath}}</h1>

7.5 定义路由

(1)安装router,注意版本:npm install vue-router@3.2.0
(2)修改App.vue,在其中添加<router-view></router-view>,此为路由页面展示位置

<template>
  <div id="app">	
    <router-view></router-view>
  </div>
</template>

<script>
</script>

<style>
</style>

(3)在src下新建router文件夹,在其中新建index.js

import Vue from 'vue'
import VueRouter from 'vue-router'
import home from '../components/Home.vue'
import error404 from '../components/error404.vue'

Vue.use(VueRouter)

const routes = [
	{
		path: '/', 
		name: 'home', 
		component: home,
	},
	{
		path: '/error404', 
		name: 'error404', 
		component: error404,
	}
]

export default new VueRouter({
	mode: 'history',
	base: process.env.BASE_URL,
	routes
})

(4)在main.js中声明

import Vue from 'vue'
import ElementUI from 'element-ui';
import 'element-ui/lib/theme-chalk/index.css';
import App from './App.vue'
import Config from './components/Config'
import router from './router'

Vue.use(ElementUI);
Vue.prototype.Config = Config
Vue.config.productionTip = false

new Vue({
	router,
	render: h => h(App),
}).$mount('#app')

(5)页面跳转: this.$router.push("error404");

7.6 组件的使用

在Home中引入HelloWorld(二者在同一目录下)

Home:

<template>
	<div>
		<img alt="Vue logo" src="../assets/logo.png">
		<HelloWorld :msg="Welcome to Your Vue.js App"/>
	</div>
</template>

<script>
import HelloWorld from './HelloWorld.vue'

export default {
	name: 'app',
	components: {
		HelloWorld
	}
}
</script>

HelloWorld:

<template>
  <div class="hello">
    <h1>{{ msg }}</h1>
  </div>
</template>

<script>
export default {
  name: 'HelloWorld',
  props: {
    msg: String
  }
}
</script>

7.7 引入外部CSS

在App.vue中引入css文件

assets/css/test.css

.test{
	color: #0000FF;
}

App.vue

<style>
  @import './assets/css/test.css';
</style>

当在App.vue中引入css文件时,在整个项目中都可用

Error404.vue

<h4 class="test" style="font-size: 40px; margin-top: 75px;">啊呀,不小心飞出地球了!</h4>

7.8 引入外部JS

在Home.vue中引入js文件,在App.vue中引入不管用,不知道为啥

test.js

var testFun = function(msg){
	console.log(msg);
}
var testFun1 = function(msg){
	console.log(msg + msg);
}

var testJS = {
	testFun,
	testFun1
}
export {
	testJS
}

Home.vue
必须在methods中重新调用一下才可以使用,否则查询不到方法

<el-button type="primary" plain @click="testFun1('asdas')">testJS</el-button>
<script>
import {testJS} from '../assets/js/test.js' //注意路径
或者import {testJS} from '@/assets/js/test.js' //注意路径

export default {
	name: 'app',
	methods:{
		testFun1(msg){
			testJS.testFun(msg);
			testJS.testFun1(msg);
		}
	}
}
</script>

7.9 axios发送请求

可参考5.2、5.3
(1)安装axios:npm install vue-axios --save
(2)在main.js中注册axios
在这里插入图片描述
import axios from 'axios'
Vue.prototype.$axios = axios
(3)使用方法与“5 axios异步请求”中介绍相同,注意使用this.$axios
在这里插入图片描述

testPost(){
	var params = new URLSearchParams();
	params.append("name", "张三");
	this.$axios.post("http://localhost:8090/api",params).then(res => {
		console.log(res);
		var msg = res.data;
	}).catch(err => {
		console.log(err);
	});
}

若报错,可能还需安装npm install --save axios

7.10 引入JQuery

(1)npm install jquery --save
(2)在Home.vue中引入jq

<input class="testjq" value="123" />
<script> 
import $ from 'jquery'

export default {
	name: 'app',
	methods:{
		testFun1(msg){
			$(".testjq").attr('value',"testJQ");
			console.log($(".testjq").attr('value'));
		}
	}
}
</script>

8 布局小知识

8.1 导航栏横排居右

<div class="col-md-8 navbar-form navbar-right">
	<ul class="nav navbar-nav">
		<li>导航1</li>
		<li>导航2</li>
		<li>导航3</li>
		<li>导航4</li>
	</ul>
</div>

8.2 鼠标悬浮动画

created() {
	$(function(){
		$('#saoma_img').hover(function() {
			console.log("123");
		}, function() {
			console.log("456");
		});					
	});
}

$("#saoma_img").animate({left:'-22px'},500);

奇葩事件

1 a标签乱跳

使用a标签触发点击事件时,a标签会跳转到其他也没面,但是并未设置href。将href设置为#,或者javascipt:void(0),也依然会跳转。
最终在外层套一层<button>不跳转了

2 运行Vue项目提示错误:no-tabs

(1)“http://eslint.org/docs/rules/no-tabs Unexpected tab character src\App.vue:4:2”

.eslintrc.js。注释掉eslintrc.js中的standard。
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值