0%

基础语法

本节主要讲解vue中的文件结构, 基础语法, 常用指令, 以及部分生命周期函数等, 都是写比较入门的知识点

文件结构

在vue的项目中, 我们常常能看到以 .vue 为后缀的文件, 这些文件其实就是vue的页面文件

我们可以这样来理解:

一个 xxx.vue 就是一个页面

或者

一个 xxx.vue 就是页面中的某一个部分(比如某个页面中的某个列表)

既然我们说了, 一个vue文件, 就相当于是一个页面, 那么, 在前端世界中, 一个页面是由什么组成的呢?

在浏览器中, 我们能看到的页面, 都是由一堆的 HTML + CSS + JS 所组成

HTML定义一个人的骨骼

CSS定义一个人的外观

JS则定义一个人的行为

那么, 既然vue文件能代表一个页面, 它就必定会包含以上这三种组成单位, 也就是说, 在vue文件里, 肯定也会有 HTML + CSS + JS

那么, 这些都是写在哪里的呢?

让我们来看一个.vue 的文件结构

<template></template>

<script></script>

<style></style>

上面, 就是一个vue文件的基本组成结构

  • template : 这里面是写HTML的地方
  • script: 这里面是写js的地方
  • style: 这里是写css的地方

这三个的区别和作用要牢牢记住!!!


示例

我们来修改App.vue文件, 内容如下

<template>
<div>
<button class="btn">这是一个按钮</button>
</div>
</template>

<style>
.btn {
width: 120px;
height: 50px;
color: #fff;
background-color: orange;
}
</style>

那么, 上面这个文件, 在浏览器的展示效果就是像下面这样子

image-20211124174958689


数据绑定

让我们来看一个例子

<template>
<ul>
<li>姓名: 张三</li>
<li>性别: 男</li>
<li>年龄: 18</li>
<li>学号: 2017130305</li>
</ul>
</template>

上面就是一个很简单的例子, 在页面中展示一个列表, 有没有看出什么问题呢?

问题就在于, 现在页面中的数据, 都是写死的

这些数据后期都是要从后台数据库过来的, 你现在写死在页面中, 后面就没法改了

让我们来改造一下

<template>
<ul>
<li>姓名: {{name}}</li>
<li>性别: {{gender}}</li>
<li>年龄: {{age}}</li>
<li>学号: {{sno}}</li>
</ul>
</template>

<script>
export default {
data() {
return {
name: '张三',
gender: '男',
age: 18,
sno: '2017130305'
}
}
}
</script>

把代码改成上面这种形式后, 在浏览器中能看到, 我们的效果还是一样的, 那么它们的区别又在哪里?

在说到区别之前, 我们得先讲讲 script 里的代码是什么意思

export default {
// 在vue中, 页面中用到的js代码, 都要写到这里面来, 你可以理解为是固定格式
}
data() {
return {
name: '张三',
gender: '男',
age: 18,
sno: '2017130305'
}
}

data 是一个函数, 不管这个函数里面干了什么其他东西, 最后, 都 必须return一个对象, 在template中用到的一切变量, 都是由data的返回值决定的.

也就是说: data里return出了什么, HTML中就只能用什么

就像上面的例子, data最后return了 name, gender, age, sno, 所以我们的template中才可以使用它

那么, 在template中, 又是如何使用 data 中的数据呢?

答案就是: 插值表达式, 也就是双花括号, 格式为{{ 变量名 }}

<li>姓名: {{name}}</li>
<li>性别: {{gender}}</li>
<li>年龄: {{age}}</li>
<li>学号: {{sno}}</li>

上面这个例子就代表, 使用data返回出来的name, gender, age, sno, 在页面中显示这几个变量的值, 所以我们才能在浏览器中看到效果

而这, 也就是我们所说的数据绑定!

在vue世界中有一个原则, 你页面中所用到的数据, 都应该来自于 data, 要好好理解这句话


指令

什么是指令, 指令的作用是啥, 常用的指令有哪些? 我们依次来进行回答

  • 什么是指令?

指令是一种以 v- 开头的特殊标记, 它们具有自己独有的特性, 指令会为自己绑定的HTML元素提供某种特殊的行为

  • 指令的作用是啥?

表达式的值发生改变时,会将某种行为, 作用到HTML元素身上

  • 常用的指令
    • v-show
    • v-if
    • v-for
    • v-bind
    • v-model
  • 如何绑定指令

指令只能在HTML元素身上进行绑定, 且必须为它赋予一个表达式或值, 例如下面的例子

<template>
<button v-aaa="bbb">我是一个按钮</button>
</template>

可以看到, 上面的 v-aaa 代表指令的名称, bbb 就是控制它行为的表达式的值

也就是说, 上面的这个例子就是, 我给一个按钮, 添加了一个指令, 指令名是v-aaa, 这个指令的行为将由bbb来进行控制, bbb不同的值, 有可能会影响到v-aaa的行为


v-show

根据表达式的 true / false , 控制元素的显示与隐藏, 其效果等同于css中的display

其中, true 为显示, false 为隐藏

<template>
<button v-show="true">按钮1</button>
<button v-show="false">按钮2</button>
</template>

上面的例子在浏览器中可以看到, 只有 按钮1 展示在页面中, 按钮2并不在页面上


v-if

与 v-show 类似, 同样是 控制元素的显示与隐藏, 区别在于

  • v-show仅仅是隐藏起来, display: none 掉了, 但它的HTML元素仍然存在
  • v-if 就类似于, 直接让你这个元素人间蒸发, 直接将一个元素从页面中彻底抹除了

举一个形象的例子:

v-show相当于死了, 但是尸体还在

v-if相当于死了, 灰飞烟灭了, 人间蒸发了, 连尸体都没有, 毛都没有给你留下

下面的例子

<template>
<button v-if="true">按钮1</button>
<button v-if="false">按钮2</button>
</template>

上面的例子在浏览器中可以看到, 只有 按钮1 展示在页面中, 按钮2并不在页面上

学过编程语言的都知道, if一般都会搭配有 else 或者 else if 的对吧, 那么我们这里也同样有

<template>
<button v-if="a > 10">按钮1</button>
<button v-else-if="a > 5">按钮2</button>
<button v-else>按钮3</button>
</template>

上面的例子中, 如果 a > 10, 展示按钮1, 否则再看看a是否大于5, 假如a>5, 显示按钮2, 如果前面2个条件都不满足, 则显示按钮3

注意:

v-if, v-else-if, v-else这三个, 都必须紧挨着, 不能被其它html元素隔开, 例如下面这个写法就是错误的!!!

><template>
<button v-if="true">按钮1</button>
<h1>我是靓仔</h1>
<button v-else>按钮3</button>
></template>

这个是错误写法! v-if和v-else必须紧挨着, 但现在却被h1给隔开了


v-for

v-for类似于for循环, 常用于帮助我们生成一组HTML元素

v-for的格式如下:

<div v-for="(item, index) in 数组">
{{index}}-{{item}}
</div>

上面的 item 代表遍历出来的每一个数组元素, index代表这个数组元素的索引, 它们都是一个变量, 我们之前是不是说过了, 在template中, 如果要展示一个变量, 必须将它放到 {{ 变量名 }} 之中

我们来看下面这个例子

<template>
<div>
<p v-for="(item, index) in list">
{{index}}-{{item.name}}-{{item.age}}
</p>
</div>
</template>

<script>
export default {
data() {
return {
list: [
{ name: '张三', age: 18 },
{ name: '李四', age: 19 },
{ name: '王五', age: 20 },
{ name: '赵六', age: 21 },
]
}
}
}
</script>

上面我们做了几件事, 在data中返回了一个变量list, list是一个数组, 数组里的每一个元素都是一个对象, 代表一个人的信息

现在我们的需求是通过 v-for, 把list数组里所有人的数据, 渲染到页面上

最终我们会看到的效果如下:

0-张三-18
1-李四-19
2-王五-20
3-赵六-21

v-for 写在谁的身上, 谁就会被循环生成

如上面的例子, v-for 写在 p标签身上, 所以p标签会被循环生成多个


v-bind

v-bind的作用是绑定html标签的属性值

什么叫标签的属性?

一个标签, 有开始标记和结束标记, 标签的属性都是写在标签的开始标记内.

如下:

<!-- 这里div有2个属性, 一个是class, 一个是id -->
<div class="a" id="b"></div>

<!-- 这里img有2个属性, 一个是src, 一个是alt -->
<img src="" alt="this is a dog picture">

<!-- 这里a标签有1个属性, 属性名是href, 属性值是https://dev-pro.cn -->
<a href="https://dev-pro.cn"></a>

通过上面这个例子, 大家应该就明白, 什么是标签的属性了

而v-bind的作用就是用来绑定这些属性的值

v-bind有2种写法, 分别如下

  • <img v-bind:src="xxx">
  • <img :src="xxx">

上面这2种写法是等价的, 一般我们用第二种, 因为只需要写一个冒号, 毕竟少些几个字也是一种幸福嘛

那么我们看一个例子

<template>
<div>
<img v-for="(item, index) in list" :src="item"/>
</div>
</template>

<script>
export default {
data() {
return {
list: [
'https://img2.baidu.com/it/u=4227461358,3954516006&fm=26&fmt=auto',
'https://img0.baidu.com/it/u=3825072512,2281091901&fm=26&fmt=auto',
'https://img0.baidu.com/it/u=2081960888,724997668&fm=26&fmt=auto',
'https://img0.baidu.com/it/u=3451109178,1218512092&fm=26&fmt=auto',
]
}
}
}
</script>

上面这个例子是, 我们在data中定义了一个变量list, 它是一个数组, 里面存放的是图片的链接地址

然后在html中, 我们通过 v-for 来帮我们遍历list数组, 循环生成img标签, 并且将img身上的src属性值绑定为遍历出来的item(图片链接)


v-model

v-model主要是实现表单的双向数据绑定, 它只能用在表单元素身上

什么是表单元素, 就是 input, select , radio , checkbox, textarea 之类的标签, v-model只对这类型的标签有效果

我们看下面的例子

<template>
<div>
<input v-model="phone"/>
<input v-model="password"/>
</div>

<hr>

<div>
<input v-model="phone"/>
</div>
</template>

<script>
export default {
data() {
return {
phone: '',
password: ''
}
}
}
</script>

这是一个类似于登陆的案例, 页面中有2个输入框, 需要我们输入手机号码和密码

如果在浏览器运行, 我们可以看到, 当我们在上方输入框中输入的时候, 下方的 input标签内容也会同步发生变化, 这就是所谓的双向数据绑定

说白了, 双向数据绑定就是:

我这里的数据发生变化, 你也会跟着变化

你那里的数据发生变化, 我这里也会跟着变化

他们是互相影响的

它们的数据流通过程为:

  1. v-model把你输入的内容设置到phone身上
  2. 由于phone的值被更新了, 所以另一个用到phone的input也发生了变化

事件

事件, 也就是给元素绑定某种事件, 比如点击事件, 鼠标移入事件, 鼠标移出事件等等

给元素添加事件的语法为:

  1. @ + 事件名 = "处理函数"
  2. v-on + 事件名 = "处理函数"

这2种方式用哪种都可以, 都是等价的, 我们一般用@开头的方式, 毕竟写的字数更少一点嘛

<button @click="handleClick">按钮</button>

上面例子的意思是, 给button标签绑定一个click(点击)事件, 当按钮被点击时, 执行 handleClick 这个函数

我们知道了如何给元素绑定事件, 那么它的处理函数要写在哪里呢? 这就涉及到了我们的新内容, methods

<script>
export default {
methods: {
handleClick() {
// 函数体
}
}
}
</script>

methods 在vue中是专门用来写函数的, 页面中用到的所有函数, 都应该写在methods里

我们再看下面这个例子

<script>
export default {
methods: {
fnA() {},
fnB() {},
fnC() {},
fnD() {}
}
}
</script>

观察上面的例子, 我们能看出, methods里有4个函数

好的, 那么我们来完善一下最开始的案例, 现在, 我想着, 当我点击按钮的时候, 弹出一个警告框, 我们可以这么来写

<template>
<!-- 鼠标点击 -->
<button @click="handleClick">点击</button>
<!-- 鼠标移入 -->
<button @mouseenter="handleClick">移入</button>
<!-- 鼠标点击 v-on写法 -->
<button v-on:click="handleClick">点击</button>
</template>

<script>
export default {
methods: {
// button的点击事件处理函数
handleClick() {
// 弹框
alert('我是一个弹框')
}
}
}
</script>

**常见的事件: ** 事件参考 | MDN (mozilla.org)


生命周期函数

所谓的生命周期函数, 就是指在页面的生命周期内, 会执行的函数

那么什么是生命周期呢? 我们这里只介绍3个就够了

  • 页面初始化后

  • 页面加载后

  • 页面关闭前

页面初始化后, 对应的是函数是 created

<script>
export default {
created() {
// 在页面初始化后, 这里的代码会自动被执行
}
}
</script>

一般我们在这里就开始发送请求给后台, 也就是, 趁着页面还没有加载完, 先问后台拿一些数据


页面加载后, 对应的函数是 mounted

<script>
export default {
mounted() {
// 在页面加载后, 这里的代码会自动被执行
}
}
</script>

到这一步后, 页面已经加载完毕了, 我们在这里可能会对页面做一些更改, 或者再次请求后台拿其它数据等


页面关闭前, 对应的函数是 beforeDestroy

<script>
export default {
beforeDestroy() {
// 在页面关闭前, 或者离开本页面之前, 这里的代码会自动被执行
}
}
</script>

一般我们会在这里做一些收尾, 清理的工作, 比如清除页面中的定时器等等


小案例

我们来做一个小案例

我们有一个人员列表页面

  1. 在页面加载前, 获取后台的人员列表数据
  2. 在页面加载完成之后, 统计人员数量, 并显示到页面中
  3. 人员列表通过v-for进行渲染
  4. 如果某个人的年龄大于30岁, 则不展示(用v-if)
  5. 点击某个人的姓名, 会弹出警告框
  6. 离开页面前, 弹框
<template>
<ul>
<li v-for="(item, index) in list">
<div v-if="item.age <= 30">
<span @click="handleClick">{{item.age}}</span>
<img :src="item.avatar"/>
</div>
</li>
<li>人员数量总计: {{total}}</li>
</ul>
</template>

<script>
export default {
data() {
return {
// 人员列表数据
list: [],
// 人员数量, 默认0个
total: 0,
}
},
methods:{
handleClick() {
alert('我是一个警告框')
}
},
// 生命周期-页面初始化后立即请求后台获取数据
created() {
// 假设我们这个数组是请求后台得到的, 设置给data里的list
this.list = [
{ name: '张三', age: 18, avatar: 'https://img1.baidu.com/it/u=3303981320,1355171730&fm=26&fmt=auto' },
{ name: '李四', age: 38, avatar: 'https://img2.baidu.com/it/u=1960058469,2576593478&fm=26&fmt=auto' },
{ name: '王五', age: 28, avatar: 'https://img0.baidu.com/it/u=1899727048,1785466738&fm=26&fmt=auto' },
];
},
// 生命周期-页面加载完毕后立即计算人员数量
mounted() {
// 设置人员数量等于数组的长度
this.total = this.list.length;
},
// 生命周期-页面被关闭前
beforeDestroy() {
// 这里会自动去拿到methods里的handleClick
this.handleClick();
}
}
</script>

tips:

在script标签中, 假如我们需要获取一个变量, 获取其它函数, 我们需要在前面跟上 this.

例如: this.list, this.total = 5, this.handleClick()

-------------本文结束    感谢阅读-------------
坚持原创技术分享,您的支持将鼓励我继续创作!