文章目录
1 Vue介绍
Vue简介
- Vue是一套用于构建用户界面的渐进式框架
- 简单理解就是用来做网页的框架
Vue优点
- 易用:相对于React和Angular来说,Vue上手简单
- 灵活:渐进式技术,能够开发任何规模的Web应用程序
- 性能:Vue采用了虚拟DOM、双向数据绑定等技术,运行速度快
下载/安装Vue
- 国内的一个网站:https://vue3js.cn/
- 安装Vue有三种方式
- CDN
- npm
- CLI
2 第一个Vue
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script src="./lib/vue.js"></script>
</head>
<body>
<div id="app">
{{msg}} - {{title}} - ${{(price * 0.8).toFixed(1)}}
</div>
<script>
Vue.createApp({
data() {
return {
msg: 'Hello Vue3.0',
title: 'introduction',
price: 117
}
}
}).mount('#app')
</script>
</body>
</html>
实现步骤
- 在页面中引入vue框架的核心文件
- 创建一个div标签,该标签要被Vue控制(挂载点)
- 使用Vue对象调用createApp方法来创建Vue应用实例,再调用mount方法将应用挂载到页面上(div标签中)
data
- data方法用来配置数据
- 内部必须使用return来返回一个对象
- 对象内的数据就是可用的数据,该数据可以在被控制的div区域内和createApp参数内使用
{{msg}}
- 插值表达式,表达式内写返回对象的key
- 将数据插入到页面中
- 插值表达式支持基本的计算操作
3 数据填充指令
<!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="./lib/vue.js"></script>
</head>
<body>
<div id="app">
<p>我是原有内容 --- {{msg}}</p>
<p v-html="msg">我是原有内容 --- </p>
<p v-text="msg">我是原有内容 --- </p>
</div>
<script>
Vue.createApp({
data () {
return {
msg: 'Hello World',
}
}
}).mount('#app')
</script>
</body>
</html>
- v-text 在DOM中插入纯文本数据,此指令不会出现闪动问题
- v-html 在DOM中插入HTML代码片段
- v-pre 在DOM中直接输出代码源码(格式化源码输出)
4 v-bind指令
用来为标签的属性节点绑定数据,可以简写为:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script src="./lib/vue.js"></script>
</head>
<body>
<div id="app">
<a v-bind:href="url" :title="title">{{website}}</a>
</div>
<script>
Vue.createApp({
data() {
return {
url: 'http://www.baidu.com',
title: '百度一下,你就知道',
website: '百度'
}
}
}).mount("#app")
</script>
</body>
</html>
5 class样式绑定
两种方式
- 对象方式:
<div v-bind:class="{ active: isActive}"></div>
- active:类名,定义在style标签中的类,书写css样式
- isActive:布尔值,true则active起效,false则active生效,定义在data中
- 数组方式:
<div v-bind:class="[fs, bgc]"></div>"
- fs、bgc:变量,要定义在data中
- fs、bgc的值是类名,定义在style标签中的类名
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script src="./lib/vue.js"></script>
<style>
.active {
color: red;
border: 1px solid #336950;
}
.add {
background-color: lightgreen;
}
.fs {
font-style: italic;
}
.bgc {
background-color: lightgrey;
}
</style>
</head>
<body>
<div id="app">
<p v-bind:class="{active: isActive, add: isAdd}">明月几时有,把酒问青天</p>
<h4 :class="[c1, c2]">不知天上宫阙,今夕是何年</h4>
</div>
<script>
const app = {
data() {
return {
isActive: true,
isAdd: false,
c1: "fs",
c2: "bgc"
}
}
}
Vue.createApp(app).mount("#app")
</script>
</body>
</html>
6 style样式绑定
两种方式
- 对象方式:
<div :style="{fontSize: fs}"></div>
- fontSize:属性名
- fs:样式值(变量),要定义在data中
- 数组方式:
<div :style="[c1, c2]"></div>
- c1,c2:变量,定义在data中
- c1,c2:值是对象形式,内部是样式属性和值
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script src="./lib/vue.js"></script>
</head>
<body>
<div id="app">
<p :style="{fontSize: objStyle.fs, backgroundColor: objStyle.bgc}">曲径通幽处</p>
<h4 v-bind:style="[c1, c2]">禅房花木深</h4>
</div>
<script>
const app = {
data() {
return {
objStyle: {
fs: '20px',
bgc: 'orange'
},
c1: {
fontSize: '30px',
color: 'blue',
backgroundColor: 'lightgrey'
},
c2: {
border: '2px solid red'
}
}
}
}
Vue.createApp(app).mount("#app")
</script>
</body>
</html>
7 v-on指令
用来为标签绑定事件,可以简写为@
<button v-on:click="handle">点我</button>
- v-on:用来绑定事件,后面是事件类型
- handle:事件要执行的函数,该函数要写在methods节点中
- methods是一个对象
- 在methods中可以书写很多函数
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script src="./lib/vue.js"></script>
<style>
.status {
width: 100px;
height: 100px;
line-height: 100px;
text-align: center;
background-color: orange;
color: #fff;
}
</style>
</head>
<body>
<div id="app">
<div
:class="{status: statusActive}"
v-on:click="handle"
@mouseenter="enter('哈哈哈我来了')"
>点我</div>
</div>
<script>
const app = {
data() {
return {
statusActive: true
}
},
methods: {
handle() {
this.statusActive = !this.statusActive
},
enter(str) {
console.log(str)
}
}
}
Vue.createApp(app).mount('#app')
</script>
</body>
</html>
在对象中如果想调用data中的数据,一定需要使用this指针
8 实现图片切换
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script src="./lib/vue.js"></script>
<style>
#app .content {
width: 600px;
margin: 30px auto;
}
#app .content img {
width: 600px;
}
#app .content div {
display: flex;
justify-content: space-between;
}
</style>
</head>
<body>
<div id="app">
<div class="content">
<img :src="list[i]">
<div>
<button @click="prev">上一张</button>
<button @click="next">下一张</button>
</div>
</div>
</div>
<script>
const app = {
data() {
return {
list: [
"./images/1.jpg",
"./images/2.jpg",
"./images/3.jpg",
"./images/4.jpg",
"./images/5.jpg"
],
i: 0
}
},
methods: {
prev() {
this.i = --this.i == -1 ? 4 : this.i
},
next() {
this.i = ++ this.i == 5 ? 0 : this.i
}
}
}
Vue.createApp(app).mount('#app')
</script>
</body>
</html>
9 v-if指令
能够根据表达式的真假值来有条件地渲染元素,还有v-else
、v-else-if
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script src="./lib/vue.js"></script>
</head>
<body>
<div id="app">
<p v-if="age > 18">成年人</p>
<p v-else>未成年人</p>
<h3 v-if="score >= 90">优秀</h3>
<h3 v-else-if="score >= 80 && score < 90">良好</h3>
<h3 v-else-if="score >= 70 && score < 80">中等</h3>
<h3 v-else-if="score >= 60 && score < 70">及格</h3>
<h3 v-else>不及格</h3>
</div>
<script>
const app = {
data () {
return {
age: 8,
score: 99
}
}
}
Vue.createApp(app).mount('#app')
</script>
</body>
</html>
10 v-for指令
循环渲染元素
<li
v-for="(item, index) in list"
:key="index"
>
{{item}}
</li>
- list:要进行循环遍历的数组
- item:每次取出的单元值
- index:每次取出的单元索引
- :key:为当前循环项绑定的唯一标识
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script src="./lib/vue.js"></script>
</head>
<body>
<div id="app">
<ul>
<li v-for="(item, index) in array" :key="index">{{item}}</li>
</ul>
</div>
<script>
const app = {
data() {
return {
array: ['关羽', '张飞', '赵云', '马超', '黄忠']
}
}
}
Vue.createApp(app).mount('#app')
</script>
</body>
</html>
11 v-model指令
用于数据的双向绑定
- data中定义的数据发生变化时,页面中的数据也跟着变化
- 修改页面中的数据时,data中的数据也会跟着变化
<input type="text" v-model="account">
data() {
return {
account: '用户名'
}
}
- account修改,input中的值就会修改
- input中的值修改,account的值也会修改
<!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="./lib/vue.js"></script>
<style>
input {
width: 260px;
}
textarea {
width: 260px;
margin-top: 10px;
vertical-align: top;
}
ul {
padding: 0px;
list-style: none;
width: 300px;
border: 1px solid #ccc;
border-radius: 5px;
}
.msg {
box-sizing: border-box;
width: 300px;
padding: 10px;
border-bottom: 1px solid #ccc;
}
.close {
float: right;
cursor: pointer;
}
span:hover {
visibility: visible;
}
</style>
</head>
<body>
<div id="app">
姓名: <input type="text" v-model="name" /><br>
留言: <textarea cols="22" rows="10" v-model="content" ></textarea><br>
<button @click="send">发表</button>
<ul>
<li class="msg" v-for="(item, index) in list" :key="index">
{{item.name}} : {{item.content}}
</li>
</ul>
</div>
<script>
const app = {
data () {
return {
list: [
{name:"后羿", content:"周日都让我射熄火了"},
{name:"鲁班", content:"智商250..."},
{name:"程咬金", content:"爱心之斧的正义冲击"},
{name:"孙悟空", content:"俺老孙来也"},
{name:"妲己", content:"妲己陪你玩哦"}
],
name: '',
content: ''
}
},
methods: {
send () {
if (this.name.trim().length === 0 || this.content.trim().length === 0) {
alert('请正确输入姓名和留言')
return;
}
let tmp = {name: this.name, content: this.content};
this.list.push(tmp);
this.name = '';
this.content = '';
}
}
}
Vue.createApp(app).mount('#app');
</script>
</body>
</html>
12 mvvm开发模式
MVVM是Model-View-ViewModel
- Model:模型,简单理解就是要操作的数据
- View:视图,就是页面结构
- ViewModel:视图模型,是连接Model和View的桥梁
MVVM的核心思想是让前端程序员专注于业务的实现,最大限度的减少DOM操作
13 CompositionAPI
Vue2采用的是OptionsAPI,Vue3采用的是CompositionAPI,Vue3兼容Vue2的OptionsAPI
14 响应式数据声明
① ref()
通常用来定义简单数据类型(数值型、字符串等)
使用时需要先从Vue中解构出来:const { ref } = Vue
<!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="./lib/vue.js"></script>
</head>
<body>
<div id="app">
<ul>
<li>姓名: {{name}}</li>
<li>
年龄: {{age}}
<button @click="add">+</button>
</li>
</ul>
姓名: <input type="text" v-model="name"><br>
年龄: <input type="text" v-model="age"><br>
</div>
<script>
// 1.从Vue对象中将ref方法解构出来
const { ref } = Vue;
// 使用ref来声明响应式数据
let name = ref('王小明');
let age = ref(8);
const add = () => {
console.log(age);
age.value++; // age是一个对象,需要修改其value值
}
const app = {
setup () {
return { name, age, add };
}
}
Vue.createApp(app).mount('#app');
</script>
</body>
</html>
② reactive
通常用来定义复杂数据类型(数组、对象)
使用时需要先从Vue中解构出来:const { reactive } = Vue
<!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="./lib/vue.js"></script>
</head>
<body>
<div id="app">
<ul>
<li v-for="item in list" :key="item.id">
{{item.id}} - {{item.name}} - {{item.age}}
</li>
<li>
{{user.id}} - {{user.name}} - {{user.age}}
</li>
</ul>
<button @click="show">点我</button>
</div>
<script>
const { reactive } = Vue;
const list = reactive([
{id: 1, name: 'zs', age: 8},
{id: 2, name: 'ls', age: 12},
{id: 3, name: 'ww', age: 10}
])
const user = reactive({
id: 4,
name: 'zl',
age: 9
})
const show = () => {
alert('哈哈哈');
}
const app = {
setup () {
return { list, user, show }
}
}
Vue.createApp(app).mount('#app');
</script>
</body>
</html>
15 生命周期
- 生命周期:Vue实例挂载、更新、销毁的过程
- Vue实例的生命周期会伴随各种事件,这些事件对应的函数叫做生命周期函数/生命周期钩子/生命周期钩子函数
- 生命周期函数会在某一时刻自动运行
① OptionsAPI
挂载:创建Vue实例并挂载到页面上
- beforeCreate:创建之前
- created:创建完成,一般用来初始化页面需要的数据
- beforeMount:挂载之前
- Mounted:挂载完成,挂载完成后可以直接操作DOM对象
更新:页面发生变化
- beforeUpdate:更新之前
- updated:更新完成
<!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="./lib/vue.js"></script>
</head>
<body>
<div id="app">
<p>{{msg}}</p>
<button @click="change">更新</button>
</div>
<script>
const { ref } = Vue;
let msg = ref('');
const app = {
beforeCreate () {
console.log('beforeCreate');
},
created () {
msg.value = 'Hello World';
console.log('created');
},
beforeMount () {
console.log('beforeMount');
},
mounted () {
document.querySelector('p').style.color = 'red';
console.log('mounted');
},
beforeUpdate () {
console.log('beforeUpdate');
},
updated () {
console.log('updated');
},
setup () {
change = () => {
msg.value = '你好,世界';
}
return { msg, change }
}
}
// createApp 用来创建Vue实例
// mount 用来将实例挂载到页面上
Vue.createApp(app).mount('#app');
</script>
</body>
</html>
② CompositionAPI
- 取消了beforeCreate和created,直接使用setup即可
- 所有的钩子函数必须从Vue对象中解构出来
- 所有的钩子函数前都要加on
<!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="./lib/vue.js"></script>
</head>
<body>
<div id="app">
<p>{{msg}}</p>
<button @click="change">更新</button>
</div>
<script>
// 钩子函数必须从Vue对象中解构出来
const {
ref,
onBeforeMount,
onMounted,
onBeforeUpdate,
onUpdated
} = Vue;
let msg = ref('');
// 初始化数据的方法,在setup中直接调用即可
const getDate = () => {
msg.value = 'Hello World';
}
Vue.createApp({
setup () {
getDate();
onBeforeMount(() => {
console.log('onBeforeMount');
})
onMounted(() => {
document.querySelector('p').style.color = 'red';
console.log('onMounted');
})
onBeforeUpdate (() => {
console.log('onBeforeUpdate');
})
onUpdated (() => {
console.log('onUpdated');
})
change = () => {
msg.value = '你好,世界';
}
return { msg, change }
}
}).mount('#app');
</script>
</body>
</html>