Vue3.x从零开始学-第一季 基础语法篇
【本视频已经完结】本视频适合没有Vue2基础的新手学习,你不用学完Vue2,而直接学习这个教程就可以了。Vue新发布的3.x版本,相较于Vue2有了很多扩充,用法上也有了不少的改变。Vue是一个渐进式框架,它不同于Angular
这样的框架,他既可以作小型的项目,也可以作大型的项目。最主要的一个特点是,他上手非常的容易。
Vue2.x版本已经在国内获得了非常大的成功,不完全统计,国内的新项目有50%-60%前端框架都选择了Vue,所以生态非常好。如果你是前端,我建议你还是学习一下。
01. [初识]课程介绍和HelloWorld
在课程的最开始之前,请允许作一下自我介绍,网络花名"技术胖",博客网站"jspang.com"。写博客的初衷是出1000集免费前端视频。然后再简单说说这套教程,这套教程是从零基础开始的,也就是说,你并不需要会Vue2。
前置知识和课程说明
但是你还是需要会下面最基本的知识:
- HTML: 超文本标记语言,用来写网页的基本结构。
- CSS : 层叠样式表,用来让你的页面更加生动和好看。
- JavaScript : 简称"JS",解释性或即时编译型的高级编程语言。
只要你会上面这三个知识,我这里说的是会,不用精通,就可以学习这门课程。课程会很长,预计总集数会超过70集。为了方便输出和博客性能,我把整个系列分成不同的季
,每季20集左右。一季完成后,会紧接着更新下一季。
课程的更新频率是每周3-5集,我会全力更新。这里说一下Vue3从基础到实战的视频完全免费,(应该会超过100集)如果你是在B站看到我的视频,请帮忙点一下一键三连。
下载VSCode
因为是零基础,所以在编写代码的时候,你需要下载一个编码工具。我在工作中最近两年一直在使用VSCode,所以我这里也向你推荐用VSCode
来进行编码。
VSCode下载地址:https://code.visualstudio.com/
下载时,需要选择你对应的系统版本。下载完成后,安装类似QQ,这里不做过多讲解,如果你实在不会安装,我这里给你文字版教程。
VSCode安装教程:https://blog.csdn.net/x15011238662/article/details/85094006 (这个教程你只要看前6部就可以了)
编写第一个HelloWorld
有了VSCode后,就可以直接开始编码了。我们通过最简单的例子,先来熟悉一下Vue3框架的特性。你可以在任何位置新建一个文件夹,比如我这里在D盘
,新建一个VueTest
文件夹,然后把这个文件夹拖动到VSCode
当中就可以了,然后在VSCode中新建立一个index.html
的文件。
打开index.html
后,可以直接输入html
,然后会出现选项,直接选择html:5
,就可以快速生成html的基本结构。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
</body>
</html>
当然,你也可以直接输入!
号,然后回车
,也会给我们输出同样的结果。根据自己的喜好,自行选择就好。
直接引入Vue3.x源码
Vue官方提供直接引入的CDN服务地址,只要用<script>
标签,就可以直接引入Vue3
,并且使用它。(其实学习期间,你并不需要会使用Vue-cli、Vite这些构建工具,来构建项目)
<script src="https://unpkg.com/vue@next"></script>
引入Vue3的框架之后,我们就可以写Vue的代码了。现在<body>
标签中,加入一个<div>
层,并给他一个id="root"
。
<div id="app"></div>
有了这个层,接着在下面写<script>
标签和Vue的语法,代码如下:
<script>
Vue.createApp({
template: '<div>Hello World</div>'
}).mount("#app")
</script>
你这时候可能还看不太懂这段代码,但是你需要跟着我把程序敲出来。为了方便你学习。我在这里给出index.html
的全部代码,
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Hello World</title>
<script src="https://unpkg.com/vue@next"></script>
</head>
<body>
<div id="app"></div>
</body>
<script>
Vue.createApp({
template: '<div>Hello World</div>'
}).mount("#app")
</script>
</html>
写完代码后,你可以直接打开index.html
就会显示在浏览器的网页上。当你看到了结果,我再给你一行行解释一下这个代码。
Vue.createApp({ //创建一个Vue实例,简单理解就说,我要使用Vue了
template: '<div>Hello World</div>' // template是模板的意思,就是在JS里写html代码
}).mount("#app") //这个模板需要放一个位置,也就是说挂载,挂载到`id=app`的DOM上
如果能在页面上出现Hello World
这文字,这节课的练习就算完成了。
如何进行提问和一起学习
如果你在学习中遇到问题,可以通过下面几个方法找到跟你一起学习的小伙伴或者直接找到我,来解决你学习中的问题。
- 在文章下方进行留言,只要你留言我都会竭尽所能回答。
- 你可以加入QQ群: Vue3-1群(2000人):827824449 ,Vue3-2群(2000人):273225311
- 你甚至可以加我的个人微信 : wx:flutter100 (我每天回上线回答你的问题)
放心,这里没有任何套路,本人目前没有售卖任何课程,所有视频都是免费的。你能学有所得,就是我最大的幸福。
好了,第一集的视频就到这里了,每周更新3-5集,如果你想跟我一起学习,点击一下收藏,防止以后找不到。
02. [初识]Vue3编写的计数器
这节学习目标非常明确,就是编写一个计数器。通过编写计数器我们要从面向DOM编程的思想中解放出来,进入面向数据的编程方式。如果你以前只使用过JQuery
,没有使用过Angular
和Vue
,这可能会颠覆你的认知,但这就是Vue的众多特性之一。
编写项目基本结构
在上节课新建的目录中,把上节中的index.html
改为Demo1.html
,然后新建一个Demo2.html
文件。这时候你可以把Demo1.html内容复制过来,但更建议你手敲一下上节的代码,作为复习。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Demo2计数器</title>
<script src="https://unpkg.com/vue@next"></script>
</head>
<body>
<div id="app"></div>
</body>
<script>
Vue.createApp({
template: '<div>Hello World</div>'
}).mount("#app")
</script>
</html>
准备计数器变量
基本编码结构准备好后,可以开始写计数器了。计数器能变化,肯定是需要一个变量的,这个变量起名为counter
。在Vue的template
(模板)中使用变量,需要用到字面量标识{{}}
双大括号,我喜欢把这个双大括号叫做字面量
。
Vue.createApp({
template: '<div>{{counter}}</div>'
}).mount("#app")
到目前为止,只是在模板中使用了counter
变量,但是还没有声明,声明这个变量需要在data()
函数中,具体代码如下。
data() {
return {
counter: 1
}
},
也许你现在还不能完全明白这段代码的意思,这不要紧,前几节课你只要跟着敲.得到结果就好。写到这里,你可以双击文件打开,在浏览器中看一下效果。
这时候页面上应该展示出1
。再回来看整个代码,他的意思是说,在Vue中声明了一个变量counter
,并在模板中展示出来。知识点就是如何声明变量和在模板中使用变量。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Demo2计数器</title>
<script src="https://unpkg.com/vue@next"></script>
</head>
<body>
<div id="app"></div>
</body>
<script>
Vue.createApp({
data() {
return {
counter: 1
}{{counter}</script>
</html>
mounted() 中实现自增
mounted
的是一个声明周期钩子函数(不懂没关系),你把他想成是页加载渲染完成,自动执行的方法就可以了。这个作个比喻,你去大宝剑,买了票,想进去之后,第一件事就是换鞋。这个换鞋就时这个方法。
先用console.log()
,打印出页面加载完成,看看效果
<script>
Vue.createApp({
data() {
return {
counter: 1
}
},
mounted() {
console.log('页面加载完成后-自动执行')
},
template: '<div>{{counter}}</div>'
}).mount("#app")
</script>
当你明白了这个函数的意义,因为mounted()
是自动执行,那就可以在里边写一个计时器了。
mounted() {
console.log('页面加载完成后-自动执行')
setInterval(() => {
this.counter += 1 //这个this.counter指向的就是data中的counter
//this.$data.counter +=1 //效果相同
}, 1000)
},
写完这段代码,浏览页面,就可以看到计数器的效果了。现在你回想以前不用框架,原生写法时,是不是要自己编写DOM,而现在完全不用了。
document.getElementById('app').innerHTML()
这节就是你要转变的一个观点,从面向DOM编程,改为面向数据编程。你能感受到这点不同,这就是你这节课最大的收获。如果你真的想学好Vue3,只听课是没有用的,还是要动手作,我建议你先把这节课代码敲三边以上。我是一个比较笨的开发者,所以一般学习时,我都会把实例代码多敲几边。这样才能有个初步印象。
如果你完全是一个新手,对这节课的代码不能完全理解,也不要慌张。在[初识]
阶段,我们只要动手,大概了解Vue3
的基本特性就可以。在基础语法中,我们还会详细讲解。
最后,为了方便你学习,给出Demo2.html
的全部代码.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Demo2计数器</title>
<script src="https://unpkg.com/vue@next"></script>
</head>
<body>
<div id="app"></div>
</body>
<script>
Vue.createApp({
data() {
return {counter: 1 }
},
mounted() {
console.log('页面加载完成后-自动执行')
setInterval(() => {
this.counter += 1
}, 1000)
},
template: '<div>{{counter}}</div>'
}).mount("#app")
</script>
</html>
03. [初识]洗脚城管理系统-来宾欢迎语展示
为了增加课程的趣味性,接下来的课程我们会有一个大目标-开发象牙山洗脚城管理系统,然后根据这个大目标我们不断学习,不断努力。所以这篇文章先来完成来宾欢迎语展示
的需求。
编写页面的基本结构
在项目根目录,新建一个目录Demo3.html
,然后复制Demo1.html
里边的代码。
复制后,你可以修改一下<title>
,加上象牙山洗脚城
,然后修改代码,增加content
变量。具体代码如下:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>象牙山洗脚城</title>
<script src="https://unpkg.com/vue@next"></script>
</head>
<body>
<div id="app"></div>
</body>
<script>
Vue.createApp({
data(){
return{
content:'欢迎你的光临,贵宾一位!'
}
},
template: '<div>{{content}}</div>'
}).mount("#app")
</script>
</html>
接下来我们要作的事情是写两个按钮,当顾客来的时候,我们显示欢迎你的光临,贵宾一位!
,当顾客离开的时候,我们显示欢迎下次光临,真空套餐下次8折优惠
。现在来写两个按钮,修改template
代码部分。
template: `<div>
<div>{{content}}</div>
<button>有顾客来</button>
<button>顾客离开</button>
</div>`
Vue3的绑定事件和事件方法
接下来需要给两个按钮绑定事件,这里绑定的事情跟原生方法不一样,需要写成下面的样子。然后在methods
属性里加入两个方法welcomeBtnClick
和byeBtnClick
。
<script>
Vue.createApp({
data() {
return {
content: '欢迎你的光临,贵宾一位!'
}
},
methods: {
welcomeBtnClick() {
alert('111')
},
byeBtnClick() {
alert('2222')
},
},
template: `{{content}
`
}).mount("#app")
</script>
写完这部就可以在浏览器测试一下,你写的代码是否好用。正常后,你需要修改响应事件的方法。
methods: {
welcomeBtnClick() {
this.content = "欢迎你的光临,贵宾一位!"
},
byeBtnClick() {
this.content = "欢迎下次光临,真空套餐下次8折优惠"
},
},
好了这个例子我们就写完了,那现在回顾一下,我们通过这个例子都学到了什么。
首先是我们了v-on
这种指令的使用,用来绑定对应的事件。然后我们又学了如何在Vue里写一个相应事件的方法。除了这两个知识外,你也能更深一层体验到什么是面向数据编程,而不再是面向DOM
编程。
希望你对本节课有所收获,记得手写代码哦。
显示隐藏套餐服务
由于服务的特殊性,老板要求我们能隐藏一些特殊有吸引力的套餐服务,只有VIP顾客才可以展示出来。于是我们开始编写代码。
明确需求后,我们需要新生成一个套餐的变量setMeal
,然后还要有一个是否展示的变量isShowMeal
。
data() {
return {
content: '',
setMeal: '真空套餐 帝王套餐 夏日套餐 学生套餐',
isShowMeal: false
}
},
有了这个变量之后,我们还需要有一个能改变isShowMeal
的响应方法showOrHideBtnClick
.用来控制套餐的显示很隐藏。
showOrHideBtnClick() {
this.isShowMeal = !this.isShowMeal
}
有了变量,有了方法,这时候就可以写模板中的代码了,注意这里涉及一个新的知识点,或者叫做新指令,就是v-if
,它的作用是如果值为真,就显示这个DOM元素,如果为假,就不显示这个元素。
template: `<div>
<div>{{content}}</div>
<button v-on:click="welcomeBtnClick">有顾客来</button>
<button v-on:click="byeBtnClick">顾客离开</button>
<div>
<div v-if="isShowMeal" >{{setMeal}}</div>
<button v-on:click="showOrHideBtnClick">显示/隐藏套餐</button>
</div>
</div>`
这时候就能通过一个按钮,随时进行菜单的隐藏和显示了。通过这两个小需求,相信你已经对Vue的编写方法有了最基本的了解,下篇文章我们来为我们的洗脚城,加入一些佳丽。希望小伙伴们继续关注。
为了方便学习,给出整个文件代码。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>象牙山洗脚城</title>
<script src="https://unpkg.com/vue@next"></script>
</head>
<body>
<div id="app"></div>
</body>
<script>
Vue.createApp({
data() {
return {
content: '',
setMeal: '真空套餐 帝王套餐 夏日套餐 学生套餐',
isShowMeal: false
}
},
methods: {
welcomeBtnClick() {
this.content = "欢迎你的光临,贵宾一位!"
},
byeBtnClick() {
this.content = "欢迎下次光临,真空套餐下次8折优惠"
},
showOrHideBtnClick() {
this.isShowMeal = !this.isShowMeal
}
},
template: `<div>
<div>{{content}}{{setMeal}}</script>
</html>
04. [初识]Vue3列表和循环-佳丽列表的制作
这节课通过完成象牙山洗脚城展示佳丽列表的需求,学习一下在Vue3.x
中如何进行循环展示和双向数据绑定。如果你想严肃点学习,可以把它看作是一个TodoList的小功能,形式不同,知识不变。快点开始学习吧。
编写Vue3的基本结构
在项目根目录,新建一个文件Demo4.html
,然后把Demo1.html
的代码全部复制过来,修改下面代码的样子。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>佳丽列表</title>
<script src="https://unpkg.com/vue@next"></script>
</head>
<body>
<div id="app"></div>
</body>
<script>
Vue.createApp({
template: '<div>Hello World</div>'
}).mount("#app")
</script>
</html>
声明佳丽数组并循环出来
我们反复强调小伙伴们的编程思想要从面向DOM,转变成面向数据的编程。这时候我们就需要一个数据佳丽列表
。在createrApp()
方法里增加一个data()
方法,声明list[]
数组。
data() {
return {
list: ['1-大脚','2-刘英','3-晓红']
}
},
有了数组,需要在模板中循环出来。这个需要用到v-for
指令.
template: `
<ul>
<li v-for="item of list">{{item}}</li>
</ul>
`
这句代码的意思是,我要进行循环,循环的数据是list
,list
中的每一项我会放到item中,然后使用字面量在模板中进行展示就可以了。
v-for
指令还有一个索引值,可以如下写法,打印出索引值。
<li v-for="(item,index) of list">[{{index}}]{{item}}</li>
会了循环之后,我们就可以根据前面的知识,做一个动态的可交互的佳丽列表了。
动态增加佳丽
先来做一个简单的效果,就是点击按钮后,就增加一个佳丽到列表中。先去掉数组中的值,然后来写一个按钮,按钮绑定handleAddItem
事件。代码如下:
<script>
Vue.createApp({
data() {
return {
list: []
}
},
methods: {
handleAddItem() {
this.list.push("佳丽")
}{{index}}]{{item}</script>
现在增加的佳丽
都是一样的,而我们最终的目的是能够自定义的增加佳丽,也就是想加大脚加大脚,想加刘英加刘英。这个时候我们就需要一个input
输入框了.而且需要用v-model
指令,进行绑定。代码如下。
<script>
Vue.createApp({
data() {
return {
//---此处修改
inputValue: '',
list: []
}
},
methods: {
handleAddItem() {
//----此处修改
this.list.push(this.inputValue)
}{{index}}]{{item}</script>
这时候我们就可以根据我们的喜欢增加佳丽了,比如增加一个大脚
、刘英
和晓红
(象牙山三大美女)。
现在这个效果还是不太完美,在实际工作中,如果我们增加完成后,希望<input/>
的值为空。这个时候你要再明白Vue中的一个特性,就是双向数据绑定。也就是这时候我们改变inputValue
的值,页面文本框的内容也会被清空。
methods: {
handleAddItem() {
this.list.push(this.inputValue)
this.inputValue = ''
}
},
写完后,可以在浏览器中打开,看一下最终的效果。
好了,让我们总结一下,这篇文章我们都学到了那些内容,学到v-for
循环指令,v-model
数据双向绑定。后面我们还会继续详解这些内容。
05. [初识]Vue3组件化开发-每个佳丽都是组件
这节算是[初识]
部分的最后一节,这个部分在你学习的时候,一定会有很多不明白的地方,这都不要紧。你只要课后敲出这些代码,然后看到和视频中一样的效果就算完成任务了。如果拿健身比喻[初识]
的作用,就算是热身吧。开始这节课的学习吧。
如何编写一个组件
Vue中一个最主要的特性,就是让你使用组件化进行开发。页面上你看到的任何的东西,都可以写成组件。先来看看如何编写一个静态的Vue组件,编写一个标题组件。
新建一个Demo5.html
文件,然后把Demo4.html
的内容全部拷贝过来。为了方便书写,把<script>
标签的第一行前,声明一个变量,比如就叫做app
,声明完变量之后,就可以把mount
部分独立出来了。
const app=Vue.createApp({
//.....somting........
app.mount("#app")
有了app
变量,可以非常方便的自定义组件并使用了。比如现在写一个关于标题的组件。
app.component('my-title', {
template: '<h1 style="text-align:center">象牙山洗脚城</h1>'
})
有了这个组件,就可以在app
的模板部分使用了,比如我们放在template
的最上面,代码如下:
template: `
<div>
<my-title />
<!--...somting......-->
</div>
`
动态组件的编写
什么是动态组件?也许我说的并不标准,我这里指的动态组件是显示内容不固定,通过父组件或者程序控制而输出的内容。
现在会了静态组件的基本使用方法,把上节课的佳丽
组件单独出来,写一个组件,这个组件会绑定一些props
,用于接受父组件传递过来的参数,然后动态显示出内容。
动态组件有一个关键的指令是v-bind
,用这种方法,组件可以通过props
取得对应的值。
具体代码的意思,我会在视频中讲解。代码如下
app.component('my-jiali', {
props: ['item', 'index'],
template: ` <li >[{{index}}]-{{item}}</li>`
})
props
是一个数组,可以接受多个值。有了my-jiali
组件后,就可以在app
的template
中使用了,方法如下。
<my-jiali
v-for="(item,index) of list"
v-bind:item="item"
v-bind:index="index"
/>
这时候肯定会有小伙伴认为,这也没有减少代码的工作量哦,第一是因为我们的代码还比较简单,第二是组件的意义是降低程序的耦合性,让大规模开发编程可能。比如一个页面,分成几个人开发,每个人写不同的模块,写好后拼凑在一起。有了组件这就变的非常容易。
这节课的内容稍微有点绕,如果你听不太懂也没关系,关键是把代码写出来,为了方便学习,这里给出Demo5.html
的全部代码。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>佳丽列表</title>
<script src="https://unpkg.com/vue@next"></script>
</head>
<body>
<div id="app"></div>
</body>
<script>
const app = Vue.createApp({
data() {
return {
inputValue: '',
list: []
}
},
methods: {
handleAddItem() {
this.list.push(this.inputValue)
this.inputValue = ''
}{
template: '<h1 style="text-align:center">象牙山洗脚城</h1>'
})
app.component('my-jiali', {
props: ['item', 'index'],
template: ` <li >[{{index}}]-{{item}}</li>`
})
app.mount("#app")
</script>
</html>
06. [基础]Vue的createApp()和mount()方法讲解
从这节课开始,我们将详细学习Vue3的基础语法,这些语法我会详细的讲解,目的是让大家理解并且会使用。所以这篇文章开始,都需要你认真的学习。
最常见的Vue初级代码
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Demo6</title>
<script src="https://unpkg.com/vue@next"></script>
</head>
<body>
<div id="app"></div>
</body>
<script>
const app = Vue.createApp({})
app.mount("#app")
</script>
</html>
createApp()和mount()方法讲解
现在你先看下面两句JavaScript代码,代码中有两个重要的方法createApp()
和mount()
。
const app = Vue.createApp({})
app.mount("#app")
createApp()
方法:
在第一篇文章编写HelloWorld
的时候,就写过这句话Vue.createApp()
从英文单词上理解,这个就是创建一个应用create-创建
,App-Application-应用
,前面的Vue就是Vue这个框架,所以Vue.createApp()
的意思就是创建一个Vue的应用。
mount()
方法
mount()
方法就是挂载到某个Html的DOM
节点上,它接受一个字符串型参数,参数可以使用CSS选择器,一般都是ID选择器的形式,指定挂载的DOM
元素。
createApp()方法的基本参数讲解
当你明白了createApp()
方法的作用,接下来可以更深层次的去了解它的参数。首先它接受一个对象形式的参数{}
。这个对象就是告诉Vue应该如何展现我们最外层的组件。 根据我们在初始章节学习的内容,我们很容易写出下面的内容。
<script>
const app = Vue.createApp({
data() {
return {
message: 'jspang.com'
}
},
template: "<h2>{{message}}</h2>"
})
app.mount("#app")
</script>
写完后,可以到浏览器中预览一下结果。
如何获取Vue的根组件vm
当你使用creatApp()
方法创建了一个Vue应用时,如何能获取根组件那?其实你使用mount()
方法时,就会返回根组件。下面的代码,声明一个变量来获取根组件,并打印出来。通过打印你可以看出根组件是一个Proxy
形式的对象。
const vm = app.mount("#app")
console.log(vm)
这里为什么我把根组件起名为vm
那?我先按下不表,我们先来了解一下Vue
的设计模式。
mvvm设计模式讲解
Vue的编程设计模式应该叫做mvvm
的设计模式。什么叫做mvvm
哪?它首先是面向数据的编程,程序中定义了数据,然后定义了模板,Vue
就可以把数据和模板自动进行关联。最后挂载到真实的DOM
上,展示给用户。
mvvm解释: 第一个
m
代表model
数据,第一个v
代表view
视图,最后两个字幕vm
代表viewModel
视图数据连接层。
如果你看完这个解释还不太明白,我们可以看一下Demo6.html
进行理解。
<script>
const app = Vue.createApp({
data() {
return {
message: 'jspang.com' //1.在这里定义了数据,也就是`model`数据
}
},
template: "<h2>{{message}}</h2>" //2.在这里定义了模板,也就是`view`,
//定义后的自动关联,就叫做`vm`,viewModel数据视图连接层。
})
app.mount("#app")
</script>
model
数据,是我们自己定义的,view
模板也是我们自己定义的,但是vm
是Vue自动给我们关联的。
当我们明白了什么是mvvm
后,你就知道为什么我们给根组件起名vm
了。
当我们获取了vm
根节点后,其实就可以操作里边的数据了。比如在控制台中输入下面的代码:
vm.$data.message ='技术胖'
这个时候你会发现网页界面也跟着发生了变化,变成了技术胖
.
好了,我们总结一下这篇文章我们都学到了什么,首先我们学习了Vue中的两个最基本方法createApp()
和mount()
,然后学习了如何获取和使用根组件
,在学习根组件的时候又讲解了Vue框架的基本模式是mvvm
,并对mvvm
模式进行了具体讲解。
07. [基础]Vue的生命周期函数-1
这篇文章我们讲解Vue3中的生命周期函数,生命周期函数你可以这样理解,就是在** 在某一时刻会自动执行的函数 **,这句话你可以注意两个关键词某一时刻
和自动执行
。学完这节文章,你会对这两个词有深刻的理解。
准备一个空白的页面
在开始讲解前,你需要一个基本的页面。这样能省去很多时间。把Demo6.html的内容,复制到Demo7.html中。修改一下标题,其他代码不变。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Demo7</title>
<script src="https://unpkg.com/vue@next"></script>
</head>
<body>
<div id="app"></div>
</body>
<script>
const app = Vue.createApp({
data() {
return {
message: 'jspang.com'
}
},
template: "<h2>{{message}}</h2>"
})
const vm = app.mount("#app")
</script>
</html>
有了这个文件,我们就可以继续学习了。
自动执行函数的理解
如果要理解什么是自动执行函数,我认为可以对比来看,先清楚什么是被动执行函数。比如我们写了一个handleItemClick( )
方法,然后让模板里的<h2>
点击后执行此事件,代码如下。
methods: {
handleItemClick() {
alert('jspang.com')
}
},
template: "<h2 v-on:click='handleItemClick'>{{message}}</h2>"
这时候可以打开浏览器,看一下这个效果。你需要点击对应的dom元素,他才会执行方法,这个就是被动执行函数。当你了解被动执行函数,再来了解什么是自动执行函数。写一个mounted
方法,它就会自动执行。这种就是自动执行函数。
mounted() {
alert('mounted')
},
这时候你再刷新一下网页,就可以看出mounted
被直接弹出了。这种没有任何操作,自动执行的方法,就叫做自动执行函数。
当你 明白了什么是自动执行函数后,我们再来学习Vue3.x的生命周期函数。
Vue3.x生命周期函数
学习生命周期函数,这里我们用一张Vue官方给出的声明周期函数图片来进行理解。看图理解会更透彻些。
- beforeCreate( ) :在实例生成之前会自动执行的函数
- created( ) : 在实例生成之后会自动执行的函数
- beforeMount( ) : 在模板渲染完成之前执行的函数
- mounted( ) : 在模板渲染完成之后执行的函数
我们也写了对应的方法,通过这些代码和查看效果,可以很好的理解生命周期函数执行的先后顺序。代码如下。
beforeCreate() {
console.log('beforeCreate')
},
created() {
console.log('created')
},
beforeMount() {
console.log('beforeMount')
},
mounted() {
console.log('mounted')
},
写完这些代码后,你可以到浏览器中查看一下效果。由于Vue的生命周期函数内容很多,所以我们分两节来讲。下节继续讲解Vue的生命周期函数。
08. [基础]Vue的生命周期函数-2
我们接着上篇文章继续学习,上篇文章只讲了Vue3中的前四个生命周期,先来简单的回顾一下。
- beforeCreate( ) :在实例生成之前会自动执行的函数
- created( ) : 在实例生成之后会自动执行的函数
- beforeMount( ) : 在模板渲染完成之前执行的函数
- mounted( ) : 在模板渲染完成之后执行的函数
beforeUpdate和updated生命周期函数
这两个生命周期函数在Vue中的data数据发生变化时,才会被执行,一个是在变化之前,一个是在变化之后。我们先来看beforeUpdate
函数,也就是在数据变化之前。
为了能展示这个效果,我们写一个数据变化的功能,每次点击文字都进行改变。在上节课编写的handleItemClick
方法中,改变message
的值。这里使用了三元运算符,代码如下:
handleItemClick() {
this.message = this.message == 'jspang.com' ? "技术胖" : "jspang.com"
}
有了这个方法之后,再来编写beforeUpdate
方法。代码如下:
- beforeUpdate :当data中的数据变化时, 会立即自动执行的函数
beforeUpdate() {
console.log('beforeUpdate')
},
写完后,你可以打开浏览器去看一下效果。
- updated:当data中的数据发生变化,页面重新渲染完后,会自动执行的函数
updated() {
console.log('updated')
},
在浏览器中你是可以看出先后顺序的。这个不太直观,如何用代码的方式看出beforeUpdate
和updated
区别?我们可以通过下面这种方法。
beforeUpdate() {
console.log('beforeUpdate')
console.log(document.getElementById('app').innerHTML)
},
updated() {
console.log('updated')
console.log(document.getElementById('app').innerHTML)
},
通过这种形式,就可以清楚的看出,在beforeUpdate
时,DOM的内容并没有渲染更新,而到了updated
中DOM的内容已经进行了更新。这就是两个生命周期函数的区别。
beforUnmount和unmounted生命周期函数
这两个生命周期函数是在Vue销毁时自动执行的函数,一个是销毁前执行,一个是销毁后执行。
- beforeUnmount( ) :当Vue应用失效时,会自动执行的函数
- unmounted() : 当Vue应用失效时,且DOM完全销毁之后,会自动执行
我们可以先把这两个生命周期函数写在页面上,代码如下:
beforeUnmount() {
console.log('beforeUnmount')
},
unmounted() {
console.log('unmounted')
},
那如何能看到这个效果那?这个需要在浏览器的控制台中输入销毁代码。
app.unmount()
这时候就会打印出这两个对应的生命周期函数了。当然你这时候如果编写程序看出页面变化,也可以通过打印innerHTML
方式。来看出效果。
beforeUnmount() {
console.log('beforeUnmount')
console.log(document.getElementById('app').innerHTML)
},
unmounted() {
console.log('unmounted')
console.log(document.getElementById('app').innerHTML)
},
这时候在浏览器执行app.unmount()
,会看到,在beforeUnmount
方法中还是有DOM内容的,然后到了unmounted
方法中,就已经没有任何的DOM内容了。
现在来总结一下:Vue3中有八个生命周期函数,
- beforeCreate( ) :在实例生成之前会自动执行的函数
- created( ) : 在实例生成之后会自动执行的函数
- beforeMount( ) : 在模板渲染完成之前执行的函数
- mounted( ) : 在模板渲染完成之后执行的函数
- beforeUpdate :当data中的数据变化时, 会立即自动执行的函数
- updated:当data中的数据发生变化,页面重新渲染完后,会自动执行的函数
- beforeUnmount( ) :当Vue应用失效时,会自动执行的函数
- unmounted() : 当Vue应用失效时,且DOM完全销毁之后,会自动执行
这些生命周期虽然多,你可以成对的去记忆,这样就有四个关键节点了:创建、渲染、更新、销毁。最主要的理解是他们是自动执行的函数。这节课就到这里,我们下节继续学习。
09. [基础]插值表达式和v-bind数据绑定
通过两节课终于学完了Vue3.x中的生命周期函数了,因为这套课默认你是没有Vue2.x的基础的,所以就不讲解Vue2和Vue3生命周期的区别了,你只要记住Vue3的8个生命周期就可以了。这节课我们主要学习两个模板语法:插值表达式和v-bind的使用。
插值表达式是什么?
我以前在课程中经常说的字面量
,其实正确叫法应该叫做插值表达式
,当然我们公司大部分还是叫字面量
的,也就是我们经常看到的{{xxxx}}
这样的东西。
我们复制上节课的代码,新建一个Demo9.html
,然后去掉生命周期相关的内容,这样就变成了一个简单的Vue代码。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Demo7</title>
<script src="https://unpkg.com/vue@next"></script>
</head>
<body>
<div id="app"></div>
</body>
<script>
const app = Vue.createApp({
data() {
return {
message: 'jspang.com'
}
},
methods: {
handleItemClick() {
this.message = this.message == 'jspang.com' ? "技术胖" : "jspang.com"
}
},
template: "<h2 v-on:click='handleItemClick'>{{message}}</h2>"
})
const vm = app.mount("#app")
</script>
</html>
这时候我们看到在template
属性中的{{message}}
就是插值表达式。也就是说利用这种形式,可以使用data中的变量,展示在模板中。
插值表达式输出html标签-v-html指令
如果我想在变量里,编写一些html的标签,然后输出展现在页面中,这时候会出现点小问题。我们先修改代码,看看问题所在。例如在message中加入<i>
标签。
return {
message: '<i>jspang.com</i>'
}
这时候如果什么都不做,直接输出,你在浏览器中看到的结果就是下面的样子。
<i>jspang.com</i>
这并不是你想要的结果,这时候需要使用v-html
的标签解决这个问题。把template属性的部分改成下面的样子。需要注意的是这压力要改成"`"符号,否则不能使用双引号这种形式
template: `<h2 v-html="message"> </h2>`
这时候再预览,就可以看到浏览器中的字变成了斜体。
插值表达式只作一次渲染-v-once
现在这种插值表达式,是跟着data中的数据一起变化的,也就是我们常说的数据双向绑定。但是如果我希望一个插值表达式,只有在第一次渲染去data中的值,而以后不再跟随data变化,这时候就要用到v-once
指令。
先来看一下目前这种代码,我们为h2
标签,加入相应事件handleItemClick
,代码如下。
template: `<h2 v-on:click="handleItemClick" v-html="message"> </h2>`
这时候在浏览器中可以看到,我们每点击一次h2标签,message
的值都是变化的。再改写一下代码。
template: `<h2
v-on:click="handleItemClick"
v-html="message"
v-once
> </h2>`
加入了v-once
后,无论data中的数据如何变化,模板也不会再次重新渲染了,这就是v-once
的变化。
插值表达式中是可以使用JS表达式的
其实在插值表达式中是可以使用JS表达式的,最常用的表达式是三元运算符。比如下面这样的代码也是可以的。比如在data中新声明一个变量count
,用三元运算符判断是否是大于2,如果大于2显示大,小于2显示小,编写代码如下:
<script>
const app = Vue.createApp({
data() {
return {
message: '<i>jspang.com</i>',
count: 5
}
},
methods: {
handleItemClick() {
this.message = this.message == 'jspang.com' ? "技术胖" : "jspang.com"
}
{{count>2?'大':'小'}
`
})
const vm = app.mount("#app")
</script>
当然你也可以使用一些简单的表达式,比如下面这些样子的JS表达式.
<div>{{'jspang'+'.com'}}</div>
<div>{{1+2}}</div>
这些形式的表达式都是可以的,但是如果你想用if语句,就是不可以的,因为只能用JS表达式而不能用语句。
v-bind指令的使用
现在我们给h2标签加入一个title属性,属性的值也想使用message
。代码如下:
<h2
v-on:click="handleItemClick"
v-html="message"
v-once
title="message"
> </h2>`
这时候浏览器中鼠标放上时显示的确实message
这个单词,而并没有出现我们想要的结果。这时候就可以使用v-bind
标签了。写成下面的样式就可以了。
v-bind:title="message"
这就是这节课的全部内容了,现在来总结一下,先学习了插值表达式和一些特殊情况的用法,从而引出了v-html
指令,v-once
指令和在插值表达式中使用JS表达式。然后又学习了v-bind
指令。
10. [基础]模板动态参数和阻止默认事件
这是2021年录制的第一节课,先祝所有小伙伴新年快乐。接着上节课继续讲模板中常用的一些语法。
v-on的基本用法和简写
v-on
是用来绑定响应事件的,在以前的课程中多次用到了。这里就先写一个最简单的事件,弹出对话框。
我这里复制了Demo9.html的代码,然后进行了精简
methods:{
hanldClick(){
alert('欢迎光临红浪漫')
}
},
template:`
<h2 v-on:click="hanldClick">{{message}}</h2>
`
在浏览器中可以看出,点击<h2>
标签,就可以弹出alert效果。这个你一定很熟悉了,所以没必要作过多的讲解。
v-on
还有一个简写方法,就是可以不屑v-on:
用@
代替,比如把代码改成下面的样子,也是完全可以使用的。
template:`
<h2 @click="hanldClick">{{message}}</h2>
`
不仅v-on
有简写方法,上节我们学习的v-bind
也有简写方法,比如上节的代码,可以直接写出。
<h2 v-bind:title="message">{{message}}</h2>
<h2 :title="message">{{message}}</h2>
Vue在开发中还是鼓励大家使用简写,这样可以让代码更加清晰。
模板动态参数
现在绑定的事件click
和title
都是固定死的,显得不太灵活,Vue也提供了动态参数,要叫做动态属性的功能。比如这里v-bind:title
中的title
是来自data
中的,就可以这样写。
const app=Vue.createApp({
data(){
return{
message:'jspang.com' ,
name:'title'
}
},
//.........
template:`
<h2
@click="hanldClick"
:[name]="message"
>
{{message}}
</h2>
`
})
可以看到我们在data
中,定义了一个name的变量,值是一个字符串,然后在绑定属性时我们使用了[]
方括号加上data中变量名的形式。这时候绑定的属性就变的灵活了,这种形式就是模板动态参数,也称为动态属性。
可以在浏览器中使用检查
的方式,查看此时绑定属性的名称,如果进行修改,比如改成title1
,浏览器中也会跟随改变,形成动态效果,这就是动态属性了。
事件动态绑定
这种形式,也可以用到v-on
事件绑定当中,比如在data
中声明一个event
的变量,然后给他一个click
,然后用同样的方法实现事件动态绑定。
data中的写法如下
return{
message:'jspang.com' ,
name:'title',
event:'click'
}
模板中的写法如下
template:`
<h2
@[event]="hanldClick"
:[name]="message"
>
{{message}}
</h2>
`
这时候就实现了动态绑定方法,可以打开浏览器,看一下效果。当点击<h2>
标签时,也会弹出对应的alert效果。当然你还可以帮click
改成其他相应事件,比如改成event:'mouseenter'
,这样,当鼠标滑入时就可以相应弹出效果了。
阻止默认事件
最常见的默认事件就是表单的默认提交事件,比如我们这里写一个表单,然后写一个属性为submit
的按钮,当点击按钮时,表单就会默认提交到对应的网址。
<form action="https://jspang.com">
<button type="submit">默认提交</button>
</form>
这时候在浏览器中预览,点击“默认提交”按钮,就会立即跳转到我的博客上去,这就是默认响应事件。但是在开发中我们经常需要阻止这种默认响应事件。比如写出下面的代码。
methods:{
hanldeClick(){
alert('欢迎光临红浪漫')
},
hanldeButton(e){
e.preventDefault()
}
},
//...
template:`
//....
<form action="https://jspang.com" @click="hanldeButton">
<button type="submit">默认提交</button>
</form>
`
这样写就可以阻止默认事件方法了,但是这是一个精彩要做的操作,每次写太麻烦了,所以Vue也给我们提供了一个模板修饰符,直接可以阻止默认行为。写法如下。
<form
action="https://jspang.com"
@click.prevent="hanldeButton">
<button type="submit">默认提交</button>
</form>
`
methods中的写法
hanldeButton(){
alert('jspang.com')
}
这样就可以阻止默认事件,直接响应对应事件的内容了。prevent
就是阻止默认事件的修饰符。修饰符可以见简化一些代码的编写,也是比较常用的一个操作。
好了这节课就到这里了,下节课我们再介绍一个模板中最常用的语法,v-if
。
11. [基础]模板中使用条件判断
模板中使用条件判断,控制页面的样式,是最常见的应用。Vue中提供了两种基本的方法,一种是我们已经讲过的三元运算符,另一种就是v-if
。
三元运算符控制模板样式
我们先来看利用三元运算符来控制模板的样式,根据Data中值的不同,显示不同的样式。这里复制Demo9.html
的代码到Demo11.html
中。
然后修改为下面的样子。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Demo11</title>
<script src="https://unpkg.com/vue@next"></script>
</head>
<body>
<div id="app"></div>
</body>
<script>
const app = Vue.createApp({
data() {
return {
message: 'jspang.com',
}
},
methods: {
handleItemClick() {
this.message = this.message == 'jspang.com' ? "技术胖" : "jspang.com"
}
},
template: `<h2 >{{message}}</h2>`
})
const vm = app.mount("#app")
</script>
</html>
这就是一个最简单的Vue代码了,然后我们在<script>
标签下面,写一段style
样式代码。
<style>
.one {color: red;}
.two {color: green;}
</style>
这里有两个基本的CSS样式,分别是让文字是红色和绿色。现在的需求是,要根据message
的值显示不同的颜色,是jspang.com
显示红色,是技术胖
时显示绿色。类似这样的需求,就可以使用三元运算符,然后绑定class的形式。
template: `<h2
:class="message=='jspang.com'?'one':'two'"
@click="handleItemClick" >
{{message}}
</h2>`
这时候文字变化,对应的css样式也会变化。可以打开浏览器,看一下效果。
v-if判断
三元运算符的限制还是比较明显的,就是只能判断两个值,如果这时候我们再加入一个值,就是既不是jspang.com
,也不是技术胖
的时候,我们显示橙色。这时候三元运算符就满足不了需求了。vue给我们准备了v-if判断。
我们先加入一个CSS样式three
:
<style>
.one {color: red;}
.two {color: green;}
.three{color:orange;}
</style>
然后可以使用v-if
来进行编写模板。
template: `
<h2 @click="handleItemClick" v-if="message=='jspang.com'" class="one" > {{message}} </h2>
<h2 @click="handleItemClick" v-if="message=='技术胖'" class="two"> {{message}} </h2>
<h2 @click="handleItemClick" v-if="message=='bilibili'" class="three"> {{message}} </h2>
`
当然,你也可以使用v-else
,比如下面把代码改为这个样子。
template: `
<h2 @click="handleItemClick" v-if="message=='jspang.com'" class="one" > {{message}} </h2>
<h2 @click="handleItemClick" v-else class="three"> {{message}} </h2>
`
v-if
在实际的工作中使用的也是非常多的,所以建议你多写两边,加深一下印象。这篇文章完成后,我们关于Vue模板方面的语法就基本结束了。
12. [基础]计算属性-computed
这篇文章来学习一下Vue3中的计算属性。计算属性的特性是:当计算属性依赖的内容发生变更时,才会重新执行计算。我相信这时候你还不能很好的理解这句话的意思,所以需要通过实际的代码来进行演示。
编写基本页面和准备变量
我们新建一个Demo12.html
,然后把Demo11.html
的内容拷贝过来,然后进行精简,只留最基本的代码。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Demo12-Vue中的计算属性</title>
<script src="https://unpkg.com/vue@next" ></script>
</head>
<body>
<div id="app"></div>
</body>
<script>
const app=Vue.createApp({
data(){
return{
message:'jspang.com' ,
}
},
methods:{
handleItemClick(){
this.message = this.message=='jspang.com'?'技术胖':'jspang.com'
}
},
template:`
<h2> {{message}}</h2>
`
})
const vm=app.mount("#app")
</script>
</html>
有了基本的Vue基本结构后,我们先在Data中生命两个变量,单价(price)和数量(count)。单价设置为10,数量设置为2个。data中的代码如下:
data(){
return{
message:'jspang.com' ,
price:10,
count:2
}
},
然后我们在模板template
中打印出两个变量的综合price * count
。
template:` <h2> {{price * count}}</h2>`
如果 一切正常的话,这时候打开浏览器预览,你应该可以看到页面上显示的是20
。
这种方法当然可以,但是显得不够优雅,也没有语义化。如果你想进行语义化,你可能想到的第一个办法就是写一个getTotal
的方法。
methods:{
getTotal(){
return this.price * (this.count++);
}
},
template:` <h2> {{getTotal()}}</h2>`
这时候你再次查看浏览器,依然可以得到同样的结果。也许你还看不出来什么问题,但此时他确实存在一些问题,问题就是只要页面中有一个值重新渲染了,他都会重新执行。
methods方法无法满足的需求
如何看出这个问题那?我们可以稍微修改一下代码,让每次得到的值都不同。这时候可以使用获得时间戳的方法,来获得当前的时间戳。
methods:{
getTotal(){
return Date.now()
}
},
我们同时在模板中,打印出message
的值,代码如下。
template:`
<h2>{{message}}</h2>
<h2> {{getTotal()}}</h2>
`
这时候打开浏览器的控制台console
,然后在里边通过手都的方式修改message
的值vm.message='1111'
,比如修改为技术胖
。这时候问题产生了,你会发现getTotal( )
方法被重新执行了。这就是这个问题的所在,这个问题其实可以用今天的主角coumputed
计算属性来解决。
编写计算属性
还是获取当前的时间戳,但是写在了计算属性中。计算属性的关键字是computed
,然后里边可以写计算用的方法,这里我起名叫做total
,当然你可以起任何的名字。
computed:{
total(){
return Date.now()
}
},
然后我们把上面模板中的方法getTotal( )
换成计算属性total
。模板的代码如下:
template:`
<h2>{{message}}</h2>
<h2> {{total}}</h2>
`
这时候到浏览器中,用手动的方法,修改message
的值,total
的值就不会进行改变了。
vm.message='1111'
通过这个例子,你会对普通方法和计算属性的区别有所了解。这时候我们作一下总结:
- 方法methods:只要页面重新渲染,就会重新执行方法
- 计算属性computed: 当计算属性依赖的内容发生变更时,才会重新执行计算
那我们再来看计算属性改变的例子。
计算属性-computed实例
我们还是用单价X数量=总和
这个小例子,来说明具体计算属性的使用方法。修改当前代码,把计算属性中total( )
方法内容修改。不同的是我们这次加入一个按钮,每点击一下按钮,就会让数量count
加1。
我们先来修改计算属性中的内容。
computed:{
total(){
return this.price * this.count
}
},
然后在模板中写一个按钮,每次点击按钮count
数量进行增加。
methods:{
addCount(){
this.count++
}
},
template:`
<h2>{{message}}</h2>
<h2> {{total}}</h2>
<button @click="addCount">再买一个</button>
`
这时候我们再到浏览器中查看效果,当点击按钮的时候,计算属性会帮助我们完成模板的自动更新。
好了,我们总结一下,这节我们主要学习了Vue中的计算属性,重点在于理解计算属性和普通methods方法的区别,当你明白了两者的区别后,在工作中就可以清楚的知道什么时候该用计算属性,什么时候该用vue的方法了。
13. [基础]Vue中的侦听器/监听器-watch
这篇文章学习Vue中的侦听器(也有叫监听器),它可以侦听data中值的变化,做出相应的操作。这看起来和上节讲的计算属性(computed)很像,但如果你足够细心,也可以发现一些区别,下面我们就开始学习吧。
侦听器的基本写法
watch侦听器的作用就是侦听一个data中的值的变化,变化后可以写一个方法,让其进行一些操作(业务逻辑的编写)。
直接复制上节课的代码(Demo12.html)到Demo13中,不用修改任何的东西,继续编写程序。在computed
代码块的上面编写一段侦听器的代码。
watch:{
count(){
console.log('count changed')
}
},
上面代码的意思是,写一个侦听器来侦听count
的数据变化,当count
变化之后立即在控制台打印出count changed
。
侦听器中的方法还可以接收两个参数,一个是现在的值(current),一个是变化之前的值(prev)。我们分别接收这两个值,并打印在控制台,看一下效果。
watch:{
count(current,prev){
console.log('watch changed')
console.log('现在的值:',current)
console.log('变化前的值:',prev)
}
},
在浏览器中可以看到打印的效果。先打印出了3,然后又打印出了2。需要注意的是两个参数的先后顺序,如果不小心,是很容易记反的。
侦听器和计算属性的区别
这时候问题来了,计算属性也是可以根据变化执行一些操作的,那侦听器watch和计算属性computed的区别是什么?
先给出结论,计算属性computed必须要返回一个值,而且在页面渲染的同时就会执行里边的业务逻辑,也就是会先执行一遍你写的业务逻辑,而watch
只有发生变化时才会执行,也就是说值没有变化,它是不执行里边业务逻辑的。为了验证结果,先注释掉侦听器watch相关的内容,在计算属性total
中写这样的代码。
代码如下:
computed:{
total(){
console.log('....count changed')
return this.price * this.count
}
},
计算属性(computed)更加简洁
再来思考一个问题,用watch侦听器,可以写出类似计算属性的代码吗?答案是肯定的。现在我们就就写一个类似计算属性效果。
先在data中声明一个新的变量,叫做newTotal
,给出一个20
的值。
data(){
return {
//....
newTotal:20
}
}
然后修改watch中代码,写一个乘法表达式算出总和
,赋值给this.newTotal
。
watch:{
count(current,prev){
this.newTotal=this.price * current
}
},
最后把模板中的渲染值,改为newTotal
就可以了。
template:`
//......
<h2>总和:{{newTotal}}</h2>
//......
`
写完这些,你在浏览器中看到的效果和计算是属性是一样的。但是从代码简洁性上,显然侦听器的写法是麻烦并冗余,所以建议优先使用计算属性来完成同样的操作。
method、watch和computed三者使用优先级
现在总结一下method、watch和computed三者如果都能实现相同的功能,它们之间的取舍和使用优先级。
computed
和method
都能实现的功能,建议使用computed,因为有缓存,不用渲染页面就刷新。computed
和watch
都能实现的功能,建议使用 computed,因为更加简洁。
14. [基础]模板样式绑定详细讲解
这篇文章我们主要学习Vue中的一些关于样式(style)的内容。样式绑定的内容还是不少的,所以分两篇文章:初识和进阶来讲述。首先我们要编写一个基本的最简单的页面。
准备干净的页面
这里新建一个Demo14.html
,然后把Demo13.html
内容复制到Demo14.html
中,并改为下面最简单的样式。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Demo14</title>
<script src="https://unpkg.com/vue@next" ></script>
</head>
<body>
<div id="app"></div>
</body>
<script>
const app=Vue.createApp({
template:`
<h2>JSPang.com</h2>
`
})
const vm=app.mount("#app")
</script>
</html>
你当然也可以直接复制这段代码,然后进行练习。
写两个最基本的样式 并引入到模板
在文件的下方,我们写三个最进本的样式red
、green
和background
,代码分别如下:
<style>
.red{color:red;}
.green{color:green;}
.background{ background-color: orange;}
</style>
引用样式,在Vue的模板中引用和普通的html的方法一样。直接写class加上类名就可以了。
template:`
<h2 class="red">JSPang.com</h2>
`
这时候你可以考虑一个问题,如果你希望程序足够灵活,样式也是可以控制的,这样引入样式的方法就不行了。你需要先在Data中声明变量,然后在模板template
中进行绑定。
声明data变量:
data(){
return {
classString:'red',
}
},
有了这个变量(或者叫做数据项)以后,就可以用bind的形式进行绑定。
<h2 v-bind:class="red">JSPang.com</h2>
<h2 :class="red">JSPang.com</h2>
绑定同样使用v-bind
,你也可以使用简写:
。上面的两种形式都可以进行绑定。这时候你可以到浏览器中查看一下效果,如果一切正常,此时应该还是红色的。
此时你可以利用浏览器的控制台,输入对应的代码,直接控制样式了。
vm.$data.classString='green'
Vue中用对象和数组的形式控制样式
对象的绑定方式
比如现在用对象的形式进行绑定样式,好处是一次可以绑定多个样式。比如这样的代码。
data(){
return {
classString:'red',
classObject:{red:true,background:true}
}
},
值为true
代表绑定,值为false
代表不绑定这个样式。
然后进行绑定
template:`
<h2 :class="classObject">JSPang.com</h2>
`
这时候再到浏览器中查看效果,就会有两个样式被绑定了red
和background
。如果你这首把red改为false,那效果就是只有背景颜色,没有字体颜色了。
数组的绑定方式
再来看一下数组的绑定方式,数组也是可以绑定多个样式的。
代码如下:
data(){
return {
classString:'red',
classObject:{red:true,background:true},
classArray:['green','background'],
}
},
这时候再修改一下绑定值,页面样式就变成了绿字,橙色的底啦。
template:`
<h2 :class="classArray">JSPang.com</h2>
`
你也可以在这种数组的数据项中,再嵌套对象的形式。
classArray:['green','background',{red:true}],
如果看不到效果,可以在CSS样式中增加!important
,当然你也可以在浏览器的控制台查看。
好了这节课就先到这里,下节课我们继续学习Vue中的样式绑定。
15. [基础]模板样式绑定-2进阶
这篇文章继续学习Vue的模板样式绑定。上篇文章你已经对Vue中的样式绑定有一个基本了解。我们预习一下,上节课我们学了三种绑定样式的方法:
- 通过普通字符串进行绑定;
- 通过对象的方式进行绑定;
- 通过数组的方式进行绑定。
这篇文字主要学习一下Vue中子组件样式的绑定和行内样式如何编写。
子组件的样式绑定
先来看一下子组件如何绑定样式。新建一个文件Demo15.html
,然后把Demo14.html
的内容拷贝到Demo15.html
中。复制好后,编写一个子组件SonCom
,组件中就是展示一个简单的内容。
代码如下:
app.component('sonCom',{
template:`
<div>SonCom</div>
`
})
有了子组件后,就可以在父组件的模板中进行使用了,使用就是直接写一个类似html的标签进去就可以。
template:`
<h2 :class="classArray">JSPang.com</h2>
<sonCom />
`
如何区分父子组件
在vue.createApp( )
方法中用对象形式{ }
配置的一般叫做父组件,而下面使用的其他组件,叫做子组件。你也可以这样理解,主动调用的是父组件,被调用的是子组件。
最简单的为子组件添加样式的方法,就是自己给子组件加上class
。
app.component('sonCom',{
template:`
<div class="green">SonCom</div>
`
})
这时候子组件的字体颜色就变成了绿色。你还可以把class写在调用子组件的地方(也就是写在父组件里),例如下面的代码。
template:`
<h2 :class="classArray">JSPang.com</h2>
<sonCom class='green' />
`
先去掉子组件里的class,在调用地方增加class样式。这时候效果也是一样的。
子组件使用样式的小坑
这时候我们修改一下子组件,再写一个<div>
进去,里边写上技术胖
的字样。这时候再来看结果。
app.component('sonCom',{
template:`
<div>SonCom</div>
<div>技术胖</div>
`
})
你会发现两个<div>
的样式都不起作用了。那我们如何让它变成绿色那,其实只有再两个并列的<div>
外层,加上一个包括性的标签就可以了。也就是说让子组件的最外层只有一个根元素。
app.component('sonCom',{
template:`
<div>
<div>SonCom</div>
<div>技术胖</div>
</div>
`
})
这样就又变成了绿色字体。还有一种用到动态绑定的方法,直接绑定属性中的class。
app.component('sonCom',{
template:`
<div :class="$attrs.class">SonCom</div>
<div>技术胖</div>
`
})
行内样式的编写
什么是行内样式?就是自己在模板的DOM元素上写CSS样式,比如下面的这样。
<h2 style="color:orange;">JSPang.com</h2>
除了这种写法以外,Vue中也为我们扩展了一些内容,让行内样式的写法更直观和令狐。你可以直接在data中编写样式,比如在Data中这样写。
data(){
return{
styleString:'color:orange;'
}
},
然后用绑定行内样式的形式,在模板中进行绑定。
template:`
<h2 :style="styleString">JSPang.com</h2>
`
你也可以用对象的形式在data中编写CSS样式。比如写成下面的代码,然后再进行绑定。
data(){
return{
//.....
styleString:'color:orange;',
styleObject:{
color:'red',
background:'yellow'
}
}
},
在写行内样式的使用,个人觉的对象的写法更加直观和简洁,所以建议小伙伴可以采用这种对象的形式来进行编写。
16. [基础]v-show和v-if的差别
在第11节中,我们学习了v-if
和三元运算符
,我相信小伙伴已经掌握的很好了。这篇文章我们学一个和v-if
很类似的语法v-show
,以及它和v-if
有什么区别,也算是一个补充课程。
v-show的基本语法
新建一个Demo16.html
文件,复制Demo15.html
的文件到Demo16.html
里边,然后删除无用的代码,保留最简单的代码就可以。代码如下:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Demo16</title>
<script src="https://unpkg.com/vue@next" ></script>
</head>
<body>
<div id="app"></div>
</body>
<script>
const app=Vue.createApp({
data(){
return{
}
},
template:`
<h2>JSPang.com</h2>
`
})
const vm=app.mount("#app")
</script>
</html>
准备好最基本的结构后,在数据项中声明一个show
的变量。
data(){
return{
show:true,
}
},
有了变量后,可以在模板中使用v-show
来控制CSS样式,从而控制DOM元素的展示与否。
template:`
<h2 v-show="show">JSPang.com</h2>
`
这时候打开浏览器进行预览,是可以看到JSPang.com
这个h2的DOM元素的。如果把数据项show
改成false
就看不到了。
v-if和v-show的区别
v-show看起来和v-if语法的功能基本一样,但其实他们无论是灵活性还是功能都是有区别的。
v-if
更加灵活,可以增加多个判断,比如v-else-iif
和else
,而v-show
不具备这样的灵活性。
v-show控制DOM元素显示,其实控制的是css样式,也就是display:noe
。现在你可以把data
的值修改为false,然后刷新浏览器,打开浏览器调试器的Elements
选项卡,就可以清楚的看到,这时候<h2>
标签上的style样式就是display:none
。
<h2 style="display: none;">JSPang.com</h2>
现在回到vscode中的代码,在模板中再复制一行(在vscode中用Alt+Shift+↓
就可以快速复制一行),这时候用v-if
进行判断。再次在浏览器中预览,你会发现整个DOM元素都不见了。
现在你应该明白了v-if
和v-show
的区别,那如何使用他们。这个就要看具体的需求了,如果显示和隐藏的状态切换比较频繁,并且没有什么多余复杂的业务逻辑,建议使用v-show
,因为他不会一直渲染你的页面DOM元素,这或多或少对性能和稳定性有点提升。反之可以使用v-if
。
17. [基础]v-for循环详细讲解-1
使用Vue的时候循环是最常用的一种操作,虽然我们在课程[初识]
阶段已经简单讲解过了v-for的使用方法,但并不全面。下面,我们将使用两篇文章详细讲解v-for的具体使用方法。
v-for循环数组的方法
v-for最常用的功能就是循环数组,先来看一个数组循环的例子。先新建一个Demo9.html
的页面,然后复制Demo16.html
的内容。修改为下面的样式。(你完全可以复制下面的代码)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script src="https://unpkg.com/vue@next" ></script>
</head>
<body>
<div id="app"></div>
</body>
<script>
const app=Vue.createApp({
data(){
return{
}
},
methods:{
},
template:``
})
const vm=app.mount("#app")
</script>
</html>
也就是最基本的一个Vue文件结构。然后在data
中声明一个数组,数组叫做listArray
,代码如下:
data(){
return{
listArray:['谢大脚','刘英','晓红']
}
},
data中数组写完后,现在要作的是在template
中循环出这些数组,这里当然使用v-for
,代码如下:
template:`
<ul>
<li v-for="item in listArray">{{item}}</li>
</ul>
`
上面代码写完后在浏览器中预览效果,可以看到,已经如我们所愿,在页面渲染出了列表。在v-for
渲染数组时中还可以加入索引index
,也就是 数组的下标。
template:`
<ul>
<li v-for="(item,index) in listArray">[{{index}}]{{item}}</li>
</ul>
`
这些就是最基本v-for循环数组的知识。
关于循环时的key值
为了提高循环时性能,在数组其中一项变化后,整个数组不进行全部重新渲染,Vue提供了绑定key值的使用方法,目的就是增加渲染性能,避免重复渲染。
为了理解这个概念,先编写出一个按钮,然后每次点击按钮后向数组中增加push
一个新值。
methods:{
handleChangeBtnClick(){
this.listArray.push('JSPang.com')
},
},
template:`
//......
<button @click="handleChangeBtnClick">点我改变</button>
`
写完后,你到页面中预览,当你点击按钮时,表面上你看到增加了一个新的内容,实际整个列表都被重新渲染了。在实际工作中,这样的代码是不被允许的,它会降低页面的性能,在数据量变多的时候,用户用起来会变的卡顿。
这时,你可以加唯一性key
值,增加后vue就会辨认出哪些内容被渲染后并没有变化,而只渲染新变化的内容。
<ul>
<li v-for="(item,index) in listArray" :key="index+item">
[{{index}}]{{item}}
</li>
</ul>
官方不建议使用索引index
为key值,但此时又为了保持唯一性,所以这里使用了index+item
进行绑定key值
v-for循环对象的方法
v-for不仅可以循环数组,还可以循环对象,使用方法基本和数组一样(但其中参数值是不一样的)。这里先在data中建立一个对象。代码如下:
data(){
return{
//......
listObject:{
GirlOne:'谢大脚',
GirlTwo:'刘英',
GirlThree:'晓红'
}
}
},
在模板中进行循环的时候,为了更好的语义化,我们把参数改为了value
,key
和index
。然后进行循环。
<ul>
<li v-for="(value,key,index) in listObject" :key="key">
[{{index}}]{{value}}-{{key}}
</li>
</ul>
写完后可以到浏览器中预览,也是可以得到你想要的结果的。
[0]谢大脚-GirlOne
[1]刘英-GirlTwo
[2]晓红-GirlThree
好了,这就是这篇文章的全部内容了。希望你能动手练习一下这些内容,因为他们在工作后基本每天都在使用。下篇文章继续讲解如何v-for循环列表时的一些注意事项。
18. [基础]v-for循环详细讲解-2
上篇文章已经对v-for
的使用有了基本的了解,这篇文章主要讲v-for中的三个注意点。
v-for循环数字
复制Demo17.html
的内容到Demo18.html
中,然后继续接着上篇文章编写代码。
v-for
是可以用来循环数字的,比如你要循环1-99的数字,可以直接写成下面的样子。
<span v-for="count in 99">{{count}},</span>
这样就可以快速的循环出1-99的值在页面上。可以在浏览器中看一下这个效果。
v-for中如何使用判断
你看一下,上篇文章写的关于数组循环的小例子,现在的新需求有些变化,由于谢大脚
的年龄比较大了,我们想刨除出去,只显示刘英
和晓红
。这时候你很可能把代码写成这个样子。
<ul>
<li
v-for="(item,index) in listArray"
:key="index+item"
v-if="item != '谢大脚'"
>
[{{index}}]{{item}}
</li>
</ul>
在浏览器中进行预览,你会发现谢大脚
的循环项,并没有消失。这是为什么那?因为v-for循环的优先级要高于v-if
判断的优先级,所以判断失效。
正确的写法应该是在<li>
外层独立出一个标签,在<li>
上做循环。比如写成下面的代码。
<ul>
<div
v-for="(item,index) in listArray"
:key="index+item"
>
<li v-if="item != '谢大脚'">
[{{index}}]{{item}}
</li>
</div>
</ul>
这时候到浏览器中预览,谢大脚项
如愿以偿的消失了。
template标签的使用
上面的结果完美吗?当你打开浏览器的控制台,看Elements选项卡时,你会发现DOM结构是有问题的,明明循环出两项,却有3个<div>
,而且这种外层套用<div>
里边使用<li>
的形式,不符合HTML语法的基本结构。
<ul>
<div>...</div>
<div>...</div>
<div>...</div>
</ul>
为了解决这个问题,Vue给我们提供了<template>
模版标签,也就是一个空的占位符,目的就是解决模板中为完成业务逻辑,而使用的无用html标签的现象。
现在可以把上面的代码写成这样。
<ul>
<template
v-for="(item,index) in listArray"
:key="index+item"
>
<li v-if="item != '谢大脚'">
[{{index}}]{{item}}
</li>
</template>
</ul>
这时候再到浏览器看一下结果,这样就符合我们的期待了。
<ul>
<!--v-if-->
<li>...</li>
<li>...</li>
</ul>
这就是本篇文章的所有内容了,也基本讲完了vue3中对于列表循环的基本操作和一些小坑。我们下篇文章见了。
19. [基础]绑定事件详讲-方法和参数
可能你会觉的Vue中的绑定事件非常简单,和原生JavaScript对比,确实是简化了很多,但里边还是有很多你需要注意的点的,特别是事件修饰符这部分的内容还是相当多的。我们将用两节文章的篇幅,讲解Vue3.x中的绑定事件和它相关的种种。第一节先来介绍一下绑定事件的基本用法。
按钮的基本绑定事件
现在的需求是这样的,只要顾客点击按钮,我们就会增加佳丽数量,这看起来非常的刺激。在开始编码前我们需要一个纯净的页面。
新建一个页面Demo19.html
,然后复制下面这段代码。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Demo19</title>
<script src="https://unpkg.com/vue@next" ></script>
</head>
<body>
<div id="app"></div>
</body>
<script>
const app=Vue.createApp({
data(){
return{
count:0
}
},
methods:{}{{count}</script>
</html>
可以先简单的看一下这段代码,在模板(template)里边有一个<div>
显示了目前的佳丽数量,数量是在data
中定义的变量count
。然后有一个按钮<button>
。现在要做的就是每点击一下按钮,让数量加1。到这里小伙伴可以不先向下看,自己先写一下。
先在methods
里写一个方法,我这里给方法起名字叫addCountClick( )
,代码如下:
methods:{
addCountClick(){
this.count++;
},
},
然后在button上绑定这个响应事件.
template:`
<div>目前已点佳丽数量{{count}}.</div>
<button @click="addCountClick">增加一位佳丽</button>
`
})
这时候你可以打开浏览器预览一下效果,当你点击按钮时,"佳丽"的数量就会不断增加。
直接用表达式实现
你还可以使用更简单的方法,不在methods
中写任何的响应方法,而是使用表达式
来编写。
<button @click="count++">增加一位佳丽</button>
这看起来更见的简单了,保持代码的精简,是一个程序员应有的追求,但这样灵活性也会比较差。
事件中的event对象
在编写响应事件事,是可以接受一个event参数的,这个参数就是关于响应事件的一些内容。我们直接打印出event,你会发现内容比较多,其实这些参数还是值得一看的,在工作中有时真的会用到。
methods:{
addCountClick(event){
this.count++;
console.log(event)
},
},
这时候你可以打开浏览器,然后打开控制台
查看一下效果。可以看到event的内容非常多,想直观看到是那个DOM元素触发事件,可以使用target
属性。
console.log(event.target)
单参数/多参数的传递
先来看传入单独的参数,比如现在每次点击佳丽的增量不再是1,而是2。这就是双飞吧。就可以这样来编写。
methods:{
addCountClick(num){
this.count+=num
},
},
template:`
//.....
<button @click="addCountClick(2)">增加一位佳丽</button>
`
})
有参数的情况下使用event
这时候你还想使用event
参数,那需要如何编写那,方法是参数增加$event
。
methods:{
addCountClick(num,event){
this.count+=num;
console.log(event.target)
},
},
template:`
<div>目前已点佳丽数量{{count}}.</div>
<button @click="addCountClick(2,$event)">增加一位佳丽</button>
`
})
总结一下,在有多个参数的情况下,要继续使用event,需要在调用的地方使用$event
,进行传递参数,然后在方法上正常接收就可以了。
一个按钮调用两个方法
在有些复杂的需求中,是需要点击一个按钮,同时执行两个方法的。
先写两个方法handleBtnClick1
和handleBtnClick2
,每个方法里的业务逻辑,就是弹出一个alert
。代码如下:
methods:{
//...
handleBtnClick1(){
alert(1)
},
handleBtnClick2(){
alert(2)
},
},
在模板的按钮中可以这样使用这两个方法。
<button @click="handleBtnClick1(),handleBtnClick2()">增加一位佳丽</button>
这里需要注意的是:调用方法的时候,要加上( )
如果不加,调用是无效的。
总结一下:如果想在模板中一次触发两个事件方法,需要 用,
逗号,把事件隔开,然后每个事件后边必须加上( )
才能起作用。
这节就先到这里了,下节继续讲解绑定事件的修饰符。
20. [基础]绑定事件详讲-事件修饰符
绑定事件中的修饰符有很多种,这些修饰符各有各的用处。本节课将讲解6中Vue中的事件修饰符,分别是;stop
,prevent
,capture
,self
,once
和passive
。
通过修饰符解决冒泡事件
在JavaScript中冒泡事件是最长处理的事件,先写一段代码,手动创造一个冒泡事件。新建一个文件Demo20.html,复制Demo19的内容,然后稍作修改。
- 修改模板
template
部分,在最外层增加一个<div>
并添加click事件。 - 修改方法
methods
部分,删除无用方法,保留两个方法,增加alter提示。 - 形成冒泡效果,就是有嵌套的DOM元素时,两个都有绑定事件,JS会自动向上传递事件。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Demo19</title>
<script src="https://unpkg.com/vue@next" ></script>
</head>
<body>
<div id="app"></div>
</body>
<script>
const app=Vue.createApp({
data(){
return{
count:0
}
},
methods:{
addCountClick(){
this.count++
},
handleBtnClick1(){
alert(1)
}{{count}</script>
</html>
stop修饰符
在Vue中要停止冒泡是非常简单的,只要加加一个事件修饰符stop
就可以了。
<button @click.stop=" addCountClick()">增加一位佳丽</button>
self修饰符
除了使用.stop
修饰符,还有一种修饰符self
,意思是只有点击自己的时候才会被执行。 只不过加的位置要在家外层DOM元素的事件上。
template:`
<div @click.self="handleBtnClick1">
<div>目前已点佳丽数量{{count}}.</div>
<button @click=" addCountClick()">增加一位佳丽</button>
</div>
`
这时候你会发现点击那里,都没办法触发hanldeBtnClick1
方法了,这是因为目前最外层div下都是独立的DOM元素,就是都有成对标签出现,都不属于最外自己,都是他们的子元素。
可以编写一段专属最外层DIV的文字。
template:`
<div @click.self="handleBtnClick1">
我是最外层的DIV文字
<div>目前已点佳丽数量{{count}}.</div>
<button @click=" addCountClick()">增加一位佳丽</button>
</div>
`
这样当点击我是最外层的DIV文字
时,就会触犯handleBtnClick1
方法了。
其它常用修饰符
prevent修饰符:阻止默然行为的修饰符,这个以前讲过,例如阻止form
表单的默认提交行为。(不在重复介绍,如果你还没有掌握,可以复习以前课程)
capture修饰符:改成捕获模式,默认的模式都是冒泡模式,也就是从下到上,但是你用capture后,是从上到下的。
修改一下模板部分的代码,不在 使用修饰符,而是让事件存在冒泡。
methods:{
addCountClick(){
this.count++
alert(0) //修改了此处
},
handleBtnClick1(){
alert(1)
},
},
template:`
<div @click.capture="handleBtnClick1"> //修改了此处
我是最外层的DIV文字
<div>目前已点佳丽数量{{count}}.</div>
<button @click=" addCountClick()">增加一位佳丽</button>
</div>
`
once修饰符:事件只执行一次(视频中作演示)。
template:`
<div @click.self="handleBtnClick1">
我是最外层的DIV文字
<div>目前已点佳丽数量{{count}}.</div>
<button @click.once=" addCountClick()">增加一位佳丽</button>
</div>
`
此时再点击按钮,事件只执行一次。这时候我们修改了两个地方,最外层的事件加了self
修饰符,button上加了once
修饰符。
passive修饰符:解决滚动时性能的修饰符,不太好演示,等以后用到我们会再详细讲解。
这节就先到这里了,我们学习了6种修饰符:stop
,prevent
,capture
,self
,once
,passive
。下节课我们讲解按键修饰符。
21. [基础]绑定事件详讲-按键、鼠标饰修符
这节课的内容会讲一下事件绑定中的按键修饰符
和鼠标修饰符
。他们对应的是在使用特点的某个按键时才会用到。这节课的内容在工作中也是比较常用的,比如按下回车键时触发表达提交,按下鼠标右键时弹出选项菜单。都是工作中用得到的。
构建基础页面
新建一个页面Demo21.html
然后把下面的代码复制到代码中。可以看到,这就是一个最简单的页面,只不过是在模板template
中加入了一个<input />
标签。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Demo21</title>
<script src="https://unpkg.com/vue@next" ></script>
</head>
<body>
<div id="app"></div>
</body>
<script>
const app=Vue.createApp({
data(){
return{}
},
methods:{
},
template:`
<div">
<input />
</div>
`
})
const vm=app.mount("#app")
</script>
</html>
然后在methods
部分加入一个方法handleKeyDwon( )
,具体内容只是在控制台打印出来keydown
。
methods:{
handleKeyDown(){
console.log('keydow....')
}
},
然后在模板中的<input />
中绑定键盘按下时响应keydown
。
template:`
<div">
<input @keydown="handleKeyDown"/>
</div>
`
单个按键修饰符
单个按键修饰符:顾名思义,就是指定键盘上某个特殊的按键时才会响应事件方法。
如果现在的需求是,上面的代码只有在按下回车时,才在控制台进行打印,这时候就需要按键修饰符了。我们学的第一个按键修饰符enter
template:`
<div">
<input @keydown.enter="handleKeyDown"/>
</div>
`
})
类似这样只响应单个按键的修饰符有很多
- enter 、tab、delete、esc、up 、down、left、right
这些你可以通过上面的列子,自行测试,我这里不在赘述。
鼠标修饰符
除了按键修饰符,还有鼠标修饰符,就是按下鼠标上的某个键时,才会响应。
最常用的就是: left、right、middle
现在的需求是在页面上作一行文字JSPang.com
,然后只有用鼠标右键点击时,才会弹出alert( )
。
先在methods
里编写一个handleClick
方法。
methods:{
//...
handleClick(){
alert('click')
}
},
然后在模板中使用鼠标修饰符,确定只有点击鼠标右键时才会响应。
<div @click.right="handleClick">JSPang.com</div>
好了这节的内容就到这里了,事件绑定我们一共讲了三节,希望小伙伴们能动手把这部分的内容联系一下,这是最常用的一些功能。
22. [基础]表单数据的双绑定-1
我在课程刚开始的初识阶段,经常强调Vue是数据驱动的开发。其中最重要的一点应用是数据的双向绑定,从这节课开始,我们就详细讲解一下Vue3中表单和数据绑定的一些方法。学完后你可以对数据双向绑定有很好的了解。
写干净的Vue3文件
这个你可以直接拷贝下面的代码,这样就可以快速写出Vue3的基本结构。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Demo22</title>
<script src="https://unpkg.com/vue@next" ></script>
</head>
<body>
<div id="app"></div>
</body>
<script>
const app=Vue.createApp({
data(){
return{}
},
methods:{
},
template:`
<div></div>
`
})
const vm=app.mount("#app")
</script>
</html>
input的数据双向绑定
这个可能是最简单和最常用的双向绑定方式,我们先在模板中给写一个<input/>
,然后在data
中声明一个name
的变量。有了变量后和input
进行双向数据绑定。
<script>
const app=Vue.createApp({
data(){
return{
name:''
}
},
template:`
{{name}
`
})
const vm=app.mount("#app")
</script>
写完这个,打开浏览器预览一下效果。可以看到,当input
框改变时,对应的变量也会变化,页面中的值也会变化。
那什么是双向绑定那?
data中的变量改变时,绑定的数据会跟随变化,此为一项修改;当通过页面修改数据,data中的变量也随之改变,这就是另一项修改。两个彼此依存改变,就为双向数据绑定。
目前这种就完成了<input />
的双向数据绑定。
textarea的数据双向绑定
以前我们写HTML
的时候,写textarea
标签都是成对出现的,比如这样<textarea></textarea>
,如果想在Vue中实现textarea的双向数据绑定,这时候只要写单标签就可以了,剩下的事情Vue底层就帮你完成了。
template:`
<div>
<div>{{name}}</div>
<div><input v-model="name" /></div>
<div><textarea v-model="name" /></div>
</div>
`
这样也是可以实现数据的双向绑定的。
checkbox数据双向绑定
checkbox
是一个勾选框(复选框),如果只有一个选项时,我们可以给<checkbox />
一个布尔值,也就是true或者false。
现在data中新声明一个变量checked
.
data(){
return{
name:'',
checked:false
}
},
然后在模板中进行双向数据绑定。
<div>{{checked}}<input type="checkbox" v-model="checked" /></div>
写完后进行预览,双向绑定是完全可以实现的。checkbox
还有一个功能就是复选,可以选择多个。
比如还是象牙山三大美女的例子,现在勾选谁,谁就可以显示在页面上。
这时候要先定义一个变量,这个变量是一个空数组。
data(){
return{
name:'',
checked:false,
girls:[]
}
},
然后增加模板中的内容如下。
<div>
{{girls}}
大脚<input type="checkbox" v-model="girls" value="大脚" />
刘英<input type="checkbox" v-model="girls" value="刘英" />
晓红<input type="checkbox" v-model="girls" value="晓红" />
</div>
这时候就可以实现多选的双向数据绑定了。
Radio的双向数据绑定
学会了checkbox
的双向数据绑定,radio
单选按钮就简单了。但是需要注意的是,既然是单选,这时候data中的变量就不能是一个数字了,一般是一个字符串。比如我们这里新定义了一个girl
的变量。
data(){
return{
name:'',
checked:false,
girls:[],
girl:'',
}
},
复制上面的template代码,然后进行修改,把checkbox
换成radio
,代码如下:
<div>
{{girl}}
大脚<input type="radio" v-model="girl" value="大脚" />
刘英<input type="radio" v-model="girl" value="刘英" />
晓红<input type="radio" v-model="girl" value="晓红" />
</div>
这样就完成了单项选择的数据双向数据绑定了。
好这节课先到这里,下节课我们继续学习表单的双向数据绑定。
23. [基础]表单数据的双绑定-2修饰符
这节我们主要来看一下v-model
(数据双向绑定)中的修饰符。但是在学习修饰符前,我们补充一下上节遗漏的知识点。
在上节课我们作了复选框选择true
和false
的情况。新建一个文件,我们重现一下代码。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Demo23</title>
<script src="https://unpkg.com/vue@next"></script>
</head>
<body>
<div id="app"></div>
</body>
<script>
const app = Vue.createApp({
data() {
return {
checked: true,
}
},
template: `
<div>{{checked}}<input type="checkbox" v-model="checked" /></div>
`
})
const vm = app.mount("#app")
</script>
</html>
在浏览器中预览时,当选择复选框时,会显示true,没选中显示false。
现在的需求是,我选中的时候显示JSPang.com
,没选中的时候显示技术胖
。这时候要如何处理那?
Vue给我们提供了这样两个属性true-value
和false-value
。我们在Data中新声明一个变量name,值为空字符串。
data() {
return {
checked: true,
name: '',
}
},
这时候在模板中编写下面的代码。
template: `
<div>{{name}}
<input
type="checkbox"
v-model="name"
true-value="JSPang.com"
false-value="技术胖"
/></div>
`
这时候到浏览器中预览,就可以看到,在选择时插值表达式会变成JSPang.com
,在没选中时会变成技术胖
。
补充的部分就到这里了,下满我们来看一下,v-model
数据双向绑定的修饰符。
v-model数据双向绑定修饰符
lazy修饰符
v-model
也有很多实用的修饰符,现在就学习一下。第一个修饰符lazy
,这个也叫做懒更新修饰符。
我们作一个input
的绑定效果,现在data中声明一个message
变量,值为空。然后在模板中写一个<input />
并和message
进行双向数据绑定。
data() {
return {
checked: true,
name: '',
message:'',
}
},
模板中进行双向数据绑定:
<div>
{{message}}<input v-model="message" />
</div>
这时候当你在文本框中输入任何内容的时候,插值表达式会跟着改变。如果你不想马上显示,就可以用lazy
修饰符,这样就可以实现当输入完成后,失去焦点再进行改变。
<div>
{{message}}<input v-model.lazy="message" />
</div>
写完lazy修饰符后,可以看一下效果,这时候的效果就和我们想象的一样了。
number修饰符
<input />
输入的内容无论是数字还是字母,最终都会变为字符串
。如果想最终输入的变成数字,你就可以使用number
修饰符了。
比如我们现在去掉lazy
修饰符,直接输入数字,这时候你修改插值表达式的结果,输出当前类型。
<div>
{{typeof message}}<input v-model="message" />
</div>
这时候你预览,就会发现最终input绑定的值会变成字符串类型。这是html的底层逻辑造成的,这时候我们可以使用number
修饰付,解决这个问题。加上number
修饰符后,你输入的值只要是数字,就变成了number类型。(也就是说,如果你输入的是字母,它还会是字符串类型)
<div>
{{typeof message}}<input v-model.number="message" />
</div>
trim修饰
trim
修饰符大家一定不陌生,它是用来消除input
框输入内容前后的空格的。现在我们再字符串上输入空格,其实它会在DOM元素上进行增加空格的,这个可以在控制台清楚的看出(详细请看视频操作)。 加入trim
修饰符后,Vue就会自动给我们去除前后的空格。
现在data中新声明一个变量,比如叫做message1
。
data() {
return {
//......
message1: 'JSPang.com'
}
},
用法如下:
<div>
{{message1}}<input v-model.trim="message1" />
</div>
这时候Vue就会自动为我们去除前后空格,但不会去除字符串中间的空格。
好了,这节课就先到这里了。第一季也算结束了,第一季我们主要讲了Vue的基础语法。但是我们会马上开始第二季,这部分我们会全面讲解Vue中的组件概念。我们下一季见了,再见。