Vue入门

1. MVVM 模式

1.1 MVVM 模式的概念

MVVM 是 Model-View-ViewModel 的简写。

  • M:Model,模型,包括数据和一些基本操作
  • V:View,视图,页面渲染结果
  • VM:View-Model,模型与视图间的双向操作(无需开发人员干涉)

1.2 MVVM 模式的作用

在 MVVM 之前,开发人员从后端获取需要的数据模型,然后要通过 DOM 操作 Model 渲染到 View 中。而后当用户操作视图,我们还需要通过 DOM 获取 View 中的数据,然后同步到 Model 中。

在 MVVM 中的 VM 要做的事情就是把 DOM 操作完全封装起来,开发人员不用再关心 Model 和 View 之间是如何互相影响的

  • 只要我们 Model 发生了改变,View 上自然就会表现出来。
  • 当用户修改了 View,Model 中的数据也会跟着改变。

在这里插入图片描述

1.3 MVVM 模式的应用

Vue 就是一款 MVVM 模式的框架

2. Vue 简介

Vue 是一套用于构建用户界面的渐进式框架。与其它大型框架不同的是,Vue 被设计为可以自底向上逐层应用。Vue 的核心库只关注视图层,不仅易于上手,还便于与第三方库或既有项目整合。另一方面,当与现代化的工具链以及各种支持类库结合使用时,Vue 也完全能够为复杂的单页应用提供驱动。

3. Node 和 NPM

NPM 是 Node 提供的模块管理工具,可以非常方便的下载安装很多前端框架,包括 Jquery、Angular.js、Vue.js 都有。为了后面学习方便,我们先安装 node 及 NPM 工具。

3.1 下载 Node.js

  1. 下载地址:https://nodejs.org/en/,建议下载 LTS 版本

  2. 安装完成后,打开命令提示符,查看版本信息

    node -v
    

3.2 设置 NPM 镜像仓库

  1. Node 自带了 NPM 了,打开命令提示符,查看版本信息

    npm -v
    
  2. npm 默认的仓库地址是在国外网站,速度较慢,建议设置到淘宝镜像。但是切换镜像是比较麻烦的。推荐一款切换镜像的工具 nrm。

  3. 安装 nrm,这里 -g 代表全局安装

    npm install nrm -g
    
  4. 查看 npm 的仓库列表,带 * 的就是当前选中的镜像仓库

    nrm ls
    
  5. 指定要使用的镜像源

    nrm use taobao
    
  6. 安装完成要重启下电脑

4. Vue 快速入门

4.1 创建工程

  1. 打开 IDEA

  2. Create New Project --> Empty Project --> Next

  3. 填写项目信息 --> Finish

    在这里插入图片描述

  4. New Modules --> Static Web --> Static Web --> Next

  5. 填写项目信息 --> Finish

    在这里插入图片描述

4.2 安装 Vue

  1. 点击 IDEA 中的左下角的 Teminal 按钮

  2. 进入 demo1 目录

    cd demo1
    
  3. 初始化项目(然后会在 demo1 目录生成一个 package.json 文件,它是 NodeJS 约定的用来存放项目的信息和配置等信息的文件)

    npm init -y
    
  4. 安装 Vue ,–save 代表本地安装(然后就会在 demo1 目录生成一个 node_modules 目录,并且在下面有一个 vue 目录)

    npm install vue --save
    

4.3 Vue 入门案例

4.3.1 Vue 声明式渲染

实现用 Vue 来渲染 name 这个数据

  1. 首先通过 new Vue() 来创建 Vue 实例

  2. 然后构造函数接收一个对象,对象中有一些属性:

    • el:是 element 的缩写,通过 id 选中要渲染的页面元素
    • data:数据,数据是一个对象,里面有很多属性,都可以渲染到视图中
  3. 页面中的 h1 元素中,我们通过 {{name}} 的方式,来渲染刚刚定义的 name 属性。

代码如下

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<div id="app">
    <!--花括号 js 表达式-->
    <h1>Hello {{name}}</h1>
</div>
</body>
<script src="node_modules/vue/dist/vue.js"></script>
<script>
    // 初始化一个 Vue 实例
    var app = new Vue({
        el: "#app",// Element 选择器
        data: {
            name: "Vue" // 定义数据模型
        }
    });
</script>
</html>

页面效果

在这里插入图片描述

4.3.2 双向绑定

实现 input 元素和 num 的双向绑定

  1. 我们在 data 添加了属性:num
  2. 在页面中有一个 input 元素,通过 v-model 与 num 进行绑定。
  3. 同时通过 {{num}} 在页面输出

代码如下

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<div id="app">
    <!--双向绑定,v-model:数据模型-->
    <input type="text" v-model="num">
    <h1>{{num}}</h1>
</div>
</body>
<script src="node_modules/vue/dist/vue.js"></script>
<script>
    var app = new Vue({
        el: "#app",
        data: {
            num: 100
        }
    });
</script>
</html>

实现效果

修改文本框内容,数字也会变化

在这里插入图片描述

在这里插入图片描述

4.3.3 事件处理

添加点击事件

我们在页面添加一个按钮,用 v-on 指令添加点击事件

代码如下

<!DOCTYPE html>
<html lang="en" xmlns:v-on="http://www.w3.org/1999/xhtml">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<div id="app">
    <input type="text" v-model="num">
    <!--vue-on:事件名-->
    <input type="button" value="点我加 1" v-on:click="num++">
    <h1>{{num}}</h1>
</div>
</body>
<script src="node_modules/vue/dist/vue.js"></script>
<script>
    var app = new Vue({
        el: "#app",
        data: {
            num: 100
        }
    });
</script>
</html>

点击事件也可以是一个方法

<!DOCTYPE html>
<html lang="en" xmlns:v-on="http://www.w3.org/1999/xhtml">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<div id="app">
    <input type="text" v-model="num">
    <!--vue-on:事件名-->
    <input type="button" value="点我加 1" v-on:click="increase">
    <h1>{{num}}</h1>
</div>
</body>
<script src="node_modules/vue/dist/vue.js"></script>
<script>
    var app = new Vue({
        el: "#app",
        data: {
            num: 100
        },
        methods: {
            increase() {
                this.num++;
            }
        }
    });
</script>
</html>

页面效果

在这里插入图片描述

在这里插入图片描述

5. Vue 实例

5.1 创建 Vue 实例

每个 Vue 应用都是通过用 Vue 函数创建一个新的 Vue 实例开始的

代码如下

var vm = new Vue({
  // 选项
})

Vue 实例的数据和方法

  • el
  • data
  • methods
  • 等等…

5.2 指定 HTML 模板

每个 Vue 实例都需要关联一段 HTML 模板,Vue 会基于此模板进行视图渲染,我们可以通过 el 属性来指定

代码如下

HTML 模板

<div id="app">
</div>

Vue 实例

var app = new Vue({
	el:"#app"
})

5.3 双向数据绑定

当 Vue 实例被创建时,它会尝试获取在 data 中定义的所有属性,用于视图的渲染,并且监视 data 中的属性变化,当 data 发生改变,所有相关的视图都将重新渲染,这就是"响应式"系统

代码如下

HTML 模板

<div id="app">
    <input type="text" v-model="name"/>
</div>

Vue 实例

var app = new Vue({
    el:"#app",
    data:{
        name:"Vue"
    }
})

5.4 定义方法

Vue 实例中除了可以定义 data 属性,也可以定义方法,并且在 Vue 实例的作用范围内使用

代码如下

HTML 模板

<div id="app">
    <!--vue-on:事件名-->
    <input type="button" value="点我加 1" v-on:click="increase">
    <h1>{{num}}</h1>
</div>

Vue 实例

var app = new Vue({
    el: "#app",
    data: {
        num: 100
    },
    methods: {
        increase() {
            this.num++;
        }
    }
});

5.5 生命周期钩子

5.5.1 生命周期

每个 Vue 实例在被创建时都要经过一系列的初始化过程 :创建实例,装载模板,渲染模板等等。Vue 为生命周期中的每个状态都设置了钩子函数(监听函数)。每当 Vue 实例处于不同的生命周期时,对应的钩子函数就会被触发调用

生命周期

在这里插入图片描述

5.5.2 钩子函数

一共八个钩子函数

  • beforeCreated:在实例化时调用。
  • created:在创建实例之后进行调用。
  • beforeMount:页面加载完成,没有渲染时调用。如:此时页面还是{{name}}
  • mounted:页面渲染后调用。如:此时页面中的 {{name}} 已被渲染成 Vue
  • beforeUpdate:组件更新之前调用。
  • updated:组件更新之后调用。
  • beforeDestroy:该函数将在销毁实例前调用 。
  • destroyed:改函数将在销毁实例时调用。

实例

我们可以在 Vue 中定义一个 created 函数,代表这个时期的钩子函数

<!DOCTYPE html>
<html lang="en" xmlns:v-on="http://www.w3.org/1999/xhtml">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<div id="app">
    <h1>{{num}}</h1>
</div>
</body>
<script src="node_modules/vue/dist/vue.js"></script>
<script>
    var app = new Vue({
        el: "#app",
        data: {
            num: 100
        },
        created: function () {
            this.num = 10000;
        }
    });
</script>
</html>

页面效果

在这里插入图片描述

6. 指令

6.1 指令的概念

指令 (Directives) 是带有 v- 前缀的特殊特性,主要的功能就是操作DOM

6.2 插值表达式

6.2.1 花括号

格式

{{表达式}}

说明

  • 该表达式支持 JS 语法,可以调用 JS 内置函数
  • 表达式必须有返回结果。例如:1+1,没有结果的表达式不允许使用,例如:var a = 1+1
  • 可以直接获取 Vue 实例中定义的数据或函数

实例

HTML 模板

<div id="app">
    <h1>Hello {{name}}</h1>
</div>

Vue 实例

var app = new Vue({
    el: "#app",
    data: {
        name: "Vue" 
    }
});

6.2.2 v-text 和 v-html

使用 {{}} 方式在数据未加载完成时,页面会显示出原始的 {{}},加载完毕后才显示正确数据,我们称为插值闪烁

使用 v-text 和 v-html 指令来替代 {{}},这样不会出现插值闪烁,当没有数据时,会显示空白

说明

  • v-text:将数据输出到元素内部,如果输出的数据有 HTML 代码,会作为普通文本输出
  • v-html:将数据输出到元素内部,如果输出的数据有 HTML 代码,会被渲染

实例

HTML 模板

<div id="app">
    <h1>Hello <span v-text="name"></span></h1>
    <h1>Hello <span v-html="name"></span></h1>
</div>

Vue 实例

var app = new Vue({
    el: "#app",
    data: {
        name: "<span>Vue</span>"
    }
});

页面效果

在这里插入图片描述

6.3 v-model

v-model 是双向绑定,视图(View)和模型(Model)之间会互相影响

v-model的可使用元素

  • input
  • select
  • textarea
  • checkbox
  • radio
  • components(Vue中的自定义组件)

实例

HTML 模板

<div id="app">
    <input type="checkbox" v-model="language" value="Java"/>Java<br/>
    <input type="checkbox" v-model="language" value="PHP"/>PHP<br/>
    <input type="checkbox" v-model="language" value="Swift"/>Swift<br/>
    <h1>
        你选择了:{{language.join(',')}}
    </h1>
</div>

Vue 实例

var app = new Vue({
    el: "#app",
    data: {
        language: []
    }
})

页面效果

勾选选择框后,选择内容也会变化

在这里插入图片描述

6.4 v-on

6.4.1 基本用法

v-on 指令用于给页面元素绑定事件

格式

v-on:事件名 = "js片段或函数名"

// 或简写为
@事件名 = "js片段或函数名"

6.4.2 事件修饰符

事件修饰符处理了许多 DOM 事件的细节,让我们不再需要花大量的时间去处理这些烦恼的事情,而能有更多的精力专注于程序的逻辑处理

事件修饰符

  • .stop :阻止事件冒泡到父元素
  • .prevent:阻止默认事件发生
  • .capture:使用事件捕获模式
  • .self:只有元素自身触发事件才执行。(冒泡或捕获的都不执行)
  • .once:只执行一次

实例

HTML 模板

<div id="app">
    <!--右击事件,并阻止弹出菜单-->
    <button v-on:contextmenu.prevent="num++">点我加 1</button>
    <br/>
    <h1>{{num}}</h1>
</div>

Vue 实例

var app = new Vue({
    el: "#app",
    data: {
        num: 100
    }
});

6.4.3 按键修饰符

在监听键盘事件时,我们经常需要检查常见的键值,v-on 可以在监听键盘事件时添加按键修饰符

实例

监听 Enter 键

<input v-on:keyup.enter="submit">

<!-- 缩写语法 -->
<input @keyup.enter="submit">

6.5 v-for

通过 v-for 指令来实现遍历数据渲染页面

6.5.1 遍历数组

语法

v-for = "item in items"
  • items:要遍历的数组,需要在 vue 的 data 中定义
  • item:迭代得到的数组元素的别名

实例

HTML 模板:

<div id="app">
    <ul>
        <li v-for="user in users">
            {{user.name}}-{{user.age}}-{{user.sex}}
        </li>
    </ul>
</div>

Vue 实例

var app = new Vue({
    el: "#app",
    data: {
        users: [
            {name: "张三", age: 18, sex: "男"},
            {name: "李四", age: 21, sex: "女"},
            {name: "王五", age: 24, sex: "男"}
        ]
    }
})

页面效果

在这里插入图片描述

6.5.2 数组角标

在遍历的过程中,如果我们需要知道数组角标,可以指定第二个参数 index

语法

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

实例

HTML 模板

<div id="app">
    <ul>
        <li v-for="(user,index) in users">
            {{index+1}}. {{user.name}}-{{user.age}}-{{user.sex}}
        </li>
    </ul>
</div>

Vue 实例

var app = new Vue({
    el: "#app",
    data: {
        users: [
            {name: "张三", age: 18, sex: "男"},
            {name: "李四", age: 21, sex: "女"},
            {name: "王五", age: 24, sex: "男"}
        ]
    }
})

页面效果

在这里插入图片描述

6.5.3 遍历对象

v-for 除了可以迭代数组,也可以迭代对象

语法:

v-for="value in object"
v-for="(value,key) in object"
v-for="(value,key,index) in object"
  • 1 个参数时,得到的是对象的属性值
  • 2 个参数时,第一个是属性值,第二个是属性名
  • 3 个参数时,第三个是索引,从0开始

实例

HTML 模板

<div id="app">
    <ul>
        <li v-for="(value, key, index) in user">
            {{index + 1}}. {{key}} - {{value}}
        </li>
    </ul>
</div>

Vue 实例

var app = new Vue({
    el: "#app",
    data: {
        user: {name: "张三", age: 18, sex: "男"}
    }
})

页面效果

在这里插入图片描述

6.6 v-if 和 v-show

6.6.1 v-if

v-if,条件判断。当得到结果为 true 时,所在的元素才会被渲染

语法:

v-if = "布尔表达式"

实例

HTML 模板

<div id="app">
    <button @click="show=!show">点我</button>
    <h1 v-if="show">看到我啦!</h1>
</div>

Vue 实例

var app = new Vue({
    el: "#app",
    data: {
        show: false
    }
});

页面效果

点击按钮出现内容

在这里插入图片描述

6.6.2 v-if 与 v-on 结合使用

当 v-if 和 v-for 出现在一起时,因为 v-for 优先级更高,所以会先遍历,再判断条件。

实例

HTML 模板

<div id="app">
    <ul>
        <li v-for="(user,index) in users" v-if="user.sex==''">
            {{index+1}}. {{user.name}}-{{user.age}}-{{user.sex}}
        </li>
    </ul>
</div>

Vue 实例

var app = new Vue({
    el: "#app",
    data: {
        users: [
            {name: "张三", age: 18, sex: "男"},
            {name: "李四", age: 21, sex: "女"},
            {name: "王五", age: 24, sex: "男"}
        ]
    }
})

页面效果

只显示男性用户信息

在这里插入图片描述

6.6.3 v-else-if 和 v-else

你可以使用 v-else-if 和 v-else 指令来表示 v-if 的 else 块

注意:

  • v-else-if 元素必须紧跟在带 v-if 或者 v-else-if 的元素的后面,否则它将不会被识别。
  • v-else 元素必须紧跟在带 v-if 或者 v-else-if 的元素的后面,否则它将不会被识别。

实例

HTML 模板

<div id="app">
    <button v-on:click="random=Math.random()">点我呀</button>
    <h1>random = {{random}}</h1>
    <h1 v-if="random > 0.75">
        random > 0.75
    </h1>
    <h1 v-else-if="random > 0.5">
        random > 0.5
    </h1>
    <h1 v-else-if="random > 0.25">
        random > 0.25
    </h1>
    <h1 v-else>
        random <= 0.25
    </h1>
</div>

Vue 实例

var app = new Vue({
    el: "#app",
    data: {
        random: 1
    }
})

页面效果

在这里插入图片描述

6.6.4 v-show

另一个用于根据条件展示元素的选项是 v-show 指令。与 v-if 不同的是带有 v-show 的元素始终会被渲染并保留在 DOM 中,v-show 只是简单地切换元素的 CSS 属性 display。

实例

HTML 模板

<div id="app">
    <button @click="show=!show">点我</button>
    <h1 v-show="show">看到我啦!</h1>
</div>

Vue 实例

var app = new Vue({
    el: "#app",
    data: {
        show: false
    }
});

页面效果

在这里插入图片描述

6.7 v-bind

html 属性不能使用双大括号形式绑定,只能使用 v-bind 指令。

6.7.1 绑定 style 样式

实例

HTML 模板

<div id="app">
    <input type="text" v-model="store">
    <!--v-bind:class 可以简写为 :class-->
    <input type="button" value="加入购物车" v-bind:class="{disabled: store==0}">
</div>

CSS 样式

.disabled{
    opacity: 0.6;
    cursor: not-allowed;
}

Vue 实例

var app = new Vue({
    el: "#app",
    data: {
        store: 0
    }
});

页面效果

数量为 0 时,不可以加入购物车

在这里插入图片描述

在这里插入图片描述

6.8 计算属性

在插值表达式中使用 js 表达式是非常方便的,但是如果 js 表达式的内容很长,就会显得不够优雅,Vue 中提供了计算属性,来替代复杂的 js 表达式

实例

HTML 模板

<div id="app">
    <h1>当前时间:{{now}}</h1>
</div>

Vue 实例

var app = new Vue({
    el: "#app",
    data: {
        time: 1580801398417 // 毫秒值
    },
    computed: {
        now() { // 计算属性本质是一个方法,但是必须返回结果
            const date = new Date(this.time);
            return date.toLocaleString();
        }
    }
})

页面效果

在这里插入图片描述

注意

我们可以将同一函数定义为一个方法而不是一个计算属性。两种方式的最终结果确实是完全相同的。然而,不同的是计算属性是基于它们的依赖进行缓存的。计算属性只有在它的相关依赖发生改变时才会重新求值。这就意味着只要 time 还没有发生改变,多次访问 time 计算属性会立即返回之前的计算结果,而不必再次执行函数。

6.9 watch

watch 可以让我们监控一个值的变化,从而做出相应的反应

实例

HTML 模板

<div id="app">
    <input type="text" v-model="message">
</div>

Vue 实例

var app = new Vue({
    el: "#app",
    data: {
        message: ""
    },
    watch: {
        // 第一个参数是当前的值,第二个参数是上一个的值
        message(newVal, oldVal) {
            console.log(newVal, oldVal);
        }
    }
})

页面效果

实时监控文本框输入的值

在这里插入图片描述

7. 组件化

在大型应用开发的时候,页面可以划分成很多部分。往往不同的页面,也会有相同的部分。例如可能会有相同的头部导航。但是如果每个页面都独自开发,这无疑增加了我们开发的成本。所以我们会把页面的不同部分拆分成独立的组件,然后在不同页面就可以共享这些组件,避免重复开发

7.1 全局组件

通过 Vue 的 component 方法来定义一个全局组件

实例

HTML 模板

<div id="app">
    <!--使用全局组件-->
    <counter></counter>
</div>

Vue 实例

// 定义全局组件,两个参数:1.组件名称。2.组件参数
Vue.component("counter",{
    template: "<button @click='num++'>点我 num+1, num = {{num}}</button>",
    data() {
        return {
            num:0
        }
    }
})

var app = new Vue({
    el:"#app",
})

页面效果

在这里插入图片描述

说明

  • 组件其实也是一个 Vue 实例,因此它在定义时也会接收:data、methods、生命周期函数等
  • 不同的是组件不会与页面的元素绑定,否则就无法复用了,因此没有 el 属性。
  • 但是组件渲染需要 HTML 模板,所以增加了 template 属性,值就是 HTML 模板
  • 全局组件定义完毕,任何 Vue 实例都可以直接在 HTML 中通过组件名称来使用组件了。
  • data 必须是一个函数,不再是一个对象。

7.2 组件的复用

定义好的组件,可以任意复用多次,并且每个组件之间互不干扰

实例

HTML 模板

<div id="app">
    <!--使用全局组件-->
    <counter></counter>
    <counter></counter>
    <counter></counter>
</div>

Vue 实例

// 定义全局组件,两个参数:1.组件名称。2.组件参数
Vue.component("counter",{
    template: "<button @click='num++'>点我 num+1, num = {{num}}</button>",
    data() {
        return {
            num:0
        }
    }
})

var app = new Vue({
    el:"#app",
})

页面效果

每个 counter 之间互不影响

在这里插入图片描述

说明

当我们定义 counter 组件时,它的 data 并不是像之前直接提供一个对象:

data: {
  num: 0
}

取而代之的是,一个组件的 data 是一个函数,因此每个实例可以维护一份被返回对象的独立的拷贝:

data() {
    return {
        num:0
    }
}

7.3 局部组件

定义全局组件,就意味着即便以后你不再使用这个组件,它依然会随着 Vue 的加载而加载。因此,对于一些并不频繁使用的组件,我们会采用定义局部组件

实例

HTML 模板

<div id="app">
    <!--使用局部组件-->
    <count></count>
</div>

Vue 实例

// 定义局部组件,结构就是全局组件的第二个参数
var count = {
    template: "<button @click='num++'>点我 num+1, num = {{num}}</button>",
    data() {
        return {
            num: 0
        }
    }
}

var app = new Vue({
    el: "#app",
    components:{
        // 将定义的对象注册为组件
        count:count
    }
})

页面效果

在这里插入图片描述

说明

  • components 就是当前 Vue 对象子组件集合。
    • key 就是子组件名
    • value 就是组件对象名
  • 效果与刚才的全局注册是类似的,不同的是,这个 counter 组件只能在当前的 Vue 实例中使用

7.4 组件通信

通常一个单页应用会以一棵嵌套的组件树的形式来组织:

在这里插入图片描述

  • 页面首先分成了顶部导航、左侧内容区、右侧边栏三部分
  • 左侧内容区又分为上下两个组件
  • 右侧边栏中又包含了3个子组件

各个组件之间以嵌套的关系组合在一起,那么这个时候不可避免的会有组件间通信的需求

7.4.1 父组件向子组件的通信

说明

  1. 在父组件中,自定义属性(属性名任意,属性值为要传递的数据)
  2. 子组件通过 props 接收父组件数据,通过自定义属性的属性名

实例

HTML 模板

<div id="app">
    <!--在父组件中,自定义属性-->
    <hello title="Hello Vue !"></hello>
</div>

Vue 实例

// 子组件
Vue.component("hello",{
    template: "<h1>{{title}}</h1>", // 直接使用 props 接收到的属性来渲染页面
    props:["title"] // 通过 props 来接收一个父组件传递的属性
})

// 父组件
var app = new Vue({
    el: "#app"
})

页面效果

在这里插入图片描述

7.4.2 动态传递和静态传递

给 prop 传入一个静态的值:

<hello title="Hello Vue !"></hello>

给 prop 传入一个动态的值:

<hello :title="42" ></hello>

注意:静态传递的值都是字符串类型的,动态传递的值会解析为 JS 表达式

7.4.3 子组件向父组件的通信

子组件接收到父组件属性后,默认是不允许修改的。既然只有父组件能修改,那么修改的函数一定是放在父组件。子组件来调用父组件的函数,该怎么做呢?

说明

vue 提供了一个内置的 this.$emit() 函数,用来调用父组件绑定的函数

实例

HTML 模板

<div id="app">
    <h1>num: {{num}}</h1>
    <!--父组件调用父组件中方法-->
    <counter @add="superAdd"></counter>
</div>

Vue 实例

// 子组件
Vue.component("counter",{
    // 子组件调用子组件中方法
    template: "<button @click='subAdd'>点我num++</button>",
    methods: {
        subAdd() {
            // 子组件调用父组件的方法,值是自定义事件名
            this.$emit("add")
        }
    }
})

// 父组件
var app = new Vue({
    el: "#app",
    data: {
        num: 0
    },
    methods: {
        superAdd() {
            this.num++;
        }
    }
})

页面效果

在这里插入图片描述

8. 路由

现在我们来实现这样一个功能:

一个页面,包含登录和注册,点击不同按钮,实现登录页和注册页切换

8.1 初步实现

代码如下

  1. 编写登录组件

    const loginForm = {
        template: `
          <div>
            <h2>登录页</h2>
            用户名:<input type="text"><br>
            密&emsp;码:<input type="password"><br>
            <input type="button" value="登录">
          </div>  
        `,
    }
    
  2. 编写注册组件

    const registerForm = {
        template: `
          <div>
            <h2>注册页</h2>
            用&ensp;户&ensp;名:<input type="text"><br>
            密&emsp;&emsp;码:<input type="password"><br>
            确认密码:<input type="password"><br>
            <input type="button" value="注册">
          </div>  
        `,
    }
    
  3. 编写父组件,并引入登录注册组件

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
    </head>
    <body>
        <div id="app">
            <span>登录</span>
            <span>注册</span>
            <hr>
            <login-Form></login-Form>
            <register-Form></register-Form>
        </div>
    </body>
    <script src="../node_modules/vue/dist/vue.js"></script>
    <script src="js/loginForm.js"></script>
    <script src="js/registerForm.js"></script>
    <script>
        var app = new Vue({
            el: "#app",
            components: {
                loginForm,
                registerForm
            }
        })
    </script>
    </html>
    

页面效果

在这里插入图片描述

8.2 进一步实现

现在登录页和注册页都有了,但它们现在是一起显示的。我希望的是点击登录和注册两个按钮,能够实现在登录页和注册页之间切换。

但是如何才能动态加载组件,实现组件切换呢?我们可以使用 vue-router 模块。

安装 vue-router

  1. 点击 IDEA 中的左下角的 Teminal 按钮

  2. 安装 vue-router

    npm install vue-router --save
    

代码如下

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<div id="app">
    <!--router-link 指定跳转路径-->
    <span><router-link to="/login">登录</router-link></span>
    <span><router-link to="/register">注册</router-link></span>
    <hr>
    <router-view></router-view>
</div>
</body>
<script src="../node_modules/vue/dist/vue.js"></script>
<script src="../node_modules/vue-router/dist/vue-router.js"></script>
<script src="js/loginForm.js"></script>
<script src="js/registerForm.js"></script>
<script>
    // 创建 VueRouter 对象
    const router = new VueRouter({
        // 路由规则
        routes: [
            {
                path: "/login", // 请求路径
                component: loginForm // 组件名称
            },
            {
                path: "/register",
                component: registerForm
            }
        ]
    })

    var app = new Vue({
        el: "#app",
        // 引用 router 对象
        router
    })
</script>
</html>

页面效果

在这里插入图片描述

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

bm1998

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值