鹤林玉露
罗大经

一愿识尽世间好人,

二愿读尽世间好书,

三愿看尽世间好山水。

这里介绍Vue2的使用。简单介绍,不会深入

Vue的基本介绍

Vue是一个前端框架, 易于构建用户界面。Vue 的核心库只关注视图层,不仅易于上手,还便于与第三方库或项目整合,支持和其它类库结合使用,开发复杂的单页应用非常方便。Vue 是 Vue.js 的简称。

下载地址

保存下载网页中的js代码

快速入门

这里简单演示一下Vue的使用

<!DOCTYPE html>
<html lang="en">
    <head>
    <meta charset="UTF-8">
    <title>vue 快速入门</title>
    </head>
    <body>
        <!--
        1. div 元素不是必须的,也可以是其它元素,比如 span,但是约定都是将 vue 实例挂载到 div
        2. 因为 div 更加适合做布局
        3. id 不是必须为 app , 是程序员指定,一般我们就使用 app
        -->
        <div id="app">
            <!--
            1. {{message}} : 插值表达式
            2. message 就是从 model 的 data 数据池来设置
            3. 当我们的代码执行时,会到 data{} 数据池中去匹配数据, 如果匹配上, 就进行替换, 如果没有匹配上, 就是输出空
            -->
        <h1>欢迎你{{message}}-{{name}}</h1>
        </div>
        <!--引入 vue.js-->
        <script src="vue.js"></script>
        <script>
        //创建 Vue 对象
        /**
        * 1. 创建 Vue 对象实例
        */
        let vm = new Vue({
            el: "#app", //创建的 vue 实例挂载到 id=app 的 div
            data: { //data{} 表示数据池(model 的有了数据), 有很多数据 ,以 k-v 形式设置(根据业务需要来设置)
            message: "Hello-Vue!", 
            name: "JL"
        	}	
        })
        console.log("vm=>", vm);
        console.log(vm._data.message);
        console.log(vm._data.name);
        </script>

    </body>
</html>

注意:

​ 注意代码顺序,要求 div 在前,script 在后,否则无法绑定数据。因为Vue会绑定对象,得先有元素对象,否则会报错。

语法介绍

数据的单向渲染

<!DOCTYPE html>
<html lang="en" xmlns:v-bind="http://www.w3.org/1999/xhtml">
<head>
    <meta charset="UTF-8">
    <title>单向数据渲染</title>
    <script type="text/javascript" src="vue.js"></script>
</head>
<body>
<!--
    1.在标签体内用插值表达式
    2.标签的属性用 v-bind:
-->
<div id="app">
    <h1>{{message}}</h1>
    <!-- v-bind可以省略(只保留:冒号) -->
    <img :src="img_src" v-bind:width="img_width">
</div>
<script type="text/javascript">
    new Vue({
        el : "#app",
        data : {
            message : "hello",
            img_src: "1.jpg",
            img_width: "1000px"
        }
    })
</script>
</body>
</html>

数据的双向绑定

<!DOCTYPE html>
<html lang="en" xmlns:v-bind="http://www.w3.org/1999/xhtml" xmlns:v-model="http://www.w3.org/1999/xhtml">
<head>
    <meta charset="UTF-8">
    <title>数据双向绑定</title>
    <script type="text/javascript" src="vue.js"></script>
</head>
<body>
<div id="app">
    <h1>{{message}}</h1>
    <!--
        1.v-bind: 是单向渲染,数据池中的数据变化,会影响view
        2.v-model="hobby.val" 是数据双向渲染,
            (1)data数据池绑定的数据变化,会影响view
            (2)view关联的数据发生变化,会影响data数据池的数据
    -->
    <input type="text" v-model:value="hobby.val"><br>
    <input type="text" v-bind:value="hobby.val">
    <p>你输入的爱好是:{{hobby.val}}</p>
</div>
<script type="text/javascript">
    var vm= new Vue({
        el: "#app",
        data:{
            message: "请输入你的爱好:",
            hobby:{
                val: "购物"
            }
        }
    })
</script>
</body>
</html>

事件绑定

  1. 使用 v-on 进行事件处理,比如v-on:click表示处理鼠标点击事件
  2. 事件调用的方法定义在 vue 对象声明的methods节点中
  3. v-on:事件名可以绑定指定事件
<!DOCTYPE html>
<html lang="en" xmlns:v-on="http://www.w3.org/1999/xhtml">
<head>
    <meta charset="UTF-8">
    <title>事件绑定</title>
    <script type="text/javascript" src="vue.js"></script>
</head>
<body>
<div id="app">
    <h1>{{message}}</h1>
    <!--当没有参数的时候可以省略括号-->
    <!--可以简写将 v-on: 简写为@-->
    <!--需要浏览器的支持-->
    <button v-on:click="sayHi()">点击输出</button>
    <button v-on:click="sayOk()">点击输出</button>
    <button @click="sayOk()">点击输出</button>
    <button @click="sayHi">点击输出</button>
</div>
<script type="text/javascript">
    var vm = new Vue({
        el: "#app",
        data:{
            message: "hello"
        },
        methods:{
            sayHi() {
               console.log("hi,银角大王");
            },
            sayOk(){
                console.log("ok,金角大王")
            }
        }
    })
</script>
</body>
</html>

修饰符

  1. 修饰符 (Modifiers) 是以(.)指明的后缀,指出某个指令以特殊方式绑定
  2. 例如,.prevent修饰符告诉 v-on 指令对于触发的事件调用 event.preventDefault()即阻止事件原本的默认行为
  3. 详细的可以前往官网
<!DOCTYPE html>
<html lang="en" xmlns:v-on="http://www.w3.org/1999/xhtml">
<head>
	<meta charset="UTF-8">
    <title>Vue 修饰符使用</title>
</head>
<body>
<div id="app">
    <!-- 
    1. 修饰符用于指出一个指令应该以特殊方式绑定。
    2. v-on:submit.prevent 的.prevent 修饰符表示阻止表单提交的默认行为
    3. 执行 程序员指定的方法
    -->
    <form action="http://www.baidu.com" v-on:submit.prevent="onMySubmit">
    妖怪名: <input type="text" v-model="monster.name"><br/><br/>
    	<button type="submit">注册</button>
    </form>
    <p>服务返回的数据是{{count}}</p>
<h1>修饰符扩展案例</h1>
<button v-on:click.once="onMySubmit">点击一次</button><br/>
<input type="text" v-on:keyup.enter="onMySubmit">
<input type="text" v-on:keyup.down="onMySubmit">
<input type="text" v-model.trim="count"> // .trim会自动去掉空格
</div>
<script src="vue.js"></script>
<script>
    let vm = new Vue({
        el: '#app', 
        data: {//数据池
        monster: {//monster 数据(对象)的属性, 可以动态生成
        },
        count: 0
    },
    methods: {//方法池
        onMySubmit() {
        //console.log("我们自己的表单提交处理...");
        //"", null, undefined 都是 false
        if(this.monster.name) {

        console.log("提交表单 name=", this.monster.name);
        //这里,程序员就可以根据自己的业务发出 ajax 请求到后端
        //得到数据后,在进行数据更新
        this.count = 666;
        } else {
        console.log("请输入名字..");
        }
    }
        } }) 
    </script> 
    </body> 
</html>

条件渲染

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>v-if</title>
    <script type="text/javascript" src="vue.js"></script>
</head>
<body>
<!-- v-if
    会根据返回的值,来决定是否动态创建子组件
    即:在切换的时候,会发生条件块内的事件监听器和子组件销毁和重建
-->
<div>
    <input type="checkbox" v-model="sel">是否同意条款
    <h1 v-if="sel">不同意条款</h1>
    <h1 v-else>同意条款</h1>
</div>
<script type="text/javascript">
    var vm = new Vue({
        el:"#app",
        data:{
            sel:false
        }
    })
</script>
</body>
</html>

v-if也可以使用else if来进行多组条件判断

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>v-if</title>
    <script type="text/javascript" src="vue.js"></script>
</head>
<body>
<!-- v-show
   会在底层通过设置display的属性来决定时候显示(display="none")
-->
<div id="app">
    <input type="checkbox" v-model="sel">是否同意条款
    <h1 v-show="sel">不同意条款</h1>
    <h1 v-show="!sel">同意条款</h1>
</div>
<script type="text/javascript">
    var vm = new Vue({
        el:"#app",
        data:{
            sel:false
        }
    })
</script>
</body>
</html>

列表渲染

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>v-for 列表渲染</title>
</head>
<body>
    <div id="app">
        <!-- 
        基本语法:
        <li v-for="变量 in 数字">{{ 变量 }}</li>-->

        <h1>简单的列表渲染</h1>
        <ul>
        <li v-for="i in 3">{{i}}</li>
        </ul>
            <!-- 
                基本语法:
                <li v-for="(变量, 索引) in 值">{{ 变量 }} - {{ 索引 }}</li>
            -->
            <h1>简单的列表渲染-带索引</h1>
        <ul>
        <li v-for="(i,index) in 3">{{i}}-{{index}}</li>
        </ul>
            <h1>遍历数据列表</h1>
        <!-- 语法:
            <tr v-for="对象 in 对象数组">
            <td>{{对象的属性}}</td>
            </tr>
        -->
        <table width="400px" border="1px">
            <tr v-for="(monster,index) in monsters">
                <td>{{index}}</td>
                <td>{{monster.id}}</td>
                <td>{{monster.name}}</td>
                <td>{{monster.age}}</td>
            </tr>
        </table>
    </div>
    <script src="vue.js"></script>
	<script>
        new Vue({
            el: '#app', 
            data: { //数据池
            monsters: [
                {id: 1, name: '牛魔王', age: 800}, 
                {id: 2, name: '黑山老妖', age: 900}, 
                {id: 3, name: '红孩儿', age: 200}
        		]
       		}
        })
	</script>
</body>
</html>

组件化编程

基本介绍

  1. 组件(Component) 是 Vue.js 最强大的功能之一(可以提高复用性)
  2. 组件也是一个Vue实例,也包括∶ data、methods、生命周期函数等
  3. 组件渲染需要 html模板,所以增加了template属性,值就是 HTML 模板
  4. 对于全局组件,任何vue 实例都可以直接在 HTML 中通过组件名称来使用组件
  5. data 是一个函数,不再是一个对象, 这样每次引用组件都是独立的对象/数据

使用场景

​ 当我们需要三组相同的按钮的时候,并且需要点击一下就计数加一。我们借此来引出组件化编程这个概念。

<!DOCTYPE html>
<html lang="en" xmlns:v-on="http://www.w3.org/1999/xhtml">
<head>
    <meta charset="UTF-8">
    <title>组件化编程</title>
    <script type="text/javascript"src="vue.js"></script>
</head>
<body>
<div id="app">
    <button v-on:click="click1()">点击次数={{count}}次【非组件化方式】</button>
    <button v-on:click="click1()">点击次数={{count}}次【非组件化方式】</button>
</div>
<script type="text/javascript">
    new Vue({
        el:"#app",
        data:{
            count:10
        },
        methods:{
            click1(){
                this.count++;
            }
        }
    })
</script>
</body>
</html>

我们这样使用的时候就会发现,我们这里数据池中的count是共用的。当然,我们可以在数据池的添加一个count1,然后在methods节点中添加一个与其对应的方法。但试想我们需要很多按钮的时候,这就造成了很多冗余的东西。由此我们有了组件化编程思想。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>组件化编程-全局组件</title>
    <script type="text/javascript" src="vue.js"></script>
</head>
<body>
<div id="app">
    <counter></counter>
    <counter></counter>
</div>
<script type="text/javascript">
    // counter为组件名称
    // 可以将组件视为一个Vue实例,他也有自己的数据池和methods
    // 对于组件,我们的数据池的数据,是使用函数/方法返回【目的是为了保证每个组件的数据是独立的】
    // 组件中的数据是独立的,方法是共享的
    Vue.component("counter",{
        template:`<button v-on:click="click()">点击次数={{count}}次【全局组件化方式】</button>`,
        // 如果使用data:{},他会报错
        data(){
            return{
                count: 10
            }
        },
        methods:{
            click(){
                this.count++;
            }
        }
    })
    // 创建Vue实例
    new Vue({
        el:"#app",
        data:{}
    })
</script>
</body>
</html>
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>组件化编程-局部组件</title>
    <script type="text/javascript" src="vue.js"></script>
</head>
<body>
<div id="app">
    <my_counter></my_counter>
    <my_counter></my_counter>
</div>
<script type="text/javascript">
    const buttonCounter = {
        template:`<button v-on:click="click()">点击次数={{count}}次【全局组件化方式】</button>`,
        // 如果使用data:{},他会报错
        data(){
            return{
                count: 10
            }
        },
        methods:{
            click(){
                this.count++;
            }
        }
    }

    // 创建Vue实例
    let vm = new Vue({
        el:"#app",
        components:{ // 引入某个组件,此时的my_counter是一个局部组件,他的使用范围在当前Vue
            'my_counter':buttonCounter
        }
    })
</script>
</body>
</html>

Vue的生命周期和监听函数(钩子函数)

基本介绍

  1. Vue 实例有一个完整的生命周期,也就是说从开始创建、初始化数据、编译模板、挂载DOM、渲染-更新-渲染、卸载等一系列过程,我们称为 Vue 实例的生命周期
  2. 钩子函数(监听函数): Vue 实例在完整的生命周期过程中(比如设置数据监听、编译模板、将实例挂载到 DOM 、在数据变化时更新 DOM 等), 也会运行叫做生命周期钩子的函数
  3. 钩子函数的 作用就是在某个阶段, 给程序员一个做某些处理的机会

生命周期图示

Vue 实例生命周期

函数的介绍:

  1. new Vue():new 了一个 Vue 的实例对象,此时就会进入组件的创建过程。

    Init Events & Lifecycle:初始化组件的事件和生命周期函数。

  2. beforeCreate:组件创建之后遇到的第一个生命周期函数,这个阶段 data 和 methods 以及 dom 结构都未被初始化,也就是获取不到 data 的值,不能调用 methods 中的函数。

    Init injections & reactivity:这个阶段中, 正在初始化 data 和 methods 中的方法。

  3. created:这个阶段组件的 data 和 methods 中的方法已初始化结束,可以访问,但是 dom 结构未初始化,页面未渲染(这个阶段,经常发起Ajax请求)。

  4. beforeMount:当模板在内存中编译完成,此时内存中的模板结构还未渲染至页面上,看不到真实的数据。

    Create vm.$el and replace ‘el’ with it:这一步,再在把内存中渲染好的模板结构替换至真实的 dom 结构也就是页面上。

  5. mounted:此时,页面渲染好,用户看到的是真实的页面数据, 生命周期创建阶段完毕,进入到了运行中的阶段。

  6. beforeUpdate:当执行此函数,数据池的数据新的,但是页面是旧的。

    Virtual DOM re-render and patch:根据最新的 data 数据,重新渲染内存中的模板结构,并把渲染好的模板结构,替换至页面上。

  7. updated:页面已经完成了更新,此时,data 数据和页面的数据都是新的。

  8. beforeDestroy:当执行此函数时,组件即将被销毁,但是还没有真正开始销毁,此时组件的 data、methods数据或方法 还可被调用。

    Teardown…… :注销组件和事件监听。

  9. destroyed:组件已经完成了销毁。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<div id="app">
    <span id="num">{{num}}</span>
    <button @click="num++">赞!</button>
    <h2>{{name}},有{{num}}次点赞</h2>
</div>
<script src="vue.js"></script>
<script>
    let vm = new Vue({
        el: "#app",
        data: {//数据池
            name: "kristina",
            num: 0
        },
        methods: {
            show() {
                return this.name;
            },
            add() {
                this.num++;
            }
        },
        beforeCreate() {//生命周期函数-创建vue实例前
            console.log("=============beforeCreate==========");
            console.log("数据模型/数据池的数据是否加载/使用?[no]", this.name, " ", this.num);
            //console.log("自定义方法是否加载/使用?[no]", this.show());
            console.log("用户页面dom是否加载/使用?[yes]", document.getElementById("num"));
            console.log("用户页面dom是否被渲染?[no]", document.getElementById("num").innerText);
        },
        created() {//生命周期函数-创建vue实例
            console.log("=============created==========");
            console.log("数据模型/数据池的数据是否加载/使用?[yes]", this.name, " ", this.num);
            console.log("自定义方法是否加载/使用?[yes]", this.show());
            console.log("用户页面dom是否加载/使用?[yes]", document.getElementById("num"));
            console.log("用户页面dom是否被渲染?[no]", document.getElementById("num").innerText);
            //可以发出Ajax
            //接收返回的数据
            //再次去更新data数据池的数据
            //编译内存模板结构
            //.....

        },
        beforeMount() {//生命周期函数-挂载前
            console.log("=============beforeMount==========");
            console.log("数据模型/数据池的数据是否加载/使用?[yes]", this.name, " ", this.num);
            console.log("自定义方法是否加载/使用?[yes]", this.show());
            console.log("用户页面dom是否加载/使用?[yes]", document.getElementById("num"));
            console.log("用户页面dom是否被渲染?[no]", document.getElementById("num").innerText);

        },
        mounted() {//生命周期函数-挂载后
            console.log("=============mounted==========");
            console.log("数据模型/数据池的数据是否加载/使用?[yes]", this.name, " ", this.num);
            console.log("自定义方法是否加载/使用?[yes]", this.show());
            console.log("用户页面dom是否加载/使用?[yes]", document.getElementById("num"));
            console.log("用户页面dom是否被渲染?[yes]", document.getElementById("num").innerText);

        },
        beforeUpdate() {//生命周期函数-数据池数据更新前
            console.log("=============beforeUpdate==========");
            console.log("数据模型/数据池的数据是否加载/使用?[yes]", this.name, " ", this.num);
            console.log("自定义方法是否加载/使用?[yes]", this.show());
            console.log("用户页面dom是否加载/使用?[yes]", document.getElementById("num"));
            console.log("用户页面dom数据是否被更新?[no]", document.getElementById("num").innerText);
            //验证数据==>修正
            // if(this.num < 10 ) {
            //     this.num = 8;
            // }
        },
        updated() {//生命周期函数-数据池数据更新后
            console.log("=============updated==========");
            console.log("数据模型/数据池的数据是否加载/使用?[yes]", this.name, " ", this.num);
            console.log("自定义方法是否加载/使用?[yes]", this.show());
            console.log("用户页面dom是否加载/使用?[yes]", document.getElementById("num"));
            console.log("用户页面dom数据是否被更新?[yes]", document.getElementById("num").innerText);
            
        }

    })
</script>
</body>
</html>

Vue脚手架模块化开发

前置准备条件

  1. Nodejs:因为需要用到npm(node package manager),npm 是随 nodejs 安装的一款包管理工具, 类似 Maven。所以我们需要先安装 Nodejs。下载地址

    安装完成之后,使用node -v查看是否安装成功

  2. 安装webpack

    npm install webpack@4.41.2 webpack-cli -D
  3. 安装vue/cli

    npm install -g @vue/cli@4.0.3

    安装完成之后,使用vue -V查看是否安装成功

项目创建

  1. 上述条件具备之后,我们创建一个存放vue工程的目录。例如vue_project

  2. 使用cmd切换到新创建的vue工程目录

  3. 使用webpack创建vue脚手架项目

    vue init webpack vue_project
  4. 执行

    npm run dec
  5. 出现访问地址即表示创建成功

IDEA运行Vue项目

先安装一个Vue.js插件,便于IDEA识别我们的Vue项目。

将项目文件夹直接拖入IDEA即可

配置npm

点击运行之后,访问地址,出现页面即代表成功。

项目结构分析

添加自己的Vue页面

这里详细的可以去B站找视频,这里因为还未理解清楚,所以不再叙述

ElementUI组件库

详细的使用可以参考官方文档。

Axios

基本介绍

axios 是独立于 vue 的一个项目,不是 Vue 的一部分,它通常和 Vue 一起使用,实现 Ajax 操作。Axios 是一个基于 promise 的 HTTP 库

axios库文件和文档

使用

axios库文件,我们可以通过cdn来引入,也可以通过本地文件引入

演示需要用到的json文件

我们这里通过直接访问json文件的方式来模拟访问后端。

{
  "success": true,
  "message": "成功",
  "data": {
    "items": [
      {
        "name": "牛魔王",
        "age": 800
      },
      {
        "name": "红孩儿",
        "age": 500
      },
      {
        "name": "蜈蚣精",
        "age": 200
      }
    ]
  }
}
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>axios应用实例</title>
    <script type="text/javascript" src="vue.js"></script>
    <script type="text/javascript" src="axios.min.js"></script>
</head>
<body>

<div id="app">
    <h1>{{msg}}</h1>
    <table width="200px">
        <tr>
            <td>名字</td>
            <td>年龄</td>
        </tr>
        <tr v-for="monster in monsterList">
            <td>{{monster.name}}</td>
            <td>{{monster.age}}</td>
        </tr>
    </table>
</div>
<script type="text/javascript">
    new Vue({
        el: "#app",
        data: {
            msg: "妖怪列表",
            monsterList: []
        },
        methods: {
            list(){ //发送ajax请求,获取数据
                axios.get("http://localhost:63342/axios/data/response.data.json")
                .then((responseData) => {
                    console.log(responseData);
                    console.log(JSON.stringify(responseData));
                    console.log(responseData.data.data.items);
                    this.monsterList = responseData.data.data.items;
                    return axios.get("http://localhost:63342/axios/data/response.data.json");
                }).then((responseData)=>{
                    console.log("第二次",responseData)
                }).catch((err)=>{
                    console.log("异常",err);
                })
            }
        },
        created(){
            this.list();
        }
    })
</script>
</body>
</html>