Vue快速入门(从入门到实战)(IDEA版)一篇文章即可快速入门(可直接开发前后端分离项目)

一、Vue快速入门

2008年,google的Chrome发布,随后就以极快的速度占领市场,超过IE成为浏览器市场的主导者。

2009年,Ryan Dahl在谷歌的Chrome v8引擎基础上,打造了基于事件循环的异步IO框架:Node.js。

基于时间循环的异步lO

单线程运行,避免多线程的变量同步问题
JS可以编写后台diamante,前后台统━编程语言
node.js的伟大之处不在于让JS迈向了后端开发,而是构建了一个庞大的生态系统。

2010年,NPM作为node.js的包管理系统首次发布,开发人员可以遵循Common.js规范来编写Node.js模块,然后发布到NPM上供其他开发人员使用。
目前已经是世界最大的包模块管理系统。

随后,在node的基础上,涌现出了一大批的前端框架:

在这里插入图片描述

MVVM模式

M:即Model,模型,包括数据和一些基本操作

V:即View,视图,页面渲染结果

VM:即View-Model,模型与视图间的双向操作(无需开发人员干涉)

在MWM之前,开发人员从后端获取需要的数据模型,然后要通过DOM操作Model渲染到View中。

而后当用户操作视图,我们还需要通过DOM获取View中的数据,然后同步到Model中。

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

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

把开发人员从繁琐的DOM操作中解放出来,把关注点放在如何操作Model上。
在这里插入图片描述
而我们今天要学习的,就是一款MVVM模式的框架:Vue

1、认识Vue

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

https://cn.vuejs.org/

在这里插入图片描述

2、安装Node.js
(1)进入Node.js官网https://nodejs.org/zh-cn/

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
然后install安装即可在这里插入图片描述

安装完成
控制台测试
输入node-v然后回车
在这里插入图片描述

2、NPM

npm版本输入npm -v然后回车
在这里插入图片描述
npm默认的仓库地址是在国外网站,速度较慢,建议大家设置到淘宝镜像。
但是切换镜像是比较麻烦的正-推荐切换镜像的工具:nrm

我们首先安装nrm,这里-g代表全局安装

npm install nrm -g

在这里插入图片描述

输入:nrm ls报错

在这里插入图片描述
找到该文件C:\Users\ZHENG\AppData\Roaming\npm\node_modules\nrm
在这里插入图片描述
在这里插入图片描述

//const NRMRC = path.join(process.env.HOME, '.nrmrc'); (删除)
const NRMRC = path.join(process.env[(process.platform == 'win32') ? 'USERPROFILE' : 'HOME'], '.nrmrc');

继续输入nrm ls
在这里插入图片描述

切换淘宝镜像nrm use taobao
在这里插入图片描述
测试一下nrm test taobao
在这里插入图片描述

二、工程案例

1、创建工程

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

2、安装Vue

在IDEA的终端当中
在这里插入图片描述
在终端上输入:npm init -y报错
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

(1)初始化项目
npm init -y

在这里插入图片描述

在这里插入图片描述

(2)安装Vue

只再当前项目安装Vue:npm install vue --save
在这里插入图片描述
打开下面内容证明安装完成
在这里插入图片描述

3、创建HTML文件
(1)编写基本的HTML页面

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

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <div>
        <h1>
            xxx非常美丽!
        </h1>
    </div>
<script src="node_modules/vue/dist/vue.js"></script>
<script>
</script>
</body>
</html>

运行查看一下
在这里插入图片描述
在这里插入图片描述

(2)使用Vue

a、定义属性

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

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

  • el:是element的缩写,通过id选中要渲染的页面元素,本例中是一个div
  • data:数据,数据是一个对象,里面有很多属性,都可以渲染到视图中
  • name:这里我们指定了一个name属性

页面中的h2元素中,我们通过{{name)}的方式,来渲染刚刚定义的name属性。

在这里插入图片描述

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <div id="app">
        <h1>
           {{name}} xxx非常美丽!
        </h1>
    </div>
<script src="node_modules/vue/dist/vue.js"></script>
<script>
    const app = new Vue({
        el:"#app",//elemnet,vue 作用的标签
        data:{
            name:"虎哥"
        }
    });
</script>
</body>
</html>

运行测试
在这里插入图片描述
在这里插入图片描述
在谷歌浏览器控制台
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <div id="app">
        <h1>
           {{name}} xxx非常美丽!<br>
            {{num}} 位其着迷!
        </h1>
    </div>
<script src="node_modules/vue/dist/vue.js"></script>
<script>
    const app = new Vue({
        el:"#app",//elemnet,vue 作用的标签
        data:{
            name:"虎哥",
            num: 1,
        }
    });
</script>
</body>
</html>

在这里插入图片描述

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <div id="app">
        <input type="text" v-model="num" />
        <h1>
           {{name}} xxx非常美丽!<br>
            {{num}} 位其着迷!
        </h1>
    </div>
<script src="node_modules/vue/dist/vue.js"></script>
<script>
    const app = new Vue({
        el:"#app",//elemnet,vue 作用的标签
        data:{
            name:"虎哥",
            num: 1,
        }
    });
</script>
</body>
</html>

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

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <div id="app">
        <input type="text" v-model="num" /><button @click="num++">+</button>
        <h1>
           {{name}} xxx非常美丽!<br>
            {{num}} 位其着迷!
        </h1>
    </div>
<script src="node_modules/vue/dist/vue.js"></script>
<script>
    const app = new Vue({
        el:"#app",//elemnet,vue 作用的标签
        data:{
            name:"虎哥",
            num: 1,
        }
    });
</script>
</body>
</html>

在这里插入图片描述
b、定义属性
在这里插入图片描述

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <div id="app">
        <button @click="handleClick">点我</button><br>
        <input type="text" v-model="num" /><button @click="num++">+</button>
        <h1>
           {{name}} xxx非常美丽!<br>
            {{num}} 位其着迷!
        </h1>
    </div>
<script src="node_modules/vue/dist/vue.js"></script>
<script>
    const app = new Vue({
        el:"#app",//elemnet,vue 作用的标签
        data:{
            name:"虎哥",
            num: 1,
        },
        methods : {
            handleClick(){
                console.log("hello");
            }
        }
    });
</script>
</body>
</html>

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

三、Vue生命周期(钩子)

每个Vue实例在被创建时都要经过一系列的初始化过程︰

创建实例,装载模板,渲染模板等等。Vue为生命周期中的每个状态都设置了钩子函数(监听函数)。

每当Vue实例处于不同的生命周期时,对应的函数就会被触发调用。

1、生命周期:

在这里插入图片描述

2、渲染数据:钩子函数

例如: created代表在vue实例创建后;
我们可以在Vue中定义一个created函数,代表这个时期的构造函数;

在这里插入图片描述

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <div id="app">
        <button @click="handleClick">点我</button><br>
        <input type="text" v-model="num" /><button @click="num++">+</button>
        <h1>
           {{name}} xxx非常美丽!<br>
            {{num}} 位其着迷!
        </h1>
    </div>
<script src="node_modules/vue/dist/vue.js"></script>
<script>
    const app = new Vue({
        el:"#app",//elemnet,vue 作用的标签
        data:{
            name:"",
            num: 1,
        },
        methods : {
            handleClick(){
                console.log(this)
                console.log("hello");
            }
        },
        created(){
            //向后台发起Ajax请求,完成对data数据初始化
            this.name = "虎哥";
        }
    });
</script>
</body>
</html>

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

3、模拟实际渲染数据:this 我们可以看下在vue内部的this变量是谁,我们在created的时候,打印this

在这里插入图片描述

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <div id="app">
        <button @click="handleClick">点我</button><br>
        <input type="text" v-model="num" /><button @click="num++">+</button>
        <h1>
           {{name}} xxx非常美丽!<br>
            {{num}} 位其着迷!
        </h1>
    </div>
<script src="node_modules/vue/dist/vue.js"></script>
<script>
    const app = new Vue({
        el:"#app",//elemnet,vue 作用的标签
        data:{
            name:"",
            num: 1,
        },
        methods : {
            handleClick(){
                console.log(this)
                console.log("hello");
            }
        },
        created(){
            //向后台发起Ajax请求,完成对data数据初始化
            setTimeout(() => this.name = "虎哥 真的",1000)
        }
    });
</script>
</body>
</html>

在这里插入图片描述
延时一秒
在这里插入图片描述
总结: this就是当前的Vue实例,在Vue对象内部,必须使用this才能访问到Vue中定义的data内属性、方法等。

四、指令

什么是指令?
指令(Directives)是带有 v-前缀的特殊属性。

例如我们在入门案例中的v-model,代表双向绑定。

1、插值表达式
(1)花括号

格式:

{{表达式}}

说明;

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

示例
HTML:

<div id= " app">i{name ) )</div>

JS:

var app =new vue({
	el:"#app",
	data:{
		name:"Jack""
	}
})
2、差值闪烁

使用0方式在网速较慢时会出现问题。在数据未加载完成时,页面会显示出原始的

{{}}

加载完毕后才显示正确数据,我们称为插值闪烁。

我们将网速调慢一些,然后试试看刚才的案例:

在这里插入图片描述
刷新页面有延迟

3、使用v-text和v-html

使用v-textv-html指令来替代{{}}说明:

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

在这里插入图片描述

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <div id="app">
        <button @click="handleClick">点我</button><br>
        <input type="text" v-model="num" /><button @click="num++">+</button>
        <h1>
           <span v-text="name"></span> xxx非常美丽!<br>
            {{num}} 位其着迷!
        </h1>
    </div>
<script src="node_modules/vue/dist/vue.js"></script>
<script>
    const app = new Vue({
        el:"#app",//elemnet,vue 作用的标签
        data:{
            name:"",
            num: 1,
        },
        methods : {
            handleClick(){
                console.log(this)
                console.log("hello");
            }
        },
        created(){
            //向后台发起Ajax请求,完成对data数据初始化
            this.name = "虎哥 真的",1000;
        }
    });
</script>
</body>
</html>

运行测试
在这里插入图片描述

v-html:将数据输出到元素内部,如果输出的数据有HTML代码,会被渲染
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
从上述结果当中似乎没有什么区别
以下继续修改代码
在这里插入图片描述

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <div id="app">
        <button @click="handleClick">点我</button><br>
        <input type="text" v-model="num" /><button @click="num++">+</button>
        <h1>
           <span v-text="name"></span> xxx非常美丽!<br>
            {{num}} 位其着迷!
        </h1>
        <span v-text="name"></span><br>
        <span v-html="name"></span>
    </div>
<script src="node_modules/vue/dist/vue.js"></script>
<script>
    const app = new Vue({
        el:"#app",//elemnet,vue 作用的标签
        data:{
            name:"",
            num: 1,
        },
        methods : {
            handleClick(){
                console.log(this)
                console.log("hello");
            }
        },
        created(){
            //向后台发起Ajax请求,完成对data数据初始化
            this.name = "<font color='#8a2be2'>虎哥<font>";
        }
    });
</script>
</body>
</html>

在这里插入图片描述
v-text:将数据输出到元素内部,如果输出的数据有HTML代码,会作为普通文本输出
v-html:将数据输出到元素内部,如果输出的数据有HTML代码,会被渲染

4、v-model

刚才的v-text和v-html可以看做是单向绑定,数据影响了视图渲染,但是反过来就不行。

接下来学习的v-model是双向绑定,视图(view)和模型(Model)之间会互相影响。

既然是双向绑定,一定是在视图中可以修改数据,这样就限定了视图的元素类型。

目前v-model的可使用元素有:

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

在这里插入图片描述

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <div id="app">
        <button @click="handleClick">点我</button><br>
        <input type="text" v-model="num" /><button @click="num++">+</button>
        <h1>
           <span v-text="name"></span> xxx非常美丽!<br>
            {{num}} 位其着迷!
        </h1>
        <span v-text="name"></span><br>
        <span v-html="name"></span>

        <hr/>
        <h1>编程语言分类</h1>
        <input type="checkbox" v-model="lessons" value="Java" />Java <br/>
        <input type="checkbox" v-model="lessons" value="JavaScript" />JavaScript <br/>
        <input type="checkbox" v-model="lessons" value="Python" />Python <br/>
        <h1>
            您已购买下列课程:{{lessons.join(",")}}
        </h1>

    </div>
<script src="node_modules/vue/dist/vue.js"></script>
<script>
    const app = new Vue({
        el:"#app",//elemnet,vue 作用的标签
        data:{
            name:"",
            num: 1,
            lessons: []
        },
        methods : {
            handleClick(){
                console.log(this)
                console.log("hello");
            }
        },
        created(){
            //向后台发起Ajax请求,完成对data数据初始化
            this.name = "<font color='#8a2be2'>虎哥<font>";
        }
    });
</script>
</body>
</html>

运行查看
在这里插入图片描述

5、v-on
(1)基本用法

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

语法:

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

简写语法:

@事件名="js片段或函数名“

例如v-on:click='add'可以简写为@click='add'

示例:
在这里插入图片描述

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

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <div id="app">
        <button @click="handleClick">点我</button><br>
        <input type="text" v-model="num" /><button @click="num++">+</button>
        <button @click="decrement">-</button>
        <h1>
           <span v-text="name"></span> xxx非常美丽!<br>
            {{num}} 位其着迷!
        </h1>
        <span v-text="name"></span><br>
        <span v-html="name"></span>

        <hr/>
        <h1>编程语言分类</h1>
        <input type="checkbox" v-model="lessons" value="Java" />Java <br/>
        <input type="checkbox" v-model="lessons" value="JavaScript" />JavaScript <br/>
        <input type="checkbox" v-model="lessons" value="Python" />Python <br/>
        <h1>
            您已购买下列课程:{{lessons.join(",")}}
        </h1>
    </div>
<script src="node_modules/vue/dist/vue.js"></script>
<script>
    const app = new Vue({
        el:"#app",//elemnet,vue 作用的标签
        data:{
            name:"",
            num: 1,
            lessons: []
        },
        methods : {
            handleClick(){
                console.log(this)
                console.log("hello");
            },
            decrement(){
                this.num--;
            }
        },
        created(){
            //向后台发起Ajax请求,完成对data数据初始化
            this.name = "<font color='#8a2be2'>虎哥<font>";
        }
    });
</script>
</body>
</html>

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

(2)点击事件(包含关系(冒泡))

在这里插入图片描述

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <div id="app">
        <button @click="handleClick">点我</button><br>
        <input type="text" v-model="num" /><button @click="num++">+</button>
        <button @click="decrement">-</button>
        <h1>
           <span v-text="name"></span> xxx非常美丽!<br>
            {{num}} 位其着迷!
        </h1>
        <span v-text="name"></span><br>
        <span v-html="name"></span>

        <hr/>
        <h1>编程语言分类</h1>
        <input type="checkbox" v-model="lessons" value="Java" />Java <br/>
        <input type="checkbox" v-model="lessons" value="JavaScript" />JavaScript <br/>
        <input type="checkbox" v-model="lessons" value="Python" />Python <br/>
        <h1>
            您已购买下列课程:{{lessons.join(",")}}
        </h1>

        <hr/>
        <!--v-on-->
        <div style="width: 100px; height: 100px; background-color:indianred; " @click="print('div')">
            div
            <button @click="print('button')">点我试试</button>
        </div>
    </div>
<script src="node_modules/vue/dist/vue.js"></script>
<script>
    const app = new Vue({
        el:"#app",//elemnet,vue 作用的标签
        data:{
            name:"",
            num: 1,
            lessons: []
        },
        methods : {
            handleClick(){
                console.log(this)
                console.log("hello");
            },
            decrement(){
                this.num--;
            },print(msg){
                console.log(msg)
            }
        },
        created(){
            //向后台发起Ajax请求,完成对data数据初始化
            this.name = "<font color='#8a2be2'>虎哥<font>";
        }
    });
</script>
</body>
</html>

点击内部同时触发两个
在这里插入图片描述
点击外面触发一个事件
在这里插入图片描述

(3)点击事件(设置不自动包含关系(停止冒泡))

在这里插入图片描述

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <div id="app">
        <button @click="handleClick">点我</button><br>
        <input type="text" v-model="num" /><button @click="num++">+</button>
        <button @click="decrement">-</button>
        <h1>
           <span v-text="name"></span> xxx非常美丽!<br>
            {{num}} 位其着迷!
        </h1>
        <span v-text="name"></span><br>
        <span v-html="name"></span>

        <hr/>
        <h1>编程语言分类</h1>
        <input type="checkbox" v-model="lessons" value="Java" />Java <br/>
        <input type="checkbox" v-model="lessons" value="JavaScript" />JavaScript <br/>
        <input type="checkbox" v-model="lessons" value="Python" />Python <br/>
        <h1>
            您已购买下列课程:{{lessons.join(",")}}
        </h1>

        <hr/>
        <!--v-on-->
        <div style="width: 100px; height: 100px; background-color:indianred; " @click.stop="print('div')">
            div
            <button @click.stop="print('button')">点我试试</button>
        </div>
    </div>
<script src="node_modules/vue/dist/vue.js"></script>
<script>
    const app = new Vue({
        el:"#app",//elemnet,vue 作用的标签
        data:{
            name:"",
            num: 1,
            lessons: []
        },
        methods : {
            handleClick(){
                console.log(this)
                console.log("hello");
            },
            decrement(){
                this.num--;
            },print(msg){
                console.log(msg)
            }
        },
        created(){
            //向后台发起Ajax请求,完成对data数据初始化
            this.name = "<font color='#8a2be2'>虎哥<font>";
        }
    });
</script>
</body>
</html>

在这里插入图片描述
在这里插入图片描述
现在这种情况只需要添加一个即可
在这里插入图片描述

(4)事件修饰符

在事件处理程序中调用event.preventDefault()event.stopPropagation())是非常常见的需求。

尽管我们可以在方法中轻松实现这点,但更好的方式是:方法只有纯粹的数据逻辑,而不是去处理DOM事件细节。

为了解决这个问题,Vue.js 为v-on提供了事件修饰符。

之前提过,修饰符是由点开头的指令后缀来表示的

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

阻止a标签跳转
在这里插入图片描述

<a href="http://www.baidu.com" @click.prevent="print('百度')">百度一下,你就疯了!</a>

在这里插入图片描述

7、v-for

遍历数据渲染页面是非常常用的需求,Vue中通过v-for指令来实现。

(1)遍历数组

语法:

v-for="item in items ""
  • items:要遍历的数组,需要在vue的data中定义好。
  • item:迭代得到的数组元素的别名
    示例:
    在这里插入图片描述
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <div id="app">
        <button @click="handleClick">点我</button><br>
        <input type="text" v-model="num" /><button @click="num++">+</button>
        <button @click="decrement">-</button>
        <h1>
           <span v-text="name"></span> xxx非常美丽!<br>
            {{num}} 位其着迷!
        </h1>
        <span v-text="name"></span><br>
        <span v-html="name"></span>

        <hr/>
        <h1>编程语言分类</h1>
        <input type="checkbox" v-model="lessons" value="Java" />Java <br/>
        <input type="checkbox" v-model="lessons" value="JavaScript" />JavaScript <br/>
        <input type="checkbox" v-model="lessons" value="Python" />Python <br/>
        <h1>
            您已购买下列课程:{{lessons.join(",")}}
        </h1>

        <hr/>
        <!--v-on-->
        <div style="width: 100px; height: 100px; background-color:indianred; " @click="print('div')">
            div
            <button @click.stop="print('button')">点我试试</button>

        </div>
        <a href="http://www.baidu.com" @click.prevent="print('百度')">百度一下,你就疯了!</a>

        <hr>
        <!--v-for-->
        <ul>
            <li v-for="u in users">
                {{u.name + "," + u.gender + ","+ u.age }}
            </li>
        </ul>
    </div>
<script src="node_modules/vue/dist/vue.js"></script>
<script>
    const app = new Vue({
        el:"#app",//elemnet,vue 作用的标签
        data:{
            name:"",
            num: 1,
            lessons: [],
            users:[
                {name:'柳岩',gender:'女',age:21},
                {name:'虎哥',gender:'男',age:30},
                {name:'范冰冰',gender:'女',age:24},
                {name:'刘亦菲',gender:'女',age:18},
                {name:'古力娜扎',gender:'女',age:25}
            ]
        },
        methods : {
            handleClick(){
                console.log(this)
                console.log("hello");
            },
            decrement(){
                this.num--;
            },print(msg){
                console.log(msg)
            }
        },
        created(){
            //向后台发起Ajax请求,完成对data数据初始化
            this.name = "<font color='#8a2be2'>虎哥<font>";
        }
    });
</script>
</body>
</html>

运行结果
在这里插入图片描述

(2)遍历数组:多个参数(数组角标)

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

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

在这里插入图片描述

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <div id="app">
        <button @click="handleClick">点我</button><br>
        <input type="text" v-model="num" /><button @click="num++">+</button>
        <button @click="decrement">-</button>
        <h1>
           <span v-text="name"></span> xxx非常美丽!<br>
            {{num}} 位其着迷!
        </h1>
        <span v-text="name"></span><br>
        <span v-html="name"></span>

        <hr/>
        <h1>编程语言分类</h1>
        <input type="checkbox" v-model="lessons" value="Java" />Java <br/>
        <input type="checkbox" v-model="lessons" value="JavaScript" />JavaScript <br/>
        <input type="checkbox" v-model="lessons" value="Python" />Python <br/>
        <h1>
            您已购买下列课程:{{lessons.join(",")}}
        </h1>

        <hr/>
        <!--v-on-->
        <div style="width: 100px; height: 100px; background-color:indianred; " @click="print('div')">
            div
            <button @click.stop="print('button')">点我试试</button>

        </div>
        <a href="http://www.baidu.com" @click.prevent="print('百度')">百度一下,你就疯了!</a>

        <hr>
        <!--v-for-->
        <ul>
            <li v-for="(u,i) in users">
              {{i}}  {{u.name + "," + u.gender + ","+ u.age }}
            </li>
        </ul>
    </div>
<script src="node_modules/vue/dist/vue.js"></script>
<script>
    const app = new Vue({
        el:"#app",//elemnet,vue 作用的标签
        data:{
            name:"",
            num: 1,
            lessons: [],
            users:[
                {name:'柳岩',gender:'女',age:21},
                {name:'虎哥',gender:'男',age:30},
                {name:'范冰冰',gender:'女',age:24},
                {name:'刘亦菲',gender:'女',age:18},
                {name:'古力娜扎',gender:'女',age:25}
            ]
        },
        methods : {
            handleClick(){
                console.log(this)
                console.log("hello");
            },
            decrement(){
                this.num--;
            },print(msg){
                console.log(msg)
            }
        },
        created(){
            //向后台发起Ajax请求,完成对data数据初始化
            this.name = "<font color='#8a2be2'>虎哥<font>";
        }
    });
</script>
</body>
</html>

在这里插入图片描述

(3)遍历对象

在这里插入图片描述

        <ul>
            <li v-for="u in users[0]">
                {{u}}
            </li>
        </ul>

在这里插入图片描述

(4)遍历对象:多个参数

在这里插入图片描述


        <ul>
            <li v-for="(u,i) in users[0]">
                {{u + "," + i }}
            </li>
        </ul>

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

     <ul>
            <li v-for="(v,k,i) in users[0]">
                {{i +"_"+ v + "," + k }}
            </li>
        </ul>

在这里插入图片描述

(5)遍历数字

在这里插入图片描述

		 <ul>
            <li v-for="i in 5">
                {{i}}
            </li>
        </ul>

在这里插入图片描述

8、key

当Vue.js用v-for 正在更新已渲染过的元素列表时,它默认用"就地复用"策略。

如果数据项的顺序被改变,Vue将不会移动DOM元素来匹配数据项的顺序,而是简单复用此处每个元素,并且确保它在特定索引下显示已被渲染过的每个元素。

这个功能可以有效的提高渲染的效率。

但是要实现这个功能,你需要给Vue一些提示,以便它能跟踪每个节点的身份,从而重用和重新排序现有元素

需要为每项提供一个唯一 key属性。理想的key值是每项都有的且唯一的id

提升加载数据的速度
在这里插入图片描述

		 <!--v-for-->
        <ul>
            <li v-for="(u,i) in users" :key="u.name">
              {{i}}  {{u.name + "," + u.gender + ","+ u.age }}
            </li>
        </ul>

在这里插入图片描述
绑定数组的角标
在这里插入图片描述

		 <!--v-for-->
        <ul>
            <li v-for="(u,i) in users" :key="i">
              {{i}}  {{u.name + "," + u.gender + ","+ u.age }}
            </li>
        </ul>

在这里插入图片描述

9、v-if和v-show

v-if,顾名思义,条件判断。当得到结果为true时,所在的元素才会被渲染。
语法:

v-if”布尔表达式”

实例:

在这里插入图片描述

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <div id="app">
        <button @click="handleClick">点我</button><br>
        <input type="text" v-model="num" /><button @click="num++">+</button>
        <button @click="decrement">-</button>
        <h1>
           <span v-text="name"></span> xxx非常美丽!<br>
            {{num}} 位其着迷!
        </h1>
        <span v-text="name"></span><br>
        <span v-html="name"></span>

        <hr/>
        <h1>编程语言分类</h1>
        <input type="checkbox" v-model="lessons" value="Java" />Java <br/>
        <input type="checkbox" v-model="lessons" value="JavaScript" />JavaScript <br/>
        <input type="checkbox" v-model="lessons" value="Python" />Python <br/>
        <h1>
            您已购买下列课程:{{lessons.join(",")}}
        </h1>

        <hr/>
        <!--v-on-->
        <div style="width: 100px; height: 100px; background-color:indianred; " @click="print('div')">
            div
            <button @click.stop="print('button')">点我试试</button>

        </div>
        <a href="http://www.baidu.com" @click.prevent="print('百度')">百度一下,你就疯了!</a>

        <hr>
        <!--v-for-->
        <ul>
            <li v-for="(u,i) in users" :key="i">
              {{i}}  {{u.name + "," + u.gender + ","+ u.age }}
            </li>
        </ul>

        <ul>
            <li v-for="(v,k,i) in users[0]">
                {{i +"_"+ v + "," + k }}
            </li>
        </ul>
        <ul>
            <li v-for="i in 5">
                {{i}}
            </li>
        </ul>
        <hr/>
        <!--v-if-->
        <button @click="show != show">点击切换</button><br>
        <h1 v-if="show">
            你好
        </h1>
    </div>
<script src="node_modules/vue/dist/vue.js"></script>
<script>
    const app = new Vue({
        el:"#app",//elemnet,vue 作用的标签
        data:{
            name:"",
            num: 1,
            lessons: [],
            users:[
                {name:'柳岩',gender:'女',age:21},
                {name:'虎哥',gender:'男',age:30},
                {name:'范冰冰',gender:'女',age:24},
                {name:'刘亦菲',gender:'女',age:18},
                {name:'古力娜扎',gender:'女',age:25}
            ],
            show: true,
        },
        methods : {
            handleClick(){
                console.log(this)
                console.log("hello");
            },
            decrement(){
                this.num--;
            },print(msg){
                console.log(msg)
            }
        },
        created(){
            //向后台发起Ajax请求,完成对data数据初始化
            this.name = "<font color='#8a2be2'>虎哥<font>";
        }
    });
</script>
</body>
</html>

在页面上
在这里插入图片描述
点击以后你好消失(点击后触发事件将show改为false)
在这里插入图片描述

10、v-if与v-for结合以及v-else
(1)v-if

当v-if和v-for出现在一起时,v-for优先级更高。

也就是说,会先遍历,再判断条件。

示例:
在这里插入图片描述

  <ul>
        <li v-for="i in 5" v-if="i%2 === 0"  >
             {{i}}
        </li>
  </ul>

在这里插入图片描述

(2)v-else

在这里插入图片描述

 		<ul>
            <li v-for="i in 5">
                <span v-if="i%2 === 0">偶数: {{i}} </span>
                <span v-else style="background-color:#cccccc;">奇数: {{i}} </span><br>
            </li>
        </ul>

在这里插入图片描述

11、v-show

对比v-if和v-show
在这里插入图片描述

		 <h1 v-if="show">
            你好
        </h1>
        <h1 v-show="show">
            你很好,我记住了!
        </h1>

运行效果
在这里插入图片描述
消失
在这里插入图片描述
上述从外表看起来没有什么区别

但是打开检查我们发现

点击之前

在这里插入图片描述
点击之后,发现v-if是直接删除结点而v-show是设置style属性display:none隐藏属性
在这里插入图片描述

12、v-bind
(1)创建新的HTML页面

在这里插入图片描述

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <div id="app">



    </div>
<script src="node_modules/vue/dist/vue.js"></script>
<script>
    const app = new Vue({
        el:"#app",//elemnet,vue 作用的标签
        data:{

        }
    });
</script>
</body>
</html>
(2)编写CSS样式和HTML

在这里插入图片描述

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <style type="text/css">
        div #box{
            width:100px;
            height: 100px;
            color: darkgray;
        }
        .red{
            background-color: red;
        }
        .blue{
            background-color: blue;
        }
    </style>
</head>
<body>
    <div id="app">
        <button>红色</button>
        <button>蓝色</button>
        <div id="box" class="red">
            我是盒子
            我是盒子
        </div>
    </div>
<script src="node_modules/vue/dist/vue.js"></script>
<script>
    const app = new Vue({
        el:"#app",//elemnet,vue 作用的标签
        data:{

        }
    });
</script>
</body>
</html>
(3)添加点击切换图片的事件

a、按照上述正常的解决思维是用差值表达式是这样解决的
在这里插入图片描述

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <style type="text/css">
        div #box{
            width:100px;
            height: 100px;
            color: darkgray;
        }
        .red{
            background-color: red;
        }
        .blue{
            background-color: blue;
        }
    </style>
</head>
<body>
    <div id="app">
        <button @click="color='red'">红色</button>
        <button @click="color='blue'">蓝色</button>
        <div id="box" class="{{color}}">
            我是盒子
            我是盒子
        </div>
    </div>
<script src="node_modules/vue/dist/vue.js"></script>
<script>
    const app = new Vue({
        el:"#app",//elemnet,vue 作用的标签
        data:{
            color:"red",
        }
    });
</script>
</body>
</html>

但是事实上上述做法是错误的
在这里插入图片描述
差值表达式不可以使用在属性当中

b、上述解决方式是错误的,下面代码使用v-bind
修改上述代码
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
c、继续更新上述代码 v-bind:class属性的特殊用法
在这里插入图片描述

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <style type="text/css">
        div #box{
            width:100px;
            height: 100px;
            color: darkgray;
        }
        .red{
            background-color: red;
        }
        .blue{
            background-color: blue;
        }
    </style>
</head>
<body>
    <div id="app">
        <button @click="isRed=!isRed">点我切换颜色</button>
        <div id="box" :class="{red:isRed, blue:!isRed}" >
            我是盒子
            我是盒子
        </div>
    </div>
<script src="node_modules/vue/dist/vue.js"></script>
<script>
    const app = new Vue({
        el:"#app",//elemnet,vue 作用的标签
        data:{
            isRed:true
        }
    });
</script>
</body>
</html>

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

13、计算属性

在插值表达式中使用js表达式是非常方便的,而且也经常被用到。

但是如果表达式的内容很长,就会显得不够优雅,而且后期维护起来也不方便

例如下面的场景、我们有一个日期的数据,但是是毫秒值:

(a)日期的格式化

在这里插入图片描述

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <style type="text/css">
        div #box{
            width:100px;
            height: 100px;
            color: darkgray;
        }
        .red{
            background-color: red;
        }
        .blue{
            background-color: blue;
        }
    </style>
</head>
<body>
    <div id="app">
        <!--class属性-->
        <button @click="isRed=!isRed">点我切换颜色</button>
        <div id="box" :class="{red:isRed, blue:!isRed}" >
            我是盒子
            我是盒子
        </div>
        <!--计算属性-->
        <h1>
            您的生日:{{ birth }}
        </h1>
    </div>
<script src="node_modules/vue/dist/vue.js"></script>
<script>
    const app = new Vue({
        el:"#app",//elemnet,vue 作用的标签
        data:{
            isRed:true,
            birthday : 1529032123201 //毫秒值
        },
        computed:{
            birth(){
                const day = new Date(this.birthday);
                return day.getFullYear() + "年" + day.getMinutes() +"月" + day.getDay() + "日";
            }
        }
    });
</script>
</body>
</html>

在这里插入图片描述

14、watch
(1)监控

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

自动监控
示例:
在这里插入图片描述

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <style type="text/css">
        div #box{
            width:100px;
            height: 100px;
            color: darkgray;
        }
        .red{
            background-color: red;
        }
        .blue{
            background-color: blue;
        }
    </style>
</head>
<body>
    <div id="app">
        <!--class属性-->
        <button @click="isRed=!isRed">点我切换颜色</button>
        <div id="box" :class="{red:isRed, blue:!isRed}" >
            我是盒子
            我是盒子
        </div>
        <!--计算属性-->
        <h1>
            您的生日:{{ birth }}
        </h1>
        <!--watch-->
        <input type="text" v-model="num" />
        <h1>num:{{ num }}</h1>
    </div>
<script src="node_modules/vue/dist/vue.js"></script>
<script>
    const app = new Vue({
        el:"#app",//elemnet,vue 作用的标签
        data:{
            isRed:true,
            birthday : 1529032123201, //毫秒值
            num : 1,
        },
        computed:{
            birth(){
                const day = new Date(this.birthday);
                return day.getFullYear() + "年" + day.getMinutes() +"月" + day.getDay() + "日";
            }
        }
    });
</script>
</body>
</html>

在这里插入图片描述

(2)浅监控

在这里插入图片描述

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <style type="text/css">
        div #box{
            width:100px;
            height: 100px;
            color: darkgray;
        }
        .red{
            background-color: red;
        }
        .blue{
            background-color: blue;
        }
    </style>
</head>
<body>
    <div id="app">
        <!--class属性-->
        <button @click="isRed=!isRed">点我切换颜色</button>
        <div id="box" :class="{red:isRed, blue:!isRed}" >
            我是盒子
            我是盒子
        </div>
        <!--计算属性-->
        <h1>
            您的生日:{{ birth }}
        </h1>
        <!--watch-->
        <input type="text" v-model="num" />
        <h1>num:{{ num }}</h1>
    </div>
<script src="node_modules/vue/dist/vue.js"></script>
<script>
    const app = new Vue({
        el:"#app",//elemnet,vue 作用的标签
        data:{
            isRed:true,
            birthday : 1529032123201, //毫秒值
            num : 1,
        },
        computed:{
            birth(){
                const day = new Date(this.birthday);
                return day.getFullYear() + "年" + day.getMinutes() +"月" + day.getDay() + "日";
            }
        },
        watch:{
            num(newVal,oldVal){
                console.log(newVal,oldVal);
            }
        }
    });
</script>
</body>
</html>

运行
在这里插入图片描述
newVal 是最新的值 oldVal是旧的值
在这里插入图片描述

(3)深监控,监控对象

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

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <style type="text/css">
        div #box{
            width:100px;
            height: 100px;
            color: darkgray;
        }
        .red{
            background-color: red;
        }
        .blue{
            background-color: blue;
        }
    </style>
</head>
<body>
    <div id="app">
        <!--class属性-->
        <button @click="isRed=!isRed">点我切换颜色</button>
        <div id="box" :class="{red:isRed, blue:!isRed}" >
            我是盒子
            我是盒子
        </div>
        <!--计算属性-->
        <h1>
            您的生日:{{ birth }}
        </h1>
        <!--watch-->
        <input type="text" v-model="num" />
        <h1>num:{{ num }}</h1>
        <input type="text" v-model="person.age" />
    </div>
<script src="node_modules/vue/dist/vue.js"></script>
<script>
    const app = new Vue({
        el:"#app",//elemnet,vue 作用的标签
        data:{
            isRed:true,
            birthday : 1529032123201, //毫秒值
            num : 1,
            person:{
                name:"Jack",
                age : 21
            }
        },
        computed:{
            birth(){
                const day = new Date(this.birthday);
                return day.getFullYear() + "年" + day.getMinutes() +"月" + day.getDay() + "日";
            }
        },
        watch:{
            num(newVal,oldVal){
                console.log(newVal,oldVal);
            },
            person:{
                deep:true,
                handler(val){
                    console.log(val.age)
                }
            }
        }
    });
</script>
</body>
</html>

在这里插入图片描述

五、组件化

在大型应用开发的时候,页面可以划分成很多部分。

往往不同的页面,也会有相同的部分。例如可能会有相同的头部导航。

但是如果每个页面都独白开发,这无骚增加了我们开发的成本。

所以我们会把页面的不同部分拆分成独立的组件,然后在不同页面就可以共享这些组件,避免重复开发。

1、定义安全组件

我们通过Vue的component方法来定义一个全局组件。
创建一个新的页面
在这里插入图片描述

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<div id="app">
    <counter></counter>
</div>
<script src="node_modules/vue/dist/vue.js"></script>
<script>
    //定义全局组件,两个参数:1.组件名称2.组件参数
    Vue.component("counter",{
        template:"<button @click='count++'>点我试试{{ count }}我记住你了!</button>",
        data(){
            return{
                count :0
            }
        }
    }) ;
    var app = new Vue({
        el:"#app"
    })
</script>
</body>
</html>

在这里插入图片描述

2、组件的复用

定义好的组件,可以任意复用多次:
在这里插入图片描述

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<div id="app">
    <!--使用定义好的全局组件-->
    <counter></counter>
    <counter></counter>
    <counter></counter>
</div>
<script src="node_modules/vue/dist/vue.js"></script>
<script>
    //定义全局组件,两个参数:1.组件名称2.组件参数
    Vue.component("counter",{
        template:"<button @click='count++'>点我试试{{ count }}我记住你了!</button>",
        data(){
            return{
                count :0
            }
        }
    }) ;
    var app = new Vue({
        el:"#app"
    })
</script>
</body>
</html>

在这里插入图片描述
组件的data属性必须是函数!
当我们定义这个 <counter> 组件时,它的data 并不是像这样直接提供一个对象:

data: {
  count: 0
}

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

data: function () {
  return {
    count: 0
  }
}

如果 Vue 没有这条规则,点击一个按钮就会影响到其它所有实例!

3、局部注册

一旦局部注册,就意味着即便以后你不再使用这个组件,它依然会随着Vue的加载而加载。

因此,对于一些并不频繁使用的组件,我们会采用局部注册。

我们先在外部定义一个对象,结构与创建组件时传递的第二个参数一致:

在这里插入图片描述

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<div id="app">
    <!--使用定义好的全局组件-->
    <counter></counter>
    <counter></counter>
    <counter></counter>
</div>
<script src="node_modules/vue/dist/vue.js"></script>
<script>
    //定义全局组件,两个参数:1.组件名称2.组件参数
    const counter = {
        template:'<button v-on:click="count++">你点了我 {{ count }} 次,我记住了.</button>',
        data(){
            return {
                count:0
            }
        }
    };
    var app = new Vue({
        el:"#app",
        comments:{
            counter:counter //将定义的对象注册为组件
        }
    })
</script>
</body>
</html>
  • components就是当前vue对象子组件集合。
    其key就是子组件名称
    其值就是组件对象的属性
  • 效果与刚才的全局注册是类似的,不同的是,这个counter组件只能在当前的Vue实例中使用

在这里插入图片描述

4、组件通信

通常一个单页应用会以一棵嵌套的组件树的形式来组织:
在这里插入图片描述

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

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

(1)父向子传递:props

比如我们有一个子组件:

Vue.component("introduce",{
    // 直接使用props接收到的属性来渲染页面
    template:'<h3>{{title}}</h3>',
    props:[title] // 通过props来接收一个父组件传递的属性
})
  • 这个子组件中要使用title属性渲染页面,但是自己并没有title属性
  • 通过props来接收父组件属性,名为title

父组件使用子组件,同时传递title属性:

在这里插入图片描述

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<div id="app">
    <h1>打个招呼:</h1>
    <!--使用子组件,同时传递title属性-->
    <introduce title="大家好,我是虎哥"/>
</div>
<script src="node_modules/vue/dist/vue.js"></script>
<script>
    //定义全局组件,两个参数:1.组件名称2.组件参数
    Vue.component("introduce",{
        //直接使用props接收到属性来渲染页面
        template:'<h3>{{ title }}</h3>',
        props:['title'] //通过props来接收一个父组件传递属性
    })
    var app = new Vue({
        el:"#app"
    })
</script>
</body>
</html>

在这里插入图片描述

(2)传递复杂数据

我们定义一个子组件:

const myList = {
    template:'\
        <ul>\
        	<li v-for="item in items" :key="item.id">{{item.id}} : {{item.name}}</li>\
        </ul>\
        ',
    props:{ // 通过props来接收父组件传递来的属性
        items:{// 这里定义items属性
            type:Array,// 要求必须是Array类型
            default:[] // 如果父组件没有传,那么给定默认值是[]
        }
	}
}
  • 这个子组件可以对 items 进行迭代,并输出到页面。
  • 但是组件中并未定义items属性。
  • 通过props来定义需要从父组件中接收的属性
    • items:是要接收的属性名称
      • type:限定父组件传递来的必须是数组,否则报错
      • default:默认值

我们在父组件中使用它:
全部代码:
在这里插入图片描述

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<div id="app">
    <h2>课程:</h2>
    <!-- 使用子组件的同时,传递属性,这里使用了v-bind,指向了父组件自己的属性lessons -->
    <my-list :items="lessons"/>
</div>
<script src="node_modules/vue/dist/vue.js"></script>
<script>
    const myList = {
        template: '\
            <ul>\
                <li  v-for="item in items" :key="item.id">{{item.id}} : {{item.name}}</li>\
            </ul>\
        ',
        props:{ // 通过props来接收父组件传递来的属性
            items:{ // 这里定义items属性
                type:Array, // 要求必须是Array类型
                default:[] // 如果父组件没有传,那么给定默认值是[]
            }
        }
    }
    var app = new Vue({
        el:"#app",
        components:{
            myList//当key和value一样的时候,可以只写一个
        },
        data:{
            lessons:[
                {id:1, name: 'java'},
                {id:2, name: 'php'},
                {id:3, name: 'ios'},
            ]
        }
    })

</script>
</body>
</html>

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

(3)子向父通信

来看这样一个案例:
在这里插入图片描述

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<div id="app">
    <h2>num:{{ num }}</h2>
    <!-- 使用子组件的同时,传传递num到子组件当中 -->
    <counter :num="num"></counter>
</div>
<script src="node_modules/vue/dist/vue.js"></script>
<script>
    Vue.component("counter",{//子组件,定义了两个按钮。点击数字num会加或减
        template:'\
             <div>\
                 <button @click="num++">加</button>\
                 <button @click="num--">减</button>\
             </div> ',
        props:['num']//count是从父组件获取的。
    })
    var app = new Vue({
        el:"#app",
        data:{
            num:0
        }
    })

</script>
</body>
</html>
  • 子组件接收父组件的num属性
  • 子组件定义点击按钮,点击后对num进行加或减操作

我们尝试运行:
在这里插入图片描述
子组件接收到父组件属性后,默认是不允许修改的。怎么办?

既然只有父组件能修改,那么加和减的操作一定是放在父组件

var app = new Vue({
    el:"#app",
    data:{
        num:0
    },
    methods:{ // 父组件中定义操作num的方法
        increment(){
            this.num++;
        },
        decrement(){
            this.num--;
        }
    }
})

在这里插入图片描述
全部代码

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<div id="app">
    <h2>num: {{num}}</h2>
    <counter :count="num" @inc="increment" @dec="decrement"></counter>
</div>
<script src="node_modules/vue/dist/vue.js"></script>
<script>
    Vue.component("counter", {
        template:'\
                <div>\
                    <button @click="plus">加</button>  \
                    <button @click="reduce">减</button>  \
                </div>',
        props:['count'],
        methods:{
            plus(){
                this.$emit("inc");
            },
            reduce(){
                this.$emit("dec");
            }
        }
    })
    var app = new Vue({
        el:"#app",
        data:{
            num:0
        },
        methods:{ // 父组件中定义操作num的方法
            increment(){
                this.num++;
            },
            decrement(){
                this.num--;
            }
        }
    })

</script>
</body>
</html>

但是,点击按钮是在子组件中,那就是说需要子组件来调用父组件的函数,怎么做?

我们可以通过v-on指令将父组件的函数绑定到子组件上:

<div id="app">
    <h2>num: {{num}}</h2>
    <counter :count="num" @inc="increment" @dec="decrement"></counter>
</div>

然后,当子组件中按钮被点击时,调用绑定的函数:

 Vue.component("counter", {
            template:'\
                <div>\
                    <button @click="plus">加</button>  \
                    <button @click="reduce">减</button>  \
                </div>',
            props:['count'],
            methods:{
                plus(){
                    this.$emit("inc");
                },
                reduce(){
                    this.$emit("dec");
                }
            }
        })

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

在这里插入图片描述

评论 22
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

程序员猫爪

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

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

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

打赏作者

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

抵扣说明:

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

余额充值