第一部分:Vue使用及实例
1.认识Vue
Vue是一款轻量级渐进式框架,简单易学、双向数据绑定、组件化开发、数据与结构分离、虚拟DOM、运行速度快。
优势:组件化开发,可以独立开发功能模块和开发公用模块提高复用性和工作效率。
响应式双向数据绑定:vue.js会自动对页面中某些数据的变化做出同步的响应。就是数据驱动页面,页面也可以驱动数据,常用于表单中,用户输入我们就可以在数据模型中拿到数据。
单页面应用程序,使页面局部刷新,不用每次跳转都请求数据和dom.
生态好,开发工具丰富,大量提高效率
2.Vue使用-从创造一个实例开始
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>vue</title>
</head>
<body>
<div id="app">
<div>{{name}}</div>
<!-- 小胡子语法和v-text等价 -->
<div v-text="name"></div>
</div>
<!--1.下载导入Vue.js-->
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
// 2.创建一个Vue的实例对象
const vm = new Vue({
// 3.告诉Vue的实例对象, 将来需要控制界面上的哪个区域,把vue实例挂载到id名为app的dom元素上
el: "#app",
//4. 指定Vue实例对象控制区域的数据,并把数据放入到响应式系统中
data: {
name: "蔡徐坤",
},
});
</script>
</body>
</html>
第二部分:Vue相关指令
1.基础指令
1.1 v-text
和 v-html
以及插值语法
插值的方式: 可以将指定的数据插入到指定的位置,不会解析HTML
<span>我是span</span>
还是会这样显示 v-text 就相当于过去学习的 innerText,默认渲染成文本,不仅不会解析html,还会覆盖原有的内容<p v-text="name">123123131</p>
只会显示在p标签显示name的值 v-html就相当于过去学习的 innerHTML,默认渲染成html,也会覆盖标签中原有的内容.利用v-html可以把数据填充到标签进行解析,然后再插入视图层中显示。
<span v-text="msg"></span>
<!-- 和下面的一样 -->
<span>{{ msg }}</span>
1.2 v-once 指令
不需要表达式的指令,作用是定义它的元素或组件只渲染一次,包括元素或组件的所有子节点。首次渲染后,不在随数据的变化重新渲染,将被视为静态内容。再更改时直接从缓存中获取
用的少
<div id="app">
//原始数据显示蔡徐坤,当前数据显示333
<p v-once>原始数据: {{ name }}</p>
<p>当前数据: {{ name }}</p>
</div>
<script>
let vue = new Vue({
el: "#app",
data: {
name: "蔡徐坤",
},
mounted() {
this.name = 3333;
},
});
</script>
1.3 v-cloak 指令
-
1.
Vue 数据绑定过程
:会先将未绑定数据的界面展示给用户,然后再根据模型中的数据和控制的区域生成绑定数据之后的 HTML 代码,最后再将绑定数据之后的 HTML 渲染到界面上. -
2.正是在最终的 HTML 被生成渲染之前会先显示模板内容,所以如果用户网络比较慢或者网页性能比较差, 那么用户会看到模板内容{{message}}
-
3.利用 v-cloak 配合 [v-cloak]:{display: none}默认先隐藏未渲染的界面等到生成 HTML 渲染之后再重新显示
-
4.v-cloak 指令作用:数据渲染之前隐藏未编译的 Mustache 标签,数据渲染之后自动显示元素;
[v-cloak] {
display: none;
}
<div v-cloak>
{{ message }}
</div>
2.条件渲染V-if和v-show
2.1 v-if、v-else-if、v-else
- 使用v-if一旦条件不成立,dom元素不存在。
- v-if 是“真正”的条件渲染,因为它会确保在切换过程中条件块内的事件监听器和子组件适当地被
销毁和重建
。- v-if 也是惰性的:如果在初始渲染时条件为假,则什么也不做——直到条件第一次变为真时,才会开始渲染条件块。
- v-if、v-else-if、v-else若果同时使用必须紧紧跟随;
- 若果一次判断多个元素,可以在外层加一个template标签上使用条件指令,最终渲染结果不会包含该元素。
- Vue在渲染时,出于效率考虑,会尽可能复用已有元素而非重新渲染,下面这个案例点击切换之后,虽然dom变了,但之前键入的内容保留了,他替换了placeholder的提示内容,说明复用了input元素
- 使用key属性的唯一值就不会被复用了
<div id="app">
<template v-if="this.type==='name'">
<label>用户名:</label>
<input type="text" placeholder="请输入用户名" key="1" />
</template>
<template v-else>
<label>邮箱名:</label>
<input type="text" placeholder="请输入邮箱名" key="2" />
</template>
<button @click="handToggleClick">切换输入类型</button>
</div>
<script>
let vue = new Vue({
el: "#app",
data: {
type: "name",
},
methods: {
handToggleClick() {
this.type = this.type === "name" ? "mail" : "name";
},
},
});
</script>
2.2 v-show
- v-show根据表达式的真假来切换元素的显示与隐藏,不会销毁元素。当表达式为false时,会给元素元素添加
display:none;
属性.- v-show无论条件为真还是假,都会被编译并保留在 DOM 中。
- v-show 不支持
<template>
元素- v-show用于频繁切换组件。 总结:
- 1.v-show和v-if的能够一样都是条件渲染, 取值为true就显示,取值为false就不显示。
- 2.v-if和v-show区别
v-if: 只要取值为false就不会创建元素 v-show: 哪怕取值为false也会创建元素,只是如果取值是false会设置元素的display为none
- 3.v-if和v-show应用场景
如果企业开发中需要频繁切换元素显示隐藏, 那么推荐使用v-show, 否则使用v-if
3.v-bind 给元素的属性绑定数据
在企业开发中想要给"元素"绑定数据, 我们可以使用{{}}, v-text, v-html , 但是如果想给"元素的属性"绑定数据, 就必须使用v-bind, 所以v-bind的作用是专门用于给"元素的属性"动态绑定数据的
3.1.v-bind格式
v-bind:属性名称="绑定的数据"
:属性名称="绑定的数据"
v-bind:src v-bind:href
//赋值的数据可以是任意一个合法的JS表达式
3.2 v-bind 给元素绑定类名
在将 v-bind 用于 class 和 style 时,表达式结果的类型除了字符串之外,还可以是对象或数组。
v-bind绑定的class可以与普通class共存.
默认情况下v-bind会去Model中查找数据,如果想让v-bind去style中查找类名, 那么就必须把类名放到数组中,并用引号将类名括起来。
1.绑定class的对象语法
下面的语法表示 bgc
这个 class 存在与否将取决于数据 属性 isActive 的 值是true还是false。
//类名绑定:
<div id="app"
class='static'
:class="{
bgc:isActive,
fz:true}">1233131</div>
//数据控制
data: {
isActive: true,
},
//当然,条件复杂时也可以使用computed属性
2.绑定class的数组语法
<div id="app" :class="['bgc',abc,isActive?'bb':'']">1233131</div>
/*
bgc,bb不是动态的,直接去样式里面找
abc是动态的,根据abc去data里面找abc,然后找到fz
*/
<script>
let vue = new Vue({
el: "#app",
data: {
abc: "fz",
isActive: true,
},
});
</script>
3.绑定class的字符串语法
<div id="app" :class="classX">1233131</div>
<script>
let vue = new Vue({
el: "#app",
data: {
classX: {
bgc: true,
fz: true,
bb: true,
},
},
});
</script>
3.3 v-bind 给元素绑定样式
如果属性名称包含-, 那么必须用引号括起来
<div id="app" :style="[styles,{color:color,'font-size':fontSize+'px'}]">
1233131
</div>
<script>
let vue = new Vue({
el: "#app",
data: {
color: "red",
fontSize: "100",
styles: {
backgroundColor: "blue",
},
},
});
3.4 使用窍门
- 类名确定,但是不确定是由还是没有,用对象类型,值为true和false来控制
- 有的类不需要控制,有的类需要通过true和false来控制,外层用数组,控制项用对象
4.绑定方法v-on
4.1 v-on语法
- 1.v-on指令专门用于给元素绑定监听事件; v-on绑定的事件被触发之后, 会去Vue实例对象的methods中查找对应的回调函数。
- 2.v-on指令格式:
v-on:事件名称="回调函数名称" @事件名称="回调函数名称"
- 3.可以给绑定的回调函数传递参数,如果需要传参,就将最后一个作为事件对象参数
$event
- 4.如果在绑定的函数中需要用到data中的数据必须加上this,直接绑定函数名会默认事件对象作为第一个实参
<body>
<div id="app">
<button @click="myFn('蔡徐坤', 22, $event)">我是按钮</button>
</div>
<script>
let vue = new Vue({
el: "#app",
data: {
gender: "man",
},
methods: {
myFn(name, age, e) {
console.log(this.gender, name, age, e); //man 蔡徐坤 22 MouseEvent对象
},
},
});
</script>
</body>
4.2 v-on事件修饰符
在Vue中通过v-on修饰符来处理例如事件冒泡,事件捕获, 阻止默认行为等
.once - 只触发一次回调
默认情况下事件的回调函数可以反复的执行, 只要事件被触发就会执行,如果想让事件监听的回调函数只执行一次, 那么就可以使用.once修饰符
<button @click.once="myFn('蔡徐坤', 22, $event)">我是按钮</button>
.prevent - 调用 event.preventDefault()。
如果想阻止元素的默认行为, 那么可以使用.prevent修饰符
.stop - 调用 event.stopPropagation()。
- 默认情况下载嵌套的元素中, 如果都监听了相同的事件, 那么会触发事件冒泡,如果想阻止事件冒泡, 那么可以使用.stop修饰符.
- 把.stop修饰符写在谁身上,就不会再往他的上级元素上传递
- 若果写在爸爸身上,触发儿子,儿子会传给爸爸,但爸爸不会传给爷爷
.self
- 如果想让回调只有当前元素触发事件的时候才执行, 那么就可以使用.self修饰符
- 如果不是从当前元素触发,被绑定了
.self
修饰符的元素就不会参与到冒泡阶段和捕获- 阻止当前元素参与捕获和冒泡,不影响父级元素。
.capture - 添加事件侦听器时使用 capture 模式。
- 默认情况下是事件冒泡, 如果想变成事件捕获, 那么就需要使用.capture修饰符。
- 触发过程是给谁绑定了
.capture
修饰符,点击子元素后就先触发有修饰符的,然后再触发触发事件源事件,最后触发它们之间的,从父元素到子元素。
.passive
当我们在监听元素滚动事件的时候,会一直触发onscroll事件,在pc端是没啥问题的,但是在移动端,会让我们的网页变卡,因此我们使用这个修饰符的时候,相当于给onscroll事件整了一个.lazy修饰符。
<div v-on:scroll.passive="onScroll">...</div>
.native
- 在组件里面绑定一些事件,必须使用.native来修饰,否则是不会触发的。
- 修饰符的作用就是把一个vue组件转化为一个普通的HTML标签,使用.native修饰符来操作普通HTML标签是会令事件失效的
<My-component @click.native="shout(3)"></My-component>
4.3其它修饰符
keyup.enter关键字修饰符
//<!-- 只有在 `key` 是 `Enter`或者对应键码 时调用 `vm.submit()` -->
<input v-on:keyup.enter="submit">
<input type="text" @keyup.keyCode="submit">//废弃
第三部分:Vue列表渲染
1.v-for
v-for指令用于基于数据源来渲染项目列表。该指令可以在模板块或者元素上使用。
v-for 指令需要使用 item in items 形式的特殊语法,其中 items 是源数据数组,而 item 则是被迭代的数组元素的别名。 一般都是给数组或对象指定别名,除此之外还可以为索引值指定别名,对于对象还可以给value指定别名,常见的几种情形如下:
<div v-for="item in items">{{ item }}</div>
<div v-for="(item, index) in items">{{ item }} {{ index }}</div>
<div v-for="val in object"></div>
<div v-for="(val, key) in object"></div>
<div v-for="(val, key, index) in object"></div>
2.key关键词
在使用v-for指令渲染列表,为每个迭代的元素指定一个key属性是很常见的做法。这是因为Vue使用key属性为每个遍历的元素创建唯一标识符,防止就地复用(即如果数据项的顺序被改变,Vue将不会移动DOM元素来匹配数据项的顺序,而是就地更新每个元素)。
解释一下。如果我们的列表中有任何动态的UI更改(比如列表项的顺序被打乱),Vue将选择在每个元素中更改数据,而不是相应的移动DOM元素。这在大多数情况下都不是问题。然而,在某种情况下,v-for渲染出来的列表项依赖于DOM状态和(或)子组件状态,这可能会导致一些非预期的渲染效果。
比如:如果渲染模板中包含了一个允许用户直接输入消息的字段,若果打乱顺序,文本会出现意外的匹配。
3.v-model
- 1.v-model指令用于表单控件元素上(
<input>、<textarea> 及 <select>
)创建双向数据绑定。它会根据控制类型自动选取正确的方法来更新元素。- 2.v-model本质上是input事件和v-bind的语法糖。
<div id="app">
<!-- <input type="text" v-model="username" /> -->
<!--
下面这个输入框是模拟双向绑定:利用v-bind和input事件;
v-bind事件单向数据绑定,数据变化驱动视图变化
input事件监听输入框的变化,并赋值给数据(视图变化驱动数据变化)
-->
<input type="text" :value="username" @input="handle" />
</div>
<script>
let vm = new Vue({
el: "#app",
data() {
return {
username: "",
};
},
methods: {
handle(event) {
this.username = event.target.value;
},
},
});
</script>
3.1 v-model绑定文本框
<!-- 单行文本 -->
<input type="text" v-model="username" />
<!-- 多行文本 -->
<textarea v-model="username" placeholder="请输入多行文本"></textarea>
3.2 v-model绑定复选框
- 1.单个复选框,绑定布尔值(选中与否切换布尔值)
- 2.多个复选框,多个复选框,绑定到同一个数组:选中则把value数据添加到双向绑定的数组
<div id="app">
<p> -------------------checkBox单选框-------------------- </p>
<div class="two">
<label for="agree">
<input type="checkbox" id="agree" v-model="isAgree" />同意协议
</label>
<p>你的选择是:{{isAgree}}</p>
<button :disabled="!isAgree">下一步:注册邮箱</button>
</div>
<p>-------------------checkBox多选框----------------------</p>
<div class="three">
<label for="">
<input type="checkbox" checked value="篮球" v-model="hobbies" />basketball
</label>
<label for="">
<input type="checkbox" value="足球" v-model="hobbies" />football
</label>
<label for="">
<input type="checkbox" value="羽毛球" v-model="hobbies"/>yuMaoball
</label>
<label for="">
<input type="checkbox" value="兵乓球" v-model="hobbies" />PingPang
</label>
<p>你的爱好是:{{hobbies}}</p>
</div>
</div>
<script>
let vm = new Vue({
el: "#app",
data() {
return {
// checkbox单选框
isAgree: false,
// checkbox复选框
hobbies: [],
};
},
});
</script>
3.3 v-model绑定单选按钮
- 选中哪个,就把他的value值赋值给双向数据
<div id="app">
<!-- v-model之radio -->
<div class="one">
<label for="male">
<input type="radio" id="male" name="sex" value="男" v-model="sex" />男
</label>
<label for="female">
<input type="radio" name="sex" value="女" v-model="sex" />女
</label>
<p>你选择的性别是:{{sex}}</p>
</div>
</div>
<script>
let vm = new Vue({
el: "#app",
data() {
return {
// radio
sex: "男",
};
},
});
3.4 v-model绑定选则框
<div id="app">
<p>----------------------select选框单选时-----------------------</p>
<div class="four">
<select name="abc" id="" v-model="city">
<option value="北京">北京</option>
<option value="上海">上海</option>
<option value="深圳">深圳</option>
<option value="广州">广州</option>
<option value="武汉">武汉</option>
</select>
<p>你选择的城市是:{{city}}</p>
</div>
<p>---------------select选框多选时-----------------------</p>
<div class="five">
<select name="abcd" id="" v-model="citys" multiple>
<option value="北京">北京</option>
<option value="上海">上海</option>
<option value="深圳">深圳</option>
<option value="广州">广州</option>
<option value="武汉">武汉</option>
</select>
<p>你选择的城市是:{{citys}}</p>
</div>
</div>
<script>
let vm = new Vue({
el: "#app",
data() {
return {
// select单选
city: " ",
// select多选
citys: [],
};
},
});
</script>
用V-for:
<div id="app">
<p>----------------------select选框单选时-----------------------</p>
<div class="four">
<select v-model="select">
<option v-for="option in options" v-bind:value="option.value">
{{ option.text }}
</option>
</select>
<p>你选择的城市是:{{select}}</p>
</div>
<p>---------------select选框多选时-----------------------</p>
<div class="five">
<select name="abcd" id="" v-model="selects" multiple>
<option v-for="option in options" v-bind:value="option.value">
{{ option.text }}
</option>
</select>
<p>你选择的城市是:{{selects}}</p>
</div>
</div>
<script>
let vm = new Vue({
el: "#app",
data() {
return {
select: "深圳", // select单选
selects: ["北京", "上海"], // select多选
options: [
{ text: "beijing", value: "北京" },
{ text: "shanghai", value: "上海" },
{ text: "shenzhen", value: "深圳" },
{ text: "guangzhou", value: "广州" },
{ text: "wuhan", value: "武汉" },
],
};
},
});
</script>
3.5 表单双向绑定修饰符
v-model.lazy
作用: v-model双向数据绑定的时候, 只要输入框的数据改变,绑定的model数据也会随之改变, 而 lazy修饰符会在光标离开input框才会更新数据.
<input type="text" v-model.lazy="value">
v-model.trim
作用: 输入框过滤首尾的空格
<input type="text" v-model.trim="value">
v-model.number
作用: 先输入数字 就会限制输入只能是数字, 先字符串就相当于没有加上number, 注意, 不是输入框不能输入字符串, 是这个数据是数字.
<input type="text" v-model.number="value">
4.列表渲染综合用法
可以用带有 v-for 的
<template>
标签来渲染多个元素块,循环块区域,不但能省去很dom节点,而且也能解决欠套不合理的情况.
4.1 渲染数组数据
v-for 指令需要以item in items形式的特殊语法, items 是源数据数组并且 item 是数组元素迭代的别名。
应用场景:通常情况下,进入一个活动要展示出所有参加活动的人员,里面有姓名,年龄,报名时间等等,那后台肯定会返回一个arraylist数组集合,集合中每个元素肯定是一个对象,那我们如何去把这个数组集合高效率,合理的渲染到页面上,,再拿到用户id去到下一个页面查询memberDetail祥情?
<template>
<div>
<ul>
<li v-for="(item,index) in memberList" @click="memberDetail(index)">
<span>{{item.custName}}</span>
<span>{{item.age}}</span>
<span>{{item.joinTime}}</span>
</li>
</ul>
</div>
</template>
<script>
export default {
created () {
//就当看作是ajax在初始化进入的时候从后台获取的用户列表数据
this.memberList = [
{custName : "ziksang1",age:20,joinTime : "2019-01-02",custId:1},
{custName : "ziksang2",age:21,joinTime : "2019-01-03",custId:2},
{custName : "ziksang3",age:22,joinTime : "2019-01-04",custId:3},
{custName : "ziksang4",age:23,joinTime : "2019-01-05",custId:4},
]
},
data () {
return {
memberList : []
}
},
methods : {
memberDetail (index) {
sessionStorage.custId = this.memberList[index].custId
}
}
}
</script>
分析
- 1.如果在template模板里面用到了数据必须先在data选项里先声明赋值,我们先给memberList给予一个[]数组.
- 2.在created函数里我们就当作模拟从后台拿到的数据,然后赋值给data选项里的memberList,此时memberList就有后台拿到的值了.
- 3.(item,index) in memberList 是vue自己封装的一个语法结构
item代表集合中的每一个元素,此时每一个元素就是一个对象
index代表集合每一个元素的下标
memberList是所要循环的数组
- 4.为什么我们要把 (item,index) in memberList放在每一个循环dom上,那就是li标签 只有在li循环体节点上和循环体所有子节点上拿到item这个对象里面的所有属性.
- 5.@click="memberDetail(index)" 这里用了一个点击方法,我们把index作为了方法的参数,目 的是什么,这个index代表每一个循环出来dom的下标,通过点击,我们可以拿到对应的用户id可 以说拿到每一个用户的任意值,然后在methods我们进行操作,我们可以能过sessonStorage来存 放,用来过度到下一个用户祥情页,来获取所有用户详情,我们可以打开谷歌浏览器,当我们用 鼠标点击的时候,可以发现sessionStorage里的变化 整个流程是无论是开发任意中型项目必备的
4.2 v-for Object 对象渲染
- 你也可以用 v-for 通过一个对象的属性来迭代。
(value,key,index) in memberDetail
value 代表属性值 key 代表属性, index代表每个dom节点的下标索引 两者都是一一对应的,通过第一个例子讲解,我相信这个例子很简单了- 应用场景 :展示一个用户详情,如果后端都给你排好序了,如何正确的方便展示出来,用最快,最便捷的方法那就是v-for 迭代对象,一般情况下展示一个用户详情,后台肯定返回一个用户对象给你.
<template>
<table>
<template>
<tr>
<td v-for="(value,key,index) in memberDetail">{{key}}</td>
</tr>
<tr>
<td v-for="(value,key,index) in memberDetail">{{value}}</td>
</tr>
</template>
</table>
</template>
<script>
export default {
created () {
//比方说我们这里拿到前面的custId传给后台拿到用户数据
this.memberDetail = {
name : 'ziksang',
age : 20,
address : "xxx省xxxx市",
tel : "15921898427"
}
},
data () {
return {
memberDetail : {}
}
}
}
</script>
<style>
body,html{
width:100%;
height:100%
}
.divider{
width:100%;
height:1px;
background:black;
}
</style>
5.数组跟新检测
Vue重写了很多数组原型方法,利用这些方法操作数组数据可以触发视图变化:
- 1.push()
- 2.pop()
- 3.shift()
- 4.unshift()
- 5.splice()
- 6.sort()
- 7.reverse()
以上这些方法是:先改变data选项artList数组,然后同步跟新视图,这些方法就是
变异方法
此外,还有一些非变异方法
,就是不能通过Array.prototype里的原形方法改变data选项artList数组来触发触发视图改变,因为操作数据后只是返回了一个新数组,所以而不会触发视图更新。
1.filter(), 2.concat(), 3.slice(), 4.map() 只要把形成的返回值再从新赋值给data选项里的数组就可以了.
- 显示过滤/排序后的结果 有时,我们想要显示一个数组经过过滤或排序后的版本,而不实际变更或重置原始数据。在这种情况下,可以创建一个计算属性,来返回过滤或排序后的数组。
第四部分:计算属性和侦听器
使用原则:computed能做的,watch都能做,反之则不行,能用computed的尽量用computed
1.计算属性computed
- 若果模板内的表达式过长或者逻辑太复杂,就可以用到计算属性,它通过逻辑计算给我们返回一个结果。
- computed中的计算属性不能在data中声明过,每一个计算属性都有get/set方法,分别用来获取计算属性和设置计算属性。默认只有get,如果需要set,要自己添加。另外set设置属性,并不是直接修改计算属性,而是修改它的依赖。
- 计算属性 本质上是一个函数 实现某种功能或者得到某个结果 ;使用的时候当作数据属性一样用 。
- 计算属性有依赖属性,他们发生变化时,计算属性也会发生变化; 若没有变化直接从缓存中获取之前的值,不会重新渲染,大大提高性能。
<div id="app">
<div>{{fullName}}</div>
<div>{{name}}</div>
</div>
<script>
var vue = new Vue({
el: "#app",
data: { firstName: "蔡", lastName: "徐坤" },
computed: {
/*
firstName/lastName是依赖属性,他们发生变化时,计算属性name,fullName也会发生变化;
若没有变化直接从缓存中获取之前的值,不会重新渲染,大大提高性能
*/
//写法一:函数写法
name() {
//相当于get方法获值,先会自动调用get方法,后面依赖值发生改变调用get方法
return this.firstName + this.lastName;
},
//写法二:对象写法
fullName: {
get() {
//相当于get方法获值,先会自动调用get方法,后面依赖值发生改变调用get方法
return this.firstName + this.lastName;
},
set(val) {
//对计算属性设置值的时候调用,并把设置的值保存到val中
},
},
},
});
</script>
双向数据监听就是用对象模式:
<div id="demo">
姓:
<input type="text" placeholder="First Name" v-model="firstName" /><br />
名: <input type="text" placeholder="Last Name" v-model="lastName" /><br />
姓名1(单向):
<input type="text" placeholder="Full Name1" v-model="fullName1" /><br />
姓名2(双向):
<input type="text" placeholder="Full Name2" v-model="fullName2" /><br />
</div>
<!--当分别修改姓、名时,姓名会发生变化;但是姓名修改的时候,姓、名不会发生变化-->
<script>
let vm = new Vue({
el: "#demo",
data: {
firstName: "蔡",
lastName: "徐坤",
},
computed: {
fullName1() {
console.log("get");
return this.firstName + "-" + this.lastName;
//当分别修改姓、名时,姓名会发生变化;但是姓名修改的时候,姓、名不会发生变化
},
fullName2: {
//当分别修改姓、名时,姓名会发生变化;
get() {
return this.firstName + "-" + this.lastName;
},
//但是姓名修改的时候,姓、名发生变化
set(value) {
console.log(value); //fullName2
const names = value.split("-");
this.firstName = names[0];
this.lastName = names[1];
},
},
},
});
</script>
2.侦听器watch
- 1.Watch 属性是专门用于监听数据变化的, 只要数据发生了变化, 就会自动调用对应数据的回调方法,监听的属性必须在data中声明过。
- 2.Watch 监听路由变化,在企业开发中我们可以通过 Watch 来判断当前界面是从哪个界面跳转过来的。场景:组件创建的时候我们获取一次列表的数据,同时监听input框,每当发生变化的时候重新获取一次筛选后的列表。
- 3.watch里面可以进行异步操作。
- 4.函数里面参数第一个是新参数,第二个是旧参数
- 5.使用 watch 来监听数据变化的时候除了常用到 handler 回调,其实其还有两个参数,便是:
deep 设置为 true 用于监听对象内部值的变化
immediate 设置为 true 将立即以表达式的当前值触发回调
<div id="app">{{fullName}}</div>
<script>
var vue = new Vue({
el: "#app",
data: { firstName: "Foo", lastName: "Bar", fullName: " " },
watch: {
//watch里面回调函数第一种写法:写成函数
firstName(newValue, oldValue) {
console.log(111); //首次执行
this.fullName = newValue + " " + this.lastName;
},
//watch里面回调函数第二种写法:写成对象
lastName: {
//只有当监视属性发生改变时handler函数才执行
handler(newValue, oldValue) {
console.log(222); //首次执行
this.fullName = newValue + " " + this.firstName;
console.log("1111");
},
immediate: true, //让handler一进来就执行
deep: true, //深层次监控
},
},
});
</script>
<div id="demo">
姓:
<input type="text" placeholder="First Name" v-model="firstName" /><br />
名: <input type="text" placeholder="Last Name" v-model="lastName" /><br />
姓名1(单向):
<input type="text" placeholder="Full Name1" v-model="fullName" /><br />
</div>
<!--当分别修改姓、名时,姓名会发生变化;但是姓名修改的时候,姓、名不会发生变化-->
<script>
let vm = new Vue({
el: "#demo",
data: {
firstName: "蔡",
lastName: "徐坤",
fullName: "蔡-徐坤",
},
watch: {
firstName: function (value) {
console.log("first变化了", value);
this.fullName = value + "-" + this.lastName;
},
lastName() {},
},
});
vm.$watch("lastName", function (value) {
console.log("lastname变化了", value);
this.fullName = this.firstName + "-" + value;
});
第五部分:生命周期
1.1 什么是生命周期?
Vue实例从创建到销毁的过程称之为生命周期,一般包括:
开始创建 -> 初始化数据 -> 编译模板 -> 挂载DOM-渲染 -> 更新-渲染 -> 销毁等一系列过程
通俗而言:
生命周期分为8个过程:创建前,创建后,挂载前,挂载后,更新前,更新后,销毁前,销毁后。 每个Vue生命周期阶段,都会有生命周期钩子函数,告诉你在当前阶段做一些事情。 我们最主要讲的是 vue 的生命周期,先来一份大纲: 1.创建期间的生命周期方法:
- beforeCreate(初始化界面前)
- created(初始化界面后)
- beforeMount(渲染dom前)
- mounted(渲染dom后) 2.运行期间的生命周期方法:
- beforeUpdate(更新数据前)
- updated(更新数据后) 3.销毁期间的生命周期方法:
- beforeDestroy(卸载组件前)
- destroyed(卸载组件后)
1.2 创建期间的生命周期方法
- 在创建 vue 实例过程中可以添加生命周期方法。这些方法系统会在特定的阶段自动调用:
- 记住,这个阶段最主要是进行vue实例的
创建
和挂载
.- created钩子函数可以起效标志着vue实例已经创建完成,在此我们可以获取数据(ajax)、获取计算属性和监听属性
- mounted表示挂载完成,模板中的HTML渲染到HTML页面中,此时一般可以做一些ajax操作,mounted只会执行一次。
let vue = new Vue({
beforeCreate: function () {
/*
1. 在调用beforeCreate的时候, 仅仅表示Vue实例刚刚被创建出来,此时此刻还没有初始化好
Vue实例中的数据和方法, 所以此时此刻还不能访问Vue实例中保存的数据和方法
*/
},
created: function () {
/*
2.在调用created的时候, 表示实例已经创建完成,这是我们最早能够访问Vue实例中保存的数据和方法的地方。
*/
console.log("data数据和methods方法初始化好了", this.msg, this.say);//蔡徐坤 say()
console.log("el未与#app关联", this.$el); //undefined
},
beforeMount: function () {
/*
3.在调用beforeMount的时候, 表示Vue已经编译好了最终模板, 但是还没有将最终的模板渲染
到界面上。
vue实例的$el初始化了,但还是挂载之前为虚拟的dom节点,data.message还未替换。
*/
console.log("el未编译", this.$el); //<div id='app'>...</div>
console.log(document.querySelector("p").innerHTML);//{{msg}}
console.log(document.querySelector("p").innerText);//{{msg}}
},
mounted: function () {
/*
在调用mounted的时候, 表示Vue已经完成了模板的渲染, 表示我们已经可以拿到界面上渲染之后的内容了
vue实例挂载完成,data.message成功渲染。
*/
console.log(document.querySelector("p").innerHTML);//蔡徐坤
console.log(document.querySelector("p").innerText);//蔡徐坤
},
el: "#app",
data: {
msg: "蔡徐坤",
},
methods: {
say() {
console.log("say");
},
},
});
图解创建阶段
1.3 运行期间的生命周期方法
- 当data变化时,会触发beforeUpdate
- 数据驱动界面变化时,会触发updated方法
let vue = new Vue({
beforeUpdate: function () {
/*
在调用beforeUpdate的时候, 表示Vue实例中保存的数据被修改了;
只有保存的数据被修改了才会调用beforeUpdate, 否则不会调用;
在调用beforeUpdate的时候, 数据已经更新了, 但是界面还没有更新;
*/
},
updated: function () {
/*
在调用updated的时候, 表示Vue实例中保存的数据被修改了, 并且界面也同步了修改的数据了,也就是说: 数据和界面都同步更新之后就会调用updated
*/
},
});
1.4 销毁期间的生命周期方法
beforeDestroy: function(){
/*
在调用beforeDestroy的时候, 表示当前组件即将被销毁了
注意点: 1.只要组件不被销毁, 那么beforeDestroy就不会调用
2.beforeDestroy函数是我们最后能够访问到组件数据和方法的函数
一般在这一步做一些重置的操作,比如清除掉组件中的定时器 和 监听的dom事件
*/
},
destroyed: function(){
/*
调用destroyed的时候, 表示当前组件已经被销毁了
注意点: 只要组件不被销毁, 那么destroyed就不会调用
不要在这个生命周期方法中再去操作组件中数据和方法
*/
console.log("destroyed");
}
1.5 组件的生命周期
-
1.Vue 实例对象可以看做是一个大的组件, 我们自定义的组件可以看做是一个小的组件
-
2.那么大的组件中可以使用的属性和方法, 在小的组件中也可以使用
-
3.例如: 在 Vue 实例中我们可以添加 data, methods, 那么在自定义的组件中也可以添加 data, methods,所以 Vue 实例中可以使用生命周期方法, 组件中也可以使用生命周期方法