Vue2(六):生命周期、组件、组件的嵌套、VueComponent构造函数、单文件组件

一、生命周期

1.什么是生命周期?

生命周期
1.又名:生命周期回调函数、生命周期函数、生命周期钩子。
2.是什么:Vue在关键时刻帮我们调用的一些特殊名称的函数。
3.生命周期函数的名字不可更改,但函数的具体内容是程序员根据需求编写的。
4.生命周期函数中的this指向是vm 或 组件实例对象。

2、生命周期中的8个钩子

常用的生命周期钩子
1.mounted: 发送ajax请求、启动定时器、绑定自定义事件、订阅消息等【初始化操作】。
2.beforeDestroy: 清除定时器、解绑自定义事件、取消订阅消息等【收尾工作】。

关于销毁Vue实例
1.销毁后借助Vue开发者工具看不到任何信息。
2.销毁后自定义事件会失效,但原生DOM事件依然有效(现在的版本好像也会失效)。(留个疑点,啥是自定义事件?啥是原生DOM事件?答:自定义事件就是定义在组件标签上的事件,是组件通信的一种方式,原生DOM事件就是类似onclick这种的)。销毁后所有的监视也没了
3.一般不会在beforeDestroy操作数据,因为即便操作数据,也不会再触发更新流程了。

   <!-- 准备一个容器 --><div id="hello"><h1>欢迎来到{{n}}年代</h1><button @click="add">点击n+1</button></div><script>const vm = new Vue({el: '#hello',data: {n: 1},methods: {add() {this.n++;}},beforeCreate() {console.log('beforeCreate');console.log(this);// debugger;},created() {console.log('created');},beforeMount() {console.log('beforeMount');},mounted() {console.log('mounted');},beforeUpdate() {console.log('beforeUpdate');},updated() {console.log('updated');},beforeDestroy() {console.log('beforeDestroy');},destryed() {console.log('destryed');}})</script>

3.图解生命周期 

4.小案例:字体闪烁,点击停止(销毁vm)

<!-- 准备一个容器 -->
<div id="hello"><h1 :style="{opacity: opacity}">欢迎来到90年代</h1><button @click="stop">点击停止闪烁</button>
</div><script>const vm = new Vue({el: '#hello',data: {opacity: 1},methods: {stop() {// clearInterval(this.timer);  vm自杀可以这么写,他杀需要写在beforeDestroy中this.$destroy();  //vm自杀}},//挂载意思就是放在页面上//挂载函数,Vue完成模板的解析并把*初始的(只调用一次)*真实DOM放入页面后(完成挂载)调用mountedmounted() {this.timer = setInterval(() => {console.log('计时器调用');this.opacity -= 0.01;if (this.opacity <= 0) this.opacity = 1;  //js里玩儿小数一般碰不到0 }, 16)},beforeDestroy() {console.log('vm即将被销毁');// 为什么vm的后事需要写在这里,是因为vm很有可能是被别人干掉的clearInterval(this.timer);},})//通过外部的定时器实现(不推荐)// setInterval(() => {//     vm.opacity -= 0.01;//     if (vm.opacity <= 0) vm.opacity = 1;  //js里玩儿小数一般碰不到0// }, 16);
</script>

下面这个不知道为什么点击停止变换之后,在点击透明度变1没有反应? 

    <div id="root"><h2 :style="{opacity}">你好我饿了</h2><button @click="opacity = 1">透明度变1</button><button @click="stop">点击停止变换</button></div>
</body>
<script>const vm = new Vue({el:'#root',data:{opacity:1},methods:{stop(){this.$destroy()}},mounted(){// Vue完成模板的解析并把真实的DoM元素放入页面后(挂载完毕)调用mountedthis.timer = setInterval(() => {this.opacity -= 0.01if(this.opacity <= 0) this.opacity=1},16)},beforeDestory(){clearInterval(this.timer)console.log('vm即将驾鹤西游');},})
</script>

二、使用组件 的三大步骤

1、定义组件(创建组件)
2、注册组件
3、使用组件(写组件标签)

1、如何定义一个组件?

使用Vue.extend(options)创建,其中options和new Vue(options)时传入的那个options几乎一样,但也有点区别;
区别如下:

(1)el不要写,为什么?
最终所有的组件都要经过一个vm的管理,由vm中的el决定服务哪个容器。备注:使用template可以配置组件结构。

(2)data必须写成函数,为什么?
避免组件被复用时,数据存在引用关系,比如我父组件要多次复用一个子组件,那如果其中一个子组件做了修改数据操作,其他复用的地方数据也会被修改。看看下面的代码,就明白了

 //1.data定义为对象,里面的值有人一改,那全都用到底地方都改了let data = { a: 1, b: 2 };let x = data;   //如果x.a = 10 ,那么y也会变成{ a: 10, b: 2 }let y = data;//2.data定义为函数,里面的值有人改,其他用到的地方不变(每次用到都会返回一个全新的)let data1 = function () {return { a1: 1, b1: 2 };}let x1 = data1();  //如果x1.a1=10,那么y1还是{ a1: 1, b1: 2 }let y1 = data1();

2、如何注册组件?

(1)局部注册

靠new Vue的时候传入components选项

   <!-- 准备一个容器 --><div id="root"><xuexiao></xuexiao><hr><xuesheng></xuesheng></div><script>//第一步:创建school组件const school = Vue.extend({name: 'dj', //可以使用name配置项指定组件在开发者工具中呈现的名字(只是开发者工具里用的名字)。// el: '#hello'  el不能写template: `<div><h2>学校名字{{schoolName}}</h2><h2>学校地址{{address}}</h2></div>`,data() {return {schoolName: 'web',address: '杭州',}}})//第一步:创建student组件const student = Vue.extend({template: `<div><h2>学生名字{{studentName}}</h2><h2>学生年龄{{age}}</h2><button @click="add">点击年龄+1</button></div>`,data() {return {studentName: 'zzy',age: 18}},methods: {add() {this.age++;}},})//创建一个vm带领小弟接管root容器const vm = new Vue({el: '#root',// 第二步:注册组件(局部注册)components: {//组件名:组件//这里最好写成school:school,简写为schoolxuexiao: school,//这里最好写成student:student,简写为studentxuesheng: student}})</script>

(2) 全局注册

Vue.component('组件名',组件)

   <!-- 准备一个容器 --><div id="root"><sayhello></sayhello></div><!-- 准备第二个容器 --><div id="root2"><sayhello></sayhello></div><script>//第一步:创建组件const hello = Vue.extend({template: `<div><h2>{{msg}}</h2></div>`,data() {return {msg: 'hello world'}}})//第二步:全局注册组件Vue.component('sayhello', hello);//创建第一个vm接管rootconst vm = new Vue({el: '#root'})//创建第二个vm接管root2new Vue({el: '#root2'})</script>

3、编写组件标签

直接写组件名的标签就欧了,一般我们定义组件时,组件名和定义的名字最好一样,这样就可以简写。(详见2.(1)代码中的注释)

   <!-- 准备一个容器 --><div id="root"><xuexiao></xuexiao><xuesheng></xuesheng></div>

 三、使用组件的一些注意点

1.关于组件名:

一个单词组成:
第一种写法(首字母小写):school
第二种写法(首字母大写):School
多个单词组成:
第一种写法(kebab-case命名):‘my-school’
第二种写法(CamelCase命名):MySchool (需要Vue脚手架支持)
备注:
(1).组件名尽可能回避HTML中已有的元素名称,例如:h2、H2都不行。
(2).可以使用name配置项指定组件在开发者工具中呈现的名字(不影响注册的名字)。

2.关于组件标签:

第一种写法:<school></school>
第二种写法:<school/>
备注:不用使用脚手架时,<school/>会导致后续组件不能渲染。

3.一个简写方式:

const school = Vue.extend(options) 可简写为:const school = options

三、组件的嵌套

(ps:一定要把组件的创建使用练习两遍,不然这里会很乱)

这里要注意,vm里要写el,其他都不写。vm里的template可以不用写根节点,因为vm里的东西是放到容器里的,而组件的template要用根节点包起来(如div)。这块儿就是一直套娃(代码倒着看)

<body><div id="root"><h1>{{msg}}</h1></div>
</body>
<script>// 1、定义sudent组件const student = Vue.extend({template: `<div><h2>学生姓名:{{name}}</h2><h2>学生年龄:{{age}}</h2></div>`,data() {return {name: '蛋糕',age: '18'}}})// 1、定义school组件const school = Vue.extend({template: `<div><h2>学校名称:{{name}}</h2><h2>学校地址:{{address}}</h2><student></student></div>`,data() {return {name: '椰果',address: '郑州'}},// 注册student组件components: {student}})// 1、定义hello组件const hello = Vue.extend({template:`<h1>{{msg}}</h1>`,data(){return {msg:'欢迎来到椰果学习'}}})// 1、定义app组件const app = Vue.extend({template:`<div><school></school><hello></hello></div>`,components: {school,hello}})// 创建vmnew Vue({template:`<app></app>`,el: '#root',// 2、注册school组件(局部)components: {app}})
</script>

四、VueComponent构造函数

school组件是一个Vue.extend生成的构造函数,当组件写到页面上时,Vue开始解析,同时自动搞了个new,这才创建了school组件的实例对象。

1.什么是VueComponent?

1、school组件本质是一个名为VueComponent的构造函数,且不是程序员定义的,是Vue.extend生成的。

2、我们只需要写<school/>或<school></school>,Vue解析时会帮我们创建school组件的实例对象,即Vue帮我们执行的:new VueComponent(options)。

3、特别注意:每次调用Vue.extend,返回的都是一个全新的VueComponent构造函数,而不是返回VueComponent的实例(这个地方不要陷入误区),只有当Vue解析组件时,才会返回所对应组件(如school)的VueComponent的实例对象

2.VueComponent中的this指向

VueComponent的实例对象,以后简称vc(也可称之为:组件实例对象)。Vue的实例对象,以后简称vm。

(1)组件配置中
data函数、methods中的函数、watch中的函数、computed中的函数。它们的this均是【VueComponent实例对象】。
我这么理解,school组件是一个Vue.extend生成的构造函数,然后在这个extend里鱿鱼西还搞了个自动生成new,所以在页面使用组件时(Vue解析组件标签时)就顺便儿创建了school组件的实例对象,所以this指向Vc
(2)new Vue(options)配置中
data函数、methods中的函数、watch中的函数、computed中的函数 它们的this均是【Vue实例对象】。

3.组件实例和Vue实例

其实这俩就像一对儿双胞胎,东西基本上99%都一样,但是这俩人不能划等号,还是有点小小的区别的,比如组件里不能写el,组件里data必须写成函数。vc有的vm都有,但是vm可以用el决定操作谁

4.一个重要的内置关系

这块儿听懂了,但是还差点事儿,这个图可以结合pink老师的图去理解,js高级抽空儿得补补。
1、一个重要的内置关系:VueComponent.prototype.__proto__ === Vue.prototype
2、为什么要有这个关系:让组件实例对象(vc)可以访问到 Vue原型上的属性、方法。

五、单文件组件

5、index.html

<!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>单文件组件</title>
</head>
<body><div id="root"><App></App></div><script src="../js/vue.js"></script><script src="./main.js"></script>
</body>
</html>

4、main.js

import App from './App.vue'new Vue({el: '#root',components: { App }
})

3、App.vue

<template><div><School></School><Student></Student></div>
</template><script>// 引入组件import School from './School'import Student from './Student'export default {name:'App',components:{School,Student}}
</script><style></style>

2、Student.vue

<!-- vetur插件 -->
<template><div><!-- 组件的结构 --><h2>学生姓名:{{ name }}</h2><h2>年龄:{{age }}</h2></div>
</template><script>
// 组件交互相关 的代码(数据、方法等等)
export default {name: 'Student',data() {return {name: '椰果',age: 18}},
}
</script>
<!-- 如果没有样式也可以不写 -->

1、School.vue

<!-- vetur插件 -->
<template><div class="demo"><!-- 组件的结构 --><h2>学校名称:{{ schoolName }}</h2><h2>学校地址:{{ address }}</h2><button @click="showName">点我提示学校名称</button></div>
</template><script>// 组件交互相关 的代码(数据、方法等等)export default {name:'School',data() { return { schoolName: '尚硅谷',address: '北京昌平'}},methods:{ showName(){ alert(this.schoolName)}},}
</script><style>/* 组件的样式  */.demo {background-color: blue;}
</style>

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/277955.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

mybatis源码阅读系列(二)

前言 上一篇文章mybatis源码阅读系列&#xff08;一&#xff09;介绍了mybatis和原生jdbc的区别&#xff0c;并通过代码展示了两者的运行过程和结果&#xff0c;下面让我们继续详细了解下mybatis的执行过程&#xff1b; package com.wyl.mybatis.service;import com.wyl.mybat…

React三大属性---state,props,ref

react的三大属性 react的三大属性分别是state props 和ref 是传递数据的重要内容 State state是组件对象最重要的属性 包含多个key-value的组合呢 存在于组件实例对象中 基本使用 此时demo是通过onClick的回调 所以this是undefined 本来应该是window 但是局部开启了严格模…

【DL经典回顾】激活函数大汇总(十八)(ISRU附代码和详细公式)

激活函数大汇总&#xff08;十八&#xff09;&#xff08;ISRU附代码和详细公式&#xff09; 更多激活函数见激活函数大汇总列表 一、引言 欢迎来到我们深入探索神经网络核心组成部分——激活函数的系列博客。在人工智能的世界里&#xff0c;激活函数扮演着不可或缺的角色&a…

Android Studio 打包 Maker MV apk 详细步骤

一.使用RPG Make MV 部署项目&#xff0c;获取项目文件夹 这步基本都不会有问题&#xff1a; 二.安装Android Studio 安装过程参考教材就行了&#xff1a; https://blog.csdn.net/m0_62491877/article/details/126832118 但是有的版本面板没有Android的选项&#xff08;勾…

ES模块化

Node.js默认并不支持ES模块化&#xff0c;如果需要使用可以采用两种方式。方式一&#xff0c;直接将所有的js文件修改为mjs扩展名。方式二&#xff0c;修改package.json中type属性为module。 导出 默认导出 // 向外部导出内容 export let a 10 export const b "孙悟空…

Vue2 引入使用ElementUI详解

目录 1 安装2 引入2.1 全局引入2.1.1 引入2.1.2 使用 2.2 按需引入2.2.1 引入2.2.2 使用 3 总结 1 安装 推荐使用 npm 的方式安装&#xff0c;它能更好地和 webpack打包工具配合使用。&#xff08;本项目使用安装方式&#xff09; npm i element-ui -S也可以使用其他的包管理…

WebRTC:真正了解 RTP 和 RTCP

介绍 近年来&#xff0c;通过互联网进行实时通信变得越来越流行&#xff0c;而 WebRTC 已成为通过网络实现实时通信的领先技术之一。WebRTC 使用多种协议&#xff0c;包括实时传输协议 (RTP) 和实时控制协议 (RTCP)。 RTP负责通过网络传输音频和视频数据&#xff0c;而RTCP负责…

Java Swing游戏开发学习12

内容来自RyiSnow视频讲解 这一节讲的是实现游戏中的NPC(Non Player Character)非玩家角色。 添加了一个老人NPC&#xff0c;一个简单的AI&#xff08;人工智能&#xff09;拄着拐杖四处走。老人与树木、玩家的碰撞检测。 NPC四处走动 实现NPC四处走动 一开始&#xff0c;每一…

cmd常用指令

cmd全称Command Prompt&#xff0c;中文译为命令提示符。 命令提示符是在操作系统中&#xff0c;提示进行命令输入的一种工作提示符。 在不同的操作系统环境下&#xff0c;命令提示符各不相同。 在windows环境下&#xff0c;命令行程序为cmd.exe&#xff0c;是一个32位的命令…

AndroidStudio 由dolphin升级到giraffe,出现“gradle project sync failed“

1 现象描述 将AS由之前的dolphin版本升级到giraffe之后&#xff0c;接着打开以前的Android project&#xff0c;出现了"Gradle project sync failed…"的异常提示&#xff0c;在build面板中并没有出现project sync过程中报错的日志。 异常提示如下图所示&#xff1a…

springboot蛋糕订购小程序的设计与实现

摘 要 相比于以前的传统手工管理方式&#xff0c;智能化的管理方式可以大幅降低商家的运营人员成本&#xff0c;实现了蛋糕订购的标准化、制度化、程序化的管理&#xff0c;有效地防止了蛋糕订购的随意管理&#xff0c;提高了信息的处理速度和精确度&#xff0c;能够及时、准确…

安卓国产百度网盘与国外云盘软件onedrive对比

我更愿意使用国外软件公司的产品&#xff0c;而不是使用国内百度等制作的流氓软件。使用这些国产软件让我不放心&#xff0c;他们占用我的设备大量空间&#xff0c;在我的设备上推送运行各种无用的垃圾功能。瞒着我&#xff0c;做一些我不知道的事情。 百度网盘安装包大小&…

【JS】html字符转义

需求 将html转为字符串将html字符串转义&#xff0c;比如<div>转为<div> 码 /*** html标签字符转义* param {Stirng} str 要转换的html字符* returns String 返回转义的html字符串*/ const elToStr str > str.replaceAll(<, <).replaceAll(>, >)…

实现界面跳转及注册界面编写(AndroidStudio)

目录 一、代码 二、最后效果 一、代码 1.先新建一个activity文件 2.注册界面的代码如下&#xff1a; <?xml version"1.0" encoding"utf-8"?> <LinearLayout xmlns:android"http://schemas.android.com/apk/res/android"android:la…

读书笔记--数据建模与设计的总结感悟

最近再次研读了DAMA数据管理知识体系,结合目前组织的信息化数字化建设情况,有所感悟就记录如下,供大家参考。数据建模和设计是应用系统或者数据架构设计过程中必须要整体考虑的事情,只是考虑的层级高度、细致情况不同罢了,大家在做信息化建设过程中,在做业务分析和需求调…

Helm Chart部署最简SpringBoot到K8S(AWS EKS版)

目标 这里假设&#xff0c;我们已经基本会使用k8s的kubectl命令进行部署了&#xff0c;也已经会自己打docker镜像推送到AWS ECR上面去了。而且&#xff0c;已经在云上准备好了AWS ECR镜像库和AWS EKS的k8s集群了。 这个前提上面&#xff0c;我们今天使用Helm Chart项目准备k8s…

问了 Gemini 1.5 Pro 五个问题,找到了初遇ChatGPT的感觉

一个月前&#xff08;2月15日&#xff09;&#xff0c;Sora和 Gemini 1.5 同时推出&#xff0c;这个故事很多人都听过了&#xff0c;Google 被冠以 AI 界汪峰的名头。 人们纷纷震惊于 Sora 的强大&#xff0c;讨论 Sora 是不是世界模型。而 Gemini 1.5 的第一个模型 Gemini 1.…

redis发布订阅与stream类型

发布订阅 redis发布订阅(pub/sub)是一种消息通信模式&#xff1b;发送者(pub)发送消息&#xff0c;订阅者(sub)接收消息。redis客户端可以订阅任意数量的频道。 基础命令&#xff1a; 语法 redis publish命令基本语法如下&#xff1a; redis 127.0.0.1:6379> PUBLISH ch…

unity学习(61)——hierarchy和scene的全新认识+模型+皮肤+动画controller

刚刚开始&#xff0c;但又结束的感觉&#xff1f; 1.对hierarchy和scene中的内容有了全新的认识 一定要清楚自己写过几个scene&#xff1b;每个scene之间如何跳转&#xff1b;build setting是add当前的scene。 2.此时的相机需要与模型同级&#xff0c;不能在把模型放在相机下…

STM32输入捕获模式测频率

STM32频率的测量&#xff1a;高频适合使用的方法是测频法&#xff0c;低频适合使用的是测周法&#xff0c;&#xff08;其中使用测频法测量频率比较稳定&#xff0c;使用测周法测量频率的方式没有这么稳定&#xff0c;因为测周法只会通过一次的测量就能得出结果所以测试出来的频…