一、Vue3简介
1.Vue是什么
Vue是一套用于构建用户界面的渐进式的JavaScript框架。所谓渐进式就是可以自底向上逐层的应用。

2.Vue的特点
1.采用组件化 模式,提高代码复用率 、且让代码更好维护。
2.声明式 编码,让编码人员无需直接操作DOM,提高开发效率。
3.使用虚拟DOM+优秀的Diff 算法,尽量复用DOM节点,。
3.Vue的API风格

Vue的组件可以按两种不同的风格书写:选项式API( 可以理解成Vue2版本)和组合式API (可以理解成Vue3版本)。
大部分的核心概念在这两种风格之间都是通用的。熟悉了一种风格以后,你也能够很快地理解另一种风格。
选项式API(Options API)
使用选项式API,我们可以用包含多个选项的对象来描述组件的逻辑,例如data 、methods 和mounted 。选项所定义的属性都会暴露在函数内部的this上,它会指向当前的组件实例。
javascript
<template>
<button @click="increment">Count is: {{ count }}</button>
</template>
<script>
export default {
data() {
return {
count: 0
}
},
methods: {
increment() {
this.count++
}
},
mounted() {
console.log(`The initial count is ${this.count}.`)
}
}
</script>
组合式API(CompositionAPl)
通过组合式API,我们可以使用导入的API函数来描述组件逻辑。
javascript
<template>
<button @click="increment">Count is: {{ count }}</button>
</template>
<script setup>
import { ref, onMounted } from 'vue'
const count = ref(0)
function increment() {
count.value++
}
onMounted(() => {
console.log(`The initial count is ${count.value}.`)
})
</script>
4.Vue开发前的准备

构建工具 让我们能使用Vue单文件组件(SFC)。Vue官方的构建流程是基于Vite的,一个现代、轻量、极速的构建工具

创建Vue项目
bash
npm init vue@latest
这一指令将会安装并执行create-vue,它是Vue官方的项目脚手架工具。你将会看到一些诸如TypeScript和测试支持之类的可选功能提示。

注意项目名字不要存在字母大写!
之后我们cd 到项目目录,执行
bash
#安装依赖
npm install
#运行项目
npm run dev
当看到下面的信息,证明项目运行成功了

我们复制链接到浏览器打开,网页内容如下

5.Vue项目目录结构

二、Vue语法
1.模版语法

Vue使用一种基于HTML的模板语法,使我们能够声明式地将其组件实例的数据绑定到呈现的DOM上。所有的Vue模板都是语法层面合法的HTML,可以被符合规范的浏览器和HTML解析器解析。
文本插值
最基本的数据绑定形式是文本插值,它使用的是"Mustache"语法(即双大括号):
javascript
<template>
<p>{{msg}}</p>
</template>
<script>
export default{
data(){
return{
msg:"神奇的魔法"
}
}
}
</script>
使用JavaScript表达式
每个绑定仅支持单一表达式 ,也就是一段能够被求值的JavaScript代码。一个简单的判断方法是是否可以合法地写在returm后面
javascript
<template>
<h3>模版语法</h3>
<p>{{msg}}</p>
<p>{{number+1}}</p>
<p>{{ok ? 'yes':'no'}}</p>
<p>{{message.split('').reverse().join('')}}</p>
</template>
<script>
export default{
data(){
return{
msg:"神奇的魔法",
number:10,
ok:true,
message:"神奇的魔法"
}
}
}
</script>
无效
html
<!-- 这是一个语句,而非表达式 -->
{{var a = 1}}
<!-- 条件控制也不支持,请使用三元表达式 -->
{{if (ok) { retrun message }}}
原始HTML
双大括号将会将数据插值为纯文本,而不是HTML。若想插入HTML,你需要使用v-html 指令。
javascript
<template>
<h3>模版语法</h3>
<p>{{msg}}</p>
<p>{{number+1}}</p>
<p>{{ok ? 'yes':'no'}}</p>
<p>{{message.split('').reverse().join('')}}</p>
<p v-html="rawHtml"></p>
</template>
<script>
export default{
data(){
return{
msg:"神奇的魔法",
number:10,
ok:true,
message:"神奇的魔法",
rawHtml:'<a href="https://www.baidu.com">神奇的链接</a>'
}
}
}
</script>
2.属性绑定

双大括号不能在HTMLattributes中使用。想要响应式地绑定一个attribute,应该使用v-bind指令
javascript
<template>
<div v-bind:id="id" v-bind:class="msg">测试</div>
</template>
<script>
export default {
data() {
return {
msg: 'active',
id:"customid"
}
}
}
</script>
v-bind 指令指示Vue将元素的id attribute与组件的dynamicld属性保持一致。如果绑定的值是null 或者undefined ,那么该attribute将会从渲染的元素上移除
javascript
<template>
<div v-bind:id="id" v-bind:class="msg" v-bind:title="title">测试</div>
</template>
<script>
export default {
data() {
return {
msg: 'active',
id:"customid",
title:null
}
}
}
</script>
简写
因为v-bind非常常用,我们提供了特定的简写语法:
html
<div :id="id" :class="msg" :title="title">测试</div>
布尔型Attribute
布尔型attribute依据true/false值来决定attribute是否应该存在于该元素上,disabled就是最常见的例子之一。
javascript
<template>
<button :disabled="isButtonDisenabled">按钮</button>
</template>
<script>
export default {
data() {
return {
isButtonDisenabled: true
}
}
}
</script>
我们可以看到此时按钮是不可点击的

动态绑定多个值
如果你有像这样的一个包含多个attribute的JavaScript对象
javascript
<template>
<div v-bind="obiectOfAttrs">测试</div>
</template>
<script>
export default {
data() {
return {
customid: 'customid',
customclass: 'customclass',
obiectOfAttrs: {
id: "customid",
class: "customclass"
}
}
}
}
3.条件渲染

在Vue中,提供了条件渲染,这类似于JavaScript 中的条件语句
- v-if
- v-else
- v-esle-if
- v-show
v-if
v-if指令用于条件性地渲染一块内容。这块内容只会在指令的表达式返回真值时才被渲染
javascript
<template>
<h3>条件渲染</h3>
<div v-if="flag">你能看见我么</div>
</template>
<script>
export default {
data(){
return {
flag: true
}
}
}
</script>
v-else
你也可以使用v-else为v-if添加一个"else区块"
javascript
<template>
<h3>条件渲染</h3>
<div v-if="flag">你能看见我么</div>
<div v-else>那你还是看我吧</div>
</template>
<script>
export default {
data(){
return {
flag: false
}
}
}
</script>
v-else-if
顾名思义,v-else-if提供的是相应于vif的"else if区块"。它可以连续多次重复使用
javascript
<template>
<h3>条件渲染</h3>
<div v-if="type === 'A'">
A
</div>
<div v-else-if="type === 'B'">
B
</div>
<div v-else-if="type === 'C'">
C
</div>
<div v-else>
NOT A/B/C
</div>
</template>
<script>
export default {
data(){
return {
type:"D"
}
}
}
</script>
v-show
另一个可以用来按条件显示一个元素的指令是**v-show。**用法基本一样
javascript
<template>
<h3>条件渲染</h3>
<div v-show="flag">你能看见我么</div>
</template>
<script>
export default {
data(){
return {
flag: true
}
}
}
</script>
v-if Vs v-show
v-if是"真实的"按条件渲染,因为它确保了在切换时,条件区块内的事件监听器和子组件都会被销毁与重建。
v-if也是惰性的:如果在初次渲染时条件值为false,则不会做任何事。条件区块只有当条件首次变为true时才被渲染。
相比之下,v-show简单许多,元素无论初始条件如何,始终会被渲染,只有CSS display属性会被切换。
总的来说,v-if有更高的切换开销,而v-show有更高的初始渲染开销。因此,如果需要频繁切换,则使用v-show较好;如果在运行时绑定条件很少改变,则v-if会更合适
4.列表渲染

我们可以使用v-for 指令基于一个数组来染一个列表。v-for 指令的值需要使用item in items 形式的特殊语法,其中items是是源数据的数组,而item是迭代项的别名。
javascript
<template>
<div>
<p v-for="item in names">{{ item }}</p>
</div>
</template>
<script>
export default {
data() {
return {
names: ["Mike", "Jane", "Tom"],
};
},
};
</script>
复杂数据
大多数情况,我们渲染的数据源来源于网络请求,也就是JSON格式
v-for 也支持使用可选的第二个参数表示当前项的位置索引
javascript
<template>
<div v-for="item in result">
<p >{{ item.id }}</p>
<img :src="item.avator" alt="">
</div>
<p v-for="(item,index) in names">{{index}}:{{item}}</p>
</template>
<script>
export default {
data() {
return {
names: ['张三', '李四', '王五'],
result: [
{
"id": "ITEM001",
"name": "产品A",
"avator": "https://p3-search.byteimg.com/obj/pgc-image/432eddcf18fc472b9429556ea80f64cf"
},
{
"id": "ITEM002",
"name": "产品B",
"avator": "https://p3-search.byteimg.com/img/labis/7d19a60bce9c75c0ddd71bd92d7e007b~480x480.JPEG"
},
{
"id": "ITEM003",
"name": "产品C",
"avator": "https://p3-search.byteimg.com/obj/pgc-image/153355020857866fdf59e72"
}
]
};
},
};
</script>
你也可以使用作of 为分隔符来替代 in 这更接近JavaScript的迭代器语法
javascript
<div v-for="item of result">
v-for与对象
你也可以使用v-for来遍历一个对象的所有属性
javascript
<template>
<div v-for="item of result">
<p >{{ item.id }}</p>
<img :src="item.avator" alt="">
</div>
<p v-for="(item,index) in names">{{index}}:{{item}}</p>
<div v-for="item of userInfo">{{ item }}</div>
</template>
<script>
export default {
data() {
return {
names: ['张三', '李四', '王五'],
result: [
{
"id": "ITEM001",
"name": "产品A",
"avator": "https://p3-search.byteimg.com/obj/pgc-image/432eddcf18fc472b9429556ea80f64cf"
},
{
"id": "ITEM002",
"name": "产品B",
"avator": "https://p3-search.byteimg.com/img/labis/7d19a60bce9c75c0ddd71bd92d7e007b~480x480.JPEG"
},
{
"id": "ITEM003",
"name": "产品C",
"avator": "https://p3-search.byteimg.com/obj/pgc-image/153355020857866fdf59e72"
}
],
userInfo: {
name: '张三',
age: 18,
sex: '男'
}
};
},
};
</script>
5.通过key管理状态

Vue默认按照"就地更新"的策略来更新通过v-for渲染的元素列表。当数据项的顺序改变时,Vue不会随之移动DOM元素的顺序,而是就地更新每个元素,确保它们在原本指定的索引位置上渲染。
为了给Vue一个提示,以便它可以跟踪每个节点的标识,从而重用和重新排序现有的元素,你需要为每个元素对应的块提供一个唯一的key attribute:
javascript
<template>
<h3>key属性添加到v-for</h3>
<p v-for="(item,index) in names" :key="index">{{item}}</p>
</template>
<script>
export default {
data(){
return{
names:["张三","李四","王五"]
}
}
};
</script>
温馨提示
key 在这里是一个通过v-bind 绑定的特殊attribute
推荐在任何可行的时候为v-for 提供一个keyattribute
key 绑定的值期望是一个基础类型的值,例如字符串或number类型
key的来源
请不要使用index作为key的值,我们要确保每一条数据的唯一索引|不会发生变化
javascript
<template>
<div v-for="item of result" :key="item.id">
<p >{{ item.id }}</p>
<img :src="item.avator" alt="">
</div>
<p v-for="(item,index) in names" :key="item">{{index}}:{{item}}</p>
<div v-for="item of userInfo">{{ item }}</div>
</template>
<script>
export default {
data() {
return {
names: ['张三', '李四', '王五'],
result: [
{
"id": "ITEM001",
"name": "产品A",
"avator": "https://p3-search.byteimg.com/obj/pgc-image/432eddcf18fc472b9429556ea80f64cf"
},
{
"id": "ITEM002",
"name": "产品B",
"avator": "https://p3-search.byteimg.com/img/labis/7d19a60bce9c75c0ddd71bd92d7e007b~480x480.JPEG"
},
{
"id": "ITEM003",
"name": "产品C",
"avator": "https://p3-search.byteimg.com/obj/pgc-image/153355020857866fdf59e72"
}
],
userInfo: {
name: '张三',
age: 18,
sex: '男'
}
};
},
};
</script>
6.事件处理

我们可以使用v-on 指令(简写为**@** )来监听DOM事件,并在事件触发时执行对应的JavaScript。用法:v-on:click="methodName" 或**@click="handler"**
事件处理器的值可以是:
- 内联事件处理器:事件被触发时执行的内联JavaScript语句(与onclick类似)
- 方法事件处理器:一个指向组件上定义的方法的属性名或是路径
内联事件处理器
内联事件处理器通常用于简单场景
javascript
<template>
<h3>内联事件处理器</h3>
<button @click="count++">点我</button>
<p>{{count}}</P>
</template>
<script>
export default {
data(){
return {
count:0
}
}
}
</script>
方法事件处理器
javascript
<template>
<h3>方法事件处理器</h3>
<button @click="addCount">点我</button>
<p>{{count}}</P>
</template>
<script>
export default {
data(){
return {
count:0
}
},
//所有的方法和函数都放在这里
methods:{
addCount(){
this.count++
}
}
}
</script>
7.事件参数

事件参数可以获取event对象和通过事件传递数据
获取event对象
javascript
<template>
<h3>事件传参</h3>
<p @click="getNameHandler(item)" v-for="(item,index) in names" :key="index">{{ item }}</p>
</template>
<script>
export default {
data(){
return {
names:['张三','王五','小王']
}
},
methods:{
getNameHandler(item){
console.log(item)
}
}
}
</script>