专注前端开发,每年100集免费视频。
首页/视频教程/ Vue3.x从零开始学-第一季 基础语法篇/
Vue3.x从零开始学-第一季 基础语法篇
2020-12-03 视频教程 2716023

【本视频已经完结】本视频适合没有Vue2基础的新手学习,你不用学完Vue2,而直接学习这个教程就可以了。Vue新发布的3.x版本,相较于Vue2有了很多扩充,用法上也有了不少的改变。Vue是一个渐进式框架,它不同于Angular这样的框架,他既可以作小型的项目,也可以作大型的项目。最主要的一个特点是,他上手非常的容易。

Vue2.x版本已经在国内获得了非常大的成功,不完全统计,国内的新项目有50%-60%前端框架都选择了Vue,所以生态非常好。如果你是前端,我建议你还是学习一下。

01. [初识]课程介绍和HelloWorld

在课程的最开始之前,请允许作一下自我介绍,网络花名"技术胖",博客网站"jspang.com"。写博客的初衷是出1000集免费前端视频。然后再简单说说这套教程,这套教程是从零基础开始的,也就是说,你并不需要会Vue2。

前置知识和课程说明

但是你还是需要会下面最基本的知识:

  1. HTML: 超文本标记语言,用来写网页的基本结构。
  2. CSS : 层叠样式表,用来让你的页面更加生动和好看。
  3. 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这文字,这节课的练习就算完成了。

如何进行提问和一起学习

如果你在学习中遇到问题,可以通过下面几个方法找到跟你一起学习的小伙伴或者直接找到我,来解决你学习中的问题。

  1. 在文章下方进行留言,只要你留言我都会竭尽所能回答。
  2. 你可以加入QQ群: Vue3-1群(2000人):827824449 ,Vue3-2群(2000人):273225311
  3. 你甚至可以加我的个人微信 : wx:flutter100 (我每天回上线回答你的问题)

放心,这里没有任何套路,本人目前没有售卖任何课程,所有视频都是免费的。你能学有所得,就是我最大的幸福。

好了,第一集的视频就到这里了,每周更新3-5集,如果你想跟我一起学习,点击一下收藏,防止以后找不到。

02. [初识]Vue3编写的计数器

这节学习目标非常明确,就是编写一个计数器。通过编写计数器我们要从面向DOM编程的思想中解放出来,进入面向数据的编程方式。如果你以前只使用过JQuery,没有使用过AngularVue,这可能会颠覆你的认知,但这就是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
            }
        },
        template: '<div>{{counter}}</div>'
    }).mount("#app")
</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>&nbsp;
    <button>顾客离开</button>

</div>`

Vue3的绑定事件和事件方法

接下来需要给两个按钮绑定事件,这里绑定的事情跟原生方法不一样,需要写成下面的样子。然后在methods属性里加入两个方法welcomeBtnClickbyeBtnClick

<script>
    Vue.createApp({
        data() {
            return {
                content: '欢迎你的光临,贵宾一位!'
            }
        },
        methods: {
            welcomeBtnClick() {
                alert('111')
            },
            byeBtnClick() {
                alert('2222')
            },
        },
        template: `<div>
                        <div>{{content}}</div>
                        <button v-on:click="welcomeBtnClick">有顾客来</button>&nbsp;
                        <button v-on:click="byeBtnClick">顾客离开</button>

                   </div>`
    }).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>&nbsp;
            <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}}</div>
                        <button v-on:click="welcomeBtnClick">有顾客来</button>&nbsp;
                        <button v-on:click="byeBtnClick">顾客离开</button>
                        <div>
                            <div v-if="isShowMeal" >{{setMeal}}</div>

                            <button v-on:click="showOrHideBtnClick">显示/隐藏套餐</button>
                        </div>
                   </div>`
    }).mount("#app")
</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("佳丽")
            }
        },
        template: `
            <div>
                <button v-on:click="handleAddItem">增加佳丽</button>
                <ul>
                    <li v-for="(item,index) of list">[{{index}}]{{item}}</li>
                </ul>
            </div>

        `
    }).mount("#app")
</script>

现在增加的佳丽都是一样的,而我们最终的目的是能够自定义的增加佳丽,也就是想加大脚加大脚,想加刘英加刘英。这个时候我们就需要一个input输入框了.而且需要用v-model指令,进行绑定。代码如下。

<script>
    Vue.createApp({
        data() {
            return {
                //---此处修改
                inputValue: '',  
                list: []   
            }
        },
        methods: {
            handleAddItem() {
                //----此处修改
                this.list.push(this.inputValue)
            }
        },
        template: `
            <div>
                <!--此处修改-->
                <input v-model="inputValue" />
                <button v-on:click="handleAddItem">增加佳丽</button>
                <ul>
                    <li v-for="(item,index) of list">[{{index}}]{{item}}</li>
                </ul>
            </div>

        `
    }).mount("#app")
</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组件后,就可以在apptemplate中使用了,方法如下。

<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: `
            <div>
                <my-title />
                <input v-model="inputValue" />
                <button v-on:click="handleAddItem">增加佳丽</button>
                <ul>
                    <my-jiali 
                        v-for="(item,index) of list"  
                        v-bind:item="item" 
                        v-bind:index="index"  
                    />
                </ul>
            </div>

        `
    })

    app.component('my-title', {
        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官方给出的声明周期函数图片来进行理解。看图理解会更透彻些。

https://newimg.jspang.com/Vuelifecycle.png

  • 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')
},

在浏览器中你是可以看出先后顺序的。这个不太直观,如何用代码的方式看出beforeUpdateupdated区别?我们可以通过下面这种方法。

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"
            }
        },
        template: `<h2 
                        v-on:click="handleItemClick" 
                        v-html="message"
                        v-once
                    > </h2>
                    <div>{{count>2?'大':'小'}}</div>
                    `
    })
    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在开发中还是鼓励大家使用简写,这样可以让代码更加清晰。

模板动态参数

现在绑定的事件clicktitle都是固定死的,显得不太灵活,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'

通过这个例子,你会对普通方法和计算属性的区别有所了解。这时候我们作一下总结:

  1. 方法methods:只要页面重新渲染,就会重新执行方法
  2. 计算属性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三者如果都能实现相同的功能,它们之间的取舍和使用优先级。

  • computedmethod都能实现的功能,建议使用computed,因为有缓存,不用渲染页面就刷新。
  • computedwatch 都能实现的功能,建议使用 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>

你当然也可以直接复制这段代码,然后进行练习。

写两个最基本的样式 并引入到模板

在文件的下方,我们写三个最进本的样式redgreenbackground,代码分别如下:

<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>  
`

这时候再到浏览器中查看效果,就会有两个样式被绑定了redbackground。如果你这首把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-iifelse,而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-ifv-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,keyindex。然后进行循环。

<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:{},
    template:`
      <div>目前已点佳丽数量{{count}}.</div>
      <button>增加一位佳丽</button>
        ` 
    }) 
    const vm=app.mount("#app")

</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,进行传递参数,然后在方法上正常接收就可以了。

一个按钮调用两个方法

在有些复杂的需求中,是需要点击一个按钮,同时执行两个方法的。

先写两个方法handleBtnClick1handleBtnClick2,每个方法里的业务逻辑,就是弹出一个alert。代码如下:

methods:{
    //...
    handleBtnClick1(){
        alert(1)
    },
    handleBtnClick2(){
        alert(2)
    },
},

在模板的按钮中可以这样使用这两个方法。

<button @click="handleBtnClick1(),handleBtnClick2()">增加一位佳丽</button>

这里需要注意的是:调用方法的时候,要加上( )如果不加,调用是无效的。

总结一下:如果想在模板中一次触发两个事件方法,需要 用,逗号,把事件隔开,然后每个事件后边必须加上( )才能起作用。

这节就先到这里了,下节继续讲解绑定事件的修饰符。

20. [基础]绑定事件详讲-事件修饰符

绑定事件中的修饰符有很多种,这些修饰符各有各的用处。本节课将讲解6中Vue中的事件修饰符,分别是;stop,prevent,capture,self,oncepassive

通过修饰符解决冒泡事件

在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)
        },
    },
    template:`
        <div @click="handleBtnClick1">
            <div>目前已点佳丽数量{{count}}.</div>
            <button @click=" addCountClick()">增加一位佳丽</button>
       </div>
        ` 
    }) 
    const vm=app.mount("#app")

</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:`
        <div>
            <div>{{name}}</div>
            <input v-model="name" />
        </div>
        ` 
    }) 
    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(数据双向绑定)中的修饰符。但是在学习修饰符前,我们补充一下上节遗漏的知识点。

### checkbox里的true-value和false-value

在上节课我们作了复选框选择truefalse的情况。新建一个文件,我们重现一下代码。

<!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-valuefalse-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中的组件概念。我们下一季见了,再见。

真诚感谢您的留言,我会亲自查收每一条留言并进行回复,审核后显示在文章底部。
您的昵称
电子邮件
最新留言

No Data

技术胖
光头Coder12年经验业余讲师免费视频被访问
只要50元/年 得3项福利

视频离线高清版下载-400集

每周至少两篇文章分享

每天回答所提问题(选择性回答)

关注公众号
扫码关注公众号
每周二,推送最新程序员软件技能视频
让技术和能力双成长