目录
1.什么是Vue
Vue 是一款用于构建用户界面的渐进式 JavaScript 框架。而构建用户界面就相当于把拿到手里的数据通过某种办法变成用户可以看见的界面。而其中渐进式指Vue可以自底向上逐层的应用(从一个轻量小巧的核心库逐渐递进到使用各式各样的Vue插件库)。
2.Vue特点
- 采用组件化模式,提高代码复用率
每个.vue相当于html、css、js文件的结合封装
- 声明式编码,让编码人员无需直接操作DOM,提高开发效率
命令式编码效率低
新旧虚拟DOM的diff比较
3.Vue如何运作
Vue提前定义好的事件, 每个 Vue 应用都是通过 createApp 函数创建一个新的 应用实例:
<script>
//创建Vue实例
const { createApp } = Vue
createApp({
data() {//相当于data:fuction() 不能用=>
return {
message: 'Hello Vue!',
name:"jzy",
url :'https://blog.csdn.net/JiangZhengyang7?spm=1018.2226.3001.5343',
school:{
name:'jiangzhengyang'
}
}
}
}).mount('#app')
// 相当于_el 挂载 const x = vue{} x.mount(#app)
</script>
通过.mount或el挂载,相当于用于指定当前Vue实例为哪个容器服务,值通常为css选择器字符串
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>开始学习 Vue</title>
<script src="https://unpkg.com/vue@3/dist/vue.global.js"></script>
</head>
<body>
<div id="app">
<h1>你好{
{name}} </h1>
<h2>{
{message}}</h2>
<a v-bind:href="url">click1</a>
<a :href="url">click2</a>
<p>Using v-html directive: <span v-html="url"></span></p>
<h2>{
{school.name}}</h2>
</div>
<!--v-bind 引号里的东西用作js表达式 -->
</body>
3.1 MVVM模型
M:模型
V:视图
VM:视图模型
其中,VM相当于Vue的实例对象,V相当于模板,M对应data中的数据,Vue相当于将一堆数据和DOM结构进行连接,是一个实例对象。
3.2 生命周期:
生命周期:
- 又名:生命周期回调函数、生命周期函数、生命周期钩子
- 是什么:Vue在关键时刻帮我们调用的一些特殊名称的函数
- 生命周期函数的名字不可更改,但函数的具体内容是程序员根据需求编写的
- 生命周期函数中的this指向是vm 或 组件实例对象
常用的生命周期钩子:
- mounted:发送ajax请求、启动定时器、绑定自定义事件、订阅消息等初始化操作
- beforeDestroy:清除定时器、解绑自定义事件、取消订阅消息等收尾工作
关于销毁Vue实例:
- 销毁后借助Vue开发者工具看不到任何信息
- 销毁后自定义事件会失效,但原生DOM事件依然有效
- 一般不会在beforeDestroy操作数据,因为即便操作数据,也不会再触发更新流程了
4.Vue模板语法
4.1文本插值
最基本的数据绑定形式是文本插值,它使用的是“Mustache”语法 (即双大括号):
<span>Message: {
{ msg }}</span>
双大括号标签会被替换为相应组件实例中 msg
属性的值。同时每次 msg
属性更改时它也会同步更新。
4.2 attributes绑定
双大括号不能在 HTML attributes 中使用。想要响应式地绑定一个 attribute,应该使用
<div v-bind:id="dynamicId"></div>
v-bind
指令指示 Vue 将元素的 id
attribute 与组件的 dynamicId
属性保持一致。如果绑定的值是 null
或者 undefined
,那么该 attribute 将会从渲染的元素上移除。
因为 v-bind
非常常用,我们提供了特定的简写语法:
<div :id="dynamicId"></div>
其中v-bind 引号里的东西用作js表达式
这些带有 v-
前缀为Vue 的内置指令
4.3 单向、双向绑定
v-model指令可以在表单 input、textarea以及select元素上创建双向数据绑定它会根据控件类型自动选取正确的方法来更新元素。尽管有些神奇,但 v-model 本质上不过是语法糖,它负责监听用户的输入事件来更新数据。
简而言之页面上的改变能映射到数据的改变
- 什么场景下会使用v-model?
表单提交是开发中非常常见的功能,也是和用户交互的重要手段:比如用户在登录、注册时需要提交账号密码;比如用户在检索、创建、更新信息时,需要提交一些数据; 这些都要求我们可以在代码逻辑中获取到用户提交的数据,我们通常会使用v-model指令来完成
原文链接:https://blog.csdn.net/weixin_45215308/article/details/121618639
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>开始学习 Vue</title>
<script src="https://unpkg.com/vue@3/dist/vue.global.js"></script>
</head>
<body>
<div id="app">
<h1>你好{
{name}} </h1>
<h2>{
{message}}</h2>
单向数据绑定:<input type ="text" v-bind:value="name">
双向数据绑定:<input type="text" v-model ="name">
<!-- v-model:value简写默认v-model -->
</div>
<!--v-bind 引号里的东西用作js表达式 -->
</body>
<script>
// vue.Vue.config.productionTip = false
//创建Vue实例
const { createApp } = Vue
createApp({
data() {//相当于data:fuction() 不能用=>
return {
message: 'Hello Vue!',
name:"jzy",
url :'https://hub.gientech.com/',
school:{
name:'jiangzhengyang'
}
}
}
}).mount('#app')
// 相当于_el 挂载 const x = vue{} x.mount(#app)
</script>
双向绑定的数据改变后
11.1
4.4 事件处理(v-on指令)
vue事件处理是每个 Vue 项目的必要方面。它用于捕获用户输入,共享数据以及许多其他创造性方式。
- 使用v-on:xxx或@xxx绑定事件,其中xxx是事件名 <button v-on:click="showInfo">点我提示信息</button> <button @click="showInfo2($event,66)">点我提示信息2</button>
- 事件的回调需要配置在methods对象中,最终会在vm上
- methods中配置的函数,==不要用箭头函数!==否则this就不是vm了
- methods中配置的函数,都是被Vue所管理的函数,this的指向是vm或组件实例对象
- @click="demo和@click="demo($event)"效果一致,但后者可以传参
-
Vue中的事件修饰符:
prevent:阻止默认事件(常用)
stop:阻止事件冒泡(常用)
once:事件只触发一次(常用)
capture:使用事件的捕获模式
self:只有event.target是当前操作的元素时才触发事件
passive:事件的默认行为立即执行,无需等待事件回调执行完毕
修饰符可以连续写,如:@click.prevent.stop="showInfo"
4.5 监视属性
监视属性watch:
- 监视属性:
watch
对象中的属性,该属性名表示data
或者computed
对象中的同名属性被监视了 - 监视有两种写法:
- 创建Vue时传入watch配置
- 通过
vm.$watch
监视
isHot: {
immediate: true,
// 初始化时handler调用
handler(newValue, oldValue) {
console.log("isHot被修改", newValue, oldValue);
},
},
vm.$watch("isHot", {
immediate: true,
// 初始化时handler回调函数自动调用
handler(newValue, oldValue) {
console.log("isHot被修改", newValue, oldValue);
},
});
- 当被监视的属性变化时,回调函数自动调用,进行相关操作
- 监视的属性必须存在,才能进行监视
-
初始化时handler回调函数自动调用,当监视属性中只需要配置
handler
函数时可简写
简写:(以上两个例子简写方法)
isHot(newValue, oldValue) {
console.log("isHot被修改", newValue, oldValue);
},
vm.$watch('isHot',function(newValue,oldValue){
console.log("isHot被修改", newValue, oldValue);
})
完整例子:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>天气案例</title>
<!-- <script src="https://unpkg.com/vue@3/dist/vue.global.js"></script> -->
<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
</head>
<style>
* {
margin: top 20px;
}
</style>
<!-- v-model页面上的输入影响数据的输入 -->
<body>
<div id="root">
<!-- <h2>今天天气{
{isHot ? '炎热':'凉爽'}}</h2> -->
<h2>今天天气{
{isHot ? '炎热':'凉爽'}}</h2>
<button @click="changeWeather">切换天气</button>
<button @click="isHot = !isHot">切换天气</button>
<!-- 绑定事件的时候可以写一些简单的语句 -->
</div>
</body>
<script type="text/javascript">
Vue.config.productionTip = false;
const vm = new Vue({
el: "#root",
data: {
isHot: true,
},
//methods不做数据代理数据劫持
computed: {
// fullName:function()
info() {
return this.isHot ? "炎热" : "凉爽";
},
},
methods: {
changeWeather() {
this.isHot = !this.isHot;
},
},
watch: {
// 正常写法
// isHot: {
// immediate: true,
// // 初始化时handler调用
// handler(newValue, oldValue) {
// console.log("isHot被修改", newValue, oldValue);
// },
// },
// 简写 函数---监视的是谁 函数用作handler
// isHot(newValue, oldValue) {
// console.log("isHot被修改", newValue, oldValue);
// },
},
});
//正常写法
// vm.$watch("isHot", {
// immediate: true,
// // 初始化时handler回调函数自动调用
// handler(newValue, oldValue) {
// console.log("isHot被修改", newValue, oldValue);
// },
// });
vm.$watch('isHot',function(newValue,oldValue){
console.log("isHot被修改", newValue, oldValue);
})
</script>
</html>
4.6 计算属性
- 写在computed对象中的属性,本质上是一个方法,不过使用时依旧当属性来使用
- 计算属性是基于缓存实现的,只在计算属性所依赖的数据发生改变时它们才会重新求值,否则访问 计算属性会立即返回之前的计算结果,而不必再次执行函数。 相比之下,每当触发重新渲染时,调用方法将总会再次执行函数。
语法:
computed: {
"计算属性名" () {
return "值"
}
}
案例,通过计算属性实现:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>姓名案例,计算属性实现</title>
<!-- <script src="https://unpkg.com/vue@3/dist/vue.global.js"></script> -->
<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
</head>
<style>
* {
margin: top 20px;
}
</style>
<!-- v-model页面上的输入影响数据的输入 -->
<body>
<div id="root">
姓:<input type="text" v-model:value="firstname" /><br />
名:<input type="text" v-model="lastname" /><br />
全名:<span>{
{firstname + '-' +lastname}}</span><br />
全名:<span>{
{firstname.slice(0,3)}}-{
{lastname}}</span><br />
全名:<span>{
{fullName}}</span><br />
</div>
</body>
<script type="text/javascript">
Vue.config.productionTip = false;
const vm = new Vue({
el: "#root",
data: {
firstname: "张",
lastname: "三",
// 存在vm自身_data
},
//methods不做数据代理数据劫持
computed: {
// 放入vm之后从对象自动调用get()拿到返回值
fullName: {
// fullname在vm里,不在_data
// get()is not a function
get() {
// this指向vm
console.log("get调用");
return this.firstname + "-" + this.lastname;
},
set(value) {
console.log("set调用");
const arr = value.split('-')
this.firstname = arr[0]
this.lastname = arr[1]
}
},
// 缓存存储了fullName 第一个以后都读取缓存
// 而methods不缓存
// get何时调用
// 1 初次读取fullName的时候
// 2 所依赖的数据变化时
},
//只要有人读取fullName了,get就会被调用,且返回值就为fullName的值
});
</script>
</html>
计算属性配置项
- get():必须要写,该函数不接受参数
- get()什么时候被调用?:当初次读取计算属性或者计算属性所依赖的数据发生变化时被调用,getter函数有一个返回值,该返回值就是计算属性的值
- set():可选项,接受一个可选参数(计算属性被修改之后的值)
- set()什么时候被调用?: 当计算属性被修改时被调用
-
get()和 set()中出现的this执向vm
计算属性简写:
以上述例子的简写(只需要get()时才可简写)
// fullName:function()
fullName() {
console.log("get调用");
return this.firstname + "-" + this.lastname;
},
4.7 计算属性vs监听属性
- computed能完成的功能,watch都可以完成.
- watch能完成的功能,computed不一定能完成.例如:watch可以进行异步操作
姓名案例监听属性使用异步任务的例子
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>姓名案例,watch实现</title>
<!-- <script src="https://unpkg.com/vue@3/dist/vue.global.js"></script> -->
<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
</head>
<style>
* {
margin: top 20px;
}
</style>
<!-- v-model页面上的输入影响数据的输入 -->
<body>
<div id="root">
姓:<input type="text" v-model:value="firstname" /><br />
名:<input type="text" v-model="lastname" /><br />
全名:<span>{
{fullName}}</span><br />
</div>
</body>
<script>
Vue.config.productionTip = false;
const vm = new Vue({
el: "#root",
data: {
firstname: "张",
lastname: "三",
// 存在vm自身_data
fullName: "张-三",
},
watch: {
firstname(newValue) {
// 他不是Vue管理的函数
setTimeout(() => {
this.fullName = newValue + "-" + this.lastname;
}, 1000);
},
// 计算属性vs监听属性
// 监听非常容易开启异步任务
//(不被vue所管理的,定时器回调函数,ajax回调函数,promise回调函数)最好写成箭头函数,这样this的指向才是vm或组件实例对象
lastname(newValue) {
setTimeout(() => {
this.fullName = this.firstname + "-" + newValue;
}, 1000);
},
},
});
</script>
</html>
4.8 绑定样式
class样式:
- 写法:class="xxx",xxx可以是字符串、对象、数组
- 字符串写法适用于:类名不确定,要动态获取
- 对象写法适用于:要绑定多个样式,个数不确定,名字也不确定
- 数组写法适用于:要绑定多个样式,个数确定,名字也确定,但不确定用不用
style样式:
- :style="{fontSize: xxx}"其中xxx是动态值
- :style="[a,b]"其中a、b是样式对象
4.9 条件渲染(v-if v-show)
v-if:
- 写法:
- v-if="表达式"
- v-else-if="表达式"
- v-else
- 适用于:切换频率较低的场景
- 特点:不展示的DOM元素直接被移除
注意:v-if可以和v-else-if、v-else一起使用,但要求结构不能被打断
v-show:
- 写法:v-show="表达式"
- 适用于:切换频率较高的场景
- 特点:不展示的DOM元素未被移除,仅仅是使用样式隐藏掉
使用v-if的时,元素可能无法获取到,而使用v-show一定可以获取
4.10 列表渲染(v-for)
v-for
指令:
- 用于展示列表数据
- 语法:
<li v-for="(item, index) in xxx" :key="yyy">
,其中key可以是index,也可以是遍历对象的唯一标识 - 可遍历:数组、对象、字符串(用的少)、指定次数(用的少)
4.11 数据监测
Vue监视数据的原理:
1.vue会监视data中所有层次的数据
2.如何监测对象中的数据?
- 通过setter实现监视,且要在new Vue时就传入要监测的数据
- 对象中后追加的属性,Vue默认不做响应式处理
- 如需给后添加的属性做响应式,请使用如下API:
- Vue.set(target,propertyName/index,value)
- vm.$set(target,propertyName/index,value)
3.如何监测数组中的数据?
- 通过包裹数组更新元素的方法实现,本质就是做了两件事:
- 调用原生对应的方法对数组进行更新
- 重新解析模板,进而更新页面
4.在Vue修改数组中的某个元素一定要用如下方法:
- 使用这些API:push()、pop()、shift()、unshift()、splice()、sort()、reverse()
- Vue.set() 或 vm.$set()
特别注意:Vue.set() 和 vm.$set() 不能给vm 或 vm的根数据对象(data等) 添加属性
例子:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>Vue数据监视</title>
<style>
button {
margin-top: 10px;
}
</style>
<!-- <script src="https://unpkg.com/vue@3/dist/vue.global.js"></script> -->
<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
</head>
<body>
<div id="root">
<h1>学生信息</h1>
<button @click="student.age++">年龄+1岁</button><br />
<button @click="addSex">添加性别属性,默认值:男</button> <br />
<button @click="addFriend">在列表首位添加一个朋友</button> <br />
<button @click="updateFirstFriendName">
修改第一个朋友的名字为:张三</button
><br />
<button @click="addHobby">添加一个爱好</button> <br />
<button @click="updateHobby">修改第一个爱好为:开车</button><br />
<button @click="removeSmoke">过滤掉爱好中的抽烟</button> <br />
<h3>姓名:{
{student.name}}</h3>
<h3>年龄:{
{student.age}}</h3>
<h3 v-if="student.sex">性别:{
{student.sex}}</h3>
<h3>爱好:</h3>
<ul>
<li v-for="(h,index) in student.hobby" :key="index">{
{h}}</li>
</ul>
<h3>朋友们:</h3>
<ul>
<li v-for="(f,index) in student.friends" :key="index">
{
{f.name}}--{
{f.age}}
</li>
</ul>
</div>
</body>
<script type="text/javascript">
Vue.config.productionTip = false; //阻止 vue 在启动时生成生产提示。
const vm = new Vue({
el: "#root",
data: {
student: {
name: "tom",
age: 18,
hobby: ["抽烟", "喝酒", "烫头"],
friends: [
{ name: "jerry", age: 35 },
{ name: "tony", age: 36 },
],
},
},
methods: {
addSex() {
//Vue.set(this.student,'sex','男')
this.$set(this.student, "sex", "男");
},
addFriend() {
this.student.friends.unshift({ name: "jack", age: 70 });
},
updateFirstFriendName() {
this.student.friends[0].name = "张三";
},
addHobby() {
this.student.hobby.push("学习");
},
updateHobby() {
this.student.hobby.splice(0, 1, "开车");
},
removeSmoke() {
this.student.hobby = this.student.hobby.filter((h) => {
return h !== "抽烟";
});
},
},
});
</script>
</html>
4.12 收集表单数据
- 若:<input type="text"/>,则v-model收集的是value值,用户输入的内容就是value值
- 若:<input type="radio"/>,则v-model收集的是value值,且要给标签配置value属性
- 若:<input type="checkbox"/>
- 没有配置value属性,那么收集的是checked属性(勾选 or 未勾选,是布尔值)
- 配置了value属性
v-model
的初始值是非数组,那么收集的就是checked(勾选 or 未勾选,是布尔值)v-model
的初始值是数组,那么收集的就是value组成的数
v-model
的三个修饰符:
- lazy:失去焦点后再收集数据
- number:输入字符串转为有效的数字
- trim:输入首尾空格过滤
例子:
<html>
<head>
<meta charset="utf-8" />
<title>Vue数据监视</title>
<style>
button {
margin-top: 10px;
}
</style>
<!-- <script src="https://unpkg.com/vue@3/dist/vue.global.js"></script> -->
<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
</head>
<body>
<div id="root">
<form @submit="demo">
<!-- 通过id、for将label input进行关联 -->
<!-- <label for="demo">账号: </label>
<input type="text",id='demo'> -->
<!-- .trim 不收集前后空格 -->
账号:<input type="text" v-model.trim="userInfo.account" /><br /><br />
密码:<input type="password" v-model="userInfo.password" /><br /><br />
年龄:<input type="number" v-model.number="userInfo.age" /><br /><br />
性别:
<!-- radio需要自己配value值 -->
男<input type="radio" name="sex" v-model="userInfo.sex" value="male" />
女<input
type="radio"
name="sex"
v-model="userInfo.sex"
value="female"
/><br /><br />
爱好:
<!-- checkbox 同上 -->
<!-- hobby初始值影响的v-model传回来的数据 -->
学习<input type="checkbox" v-model="userInfo.hobby" value="study" />
打游戏<input type="checkbox" v-model="userInfo.hobby" value="game" />
吃饭<input
type="checkbox"
v-model="userInfo.hobby"
value="eat"
/><br /><br />
所属校区
<select name="" id="">
<option value="">请选择校区</option>
<option value="beijing">北京</option>
<option value="shanghai">上海</option>
<option value="shenzhen">深圳</option>
<option value="wuhan">武汉</option></select
><br /><br />
其他信息:
<!-- .lazy失去焦点的一瞬间收集数据 -->
<textarea
v-model.lazy="userInfo.other"
name=""
id=""
cols="30"
rows="10"
></textarea
><br /><br />
<input type="checkbox" v-model="userInfo.agree" />阅读并接受<a
href="https://blog.csdn.net/JiangZhengyang7?spm=1001.2101.3001.5343"
>《用户协议》</a
>
<!-- 点击按钮表单提交 -->
<button>提交</button>
</form>
</div>
</body>
<script type="text/javascript">
Vue.config.productionTip = false; //阻止 vue 在启动时生成生产提示。
const vm = new Vue({
el: "#root",
data: {
userInfo: {
account: "",
password: "",
age: 0,
sex: "female",
// 多组勾选框写成[]
hobby: [],
city: "beijing",
other: "",
agree: "",
},
},
methods: {
demo() {
console.log(JSON.stringify(this.userInfo));
alert(1)
},
},
});
</script>
</html>