vue.js页面加载执行created,mounted的先后顺序说明
作者:孔燚森 发布时间:2024-05-09 15:10:22
created页面加载未渲染html之前执行。
mounted渲染html后再执行。
由于created在html模板生产之前所以无法对Dom进行操作而mounted可以。
补充知识:关于Vue子组件data选项某个属性引用子组件props定义的属性的几点思考
学过Vue的都知道Vue等MVVM框架相对于传统的JS库比如Jquery最大的区别在于数据驱动视图,重点在于数据,拿到数据后将数据通过模板{{}}语法或者v-html展示在页面上。
我们也都知道在Vue父子组件可以通过Props实现父组件传递到子组件。
在项目开发中,我们会遇到这种需求,页面初始化时,父组件通过接口拿到需要数据,然后拿到的数据通过props传递给子组件。在子组件会有些业务上的操作来改变接受的props值
注意Vue中子组件不能直接更改props值,这样会报错。
父组件需要拿到字组件改变后的值作为接口请求参数的值。
为了实现这种需求,我们一般会在data中定义某个属性,这个属性引用props的某个值。然后监听该数据,当该数据发生变化时,向父级组件传递自定义事件和改变后的值。
// 子组件
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>局部组件的使用</title>
</head>
<body>
<div id="app">
<h1>在有template选项时,#app里的内容不展示</h1>
</div>
</body>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script type="text/javascript">
// 全局组件在声明时已经挂在到全局,可以直接使用
Vue.component('Parent', {
template: `
<div>
<p>我是父组件</p>
<Child :childDataA="msg"/>
</div>
`,
data() {
return {
msg: '传递给子组件的数据'
}
},
methods: {
childHandler(val) {
console.log(val)
}
}
})
Vue.component('Child', {
template: `
<div>
<p>我是子组件</p>
{{ childDataA }}
<input type="text" v-model="childDataA" @input="changeValue">
</div>
`,
// 指定props属性的类型时,会对传入的参数进行类型检查,如果不符合就会报错
props: {
childDataA: {
type: String,
default: ''
},
childDataB: {
type: Object,
default: null
}
},
data() {
return {
msgA: this.childDataA,
msgB: this.childDataB
}
},
methods: {
changeValue() {
this.$emit('childHandler', this.msg)
}
}
})
// 声明局部组件App
const App = {
template: `
<div>
<Parent />
</div>
`
}
new Vue({
el: '#app',
data() {
return {
}
},
// 挂在子组件
components: {
App
},
//使用子组件
template: '<App/>'
})
</script>
</html>
在上面的代码中定义了子组件Child和父组件Parent,子组件的input框通过v-model绑定接受的props的childDataA,页面初始化如下
当在文本框输入其他值时
会提醒你避免直接更改props属性,而是基于props基础上定义data或者计算属性来操作。
接下来我们看另外一种情况。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>局部组件的使用</title>
</head>
<body>
<div id="app">
<h1>在有template选项时,#app里的内容不展示</h1>
</div>
</body>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script type="text/javascript">
// 全局组件在声明时已经挂在到全局,可以直接使用
Vue.component('Parent', {
template: `
<div>
<p>我是父组件</p>
<Child :childDataA="msg" :childDataB="msgB"/>
</div>
`,
data() {
return {
msg: '传递给子组件的数据',
msgB: {
name: '我是name属性'
}
}
},
methods: {
},
watch: {
msg(val) {
console.log(val)
},
msgB: {
deep: true,
handler: function(newVal, oldVal) {
console.log(newVal, oldVal)
}
}
}
})
Vue.component('Child', {
template: `
<div>
<p>我是子组件</p>
{{ childDataA }}
<input type="text" v-model="msgA">
<input type="text" v-model="msgB.name">
</div>
`,
// 指定props属性的类型时,会对传入的参数进行类型检查,如果不符合就会报错
props: {
childDataA: {
type: String,
default: ''
},
childDataB: {
type: Object,
default: null
}
},
data() {
return {
msgA: this.childDataA,
msgB: this.childDataB
}
},
methods: {
},
mounted() {
console.log(`msgA数据类型是${typeof this.msgA}`)
console.log(this.childDataA === this.msgA)
console.log(`msgB数据类型是${typeof this.msgB}`)
console.log(this.childDataB === this.msgB)
}
})
// 声明局部组件App
const App = {
template: `
<div>
<Parent />
</div>
`
}
new Vue({
el: '#app',
data() {
return {
}
},
// 挂在子组件
components: {
App
},
//使用子组件
template: '<App/>'
})
</script>
</html>
页面
可以看到无论原始类型msgA和引用类型值msgB都和接受的props值时严格相等的。
分别改变两个文本框的值
只有45行打印出改变后的name值,也就是说data选项的msgA引用props的childDataA,childDataA是一个原始类型,msgA改变并不会导致childDataA发生变化。也就是父组件的msg不会发生改变。而msgB引用props的childDataB,childDataA是一个引用类型,msgB改变导致childDataB发生变化。也就是父组件的data选型中的msgB发生变化。
不用深究Vue源码是如何具体实现的,在子组件的mounted阶段可以看到两个值childDataA=== msgA,childDataB=== msgB。从这里我们可以得值,父组件的msgB和子组件的props中的childDataB以及data中的msgB都是的引用都是相同的,也就是引用同一个对象,其中一个属性值发生变化时,都会发生变化。而原始类型不会。
所以这里其实延伸到JS中的原始类型和引用类型相等的比较。
原始类型只要值相等即可严格相等(字符串编制值也要相等)
引用类型的比较是引用的比较,必须要求内存地址相同。如果两个对象属性即属性值完全相同,但引用不同(地址不同),那这两个对象是不严格相等的。
var a = 1
b = a
b // 1
b = 2
b // 2
a // 1
var objA = {name: 'A'}
var objB = objA
objB //{name: 'A'}
objB.name = 'B
objA.name // 'B'
上面说了这么多,有什么用呢。其实我们可以得到以下几点启发
在实际业务开发中,如果子组件接受的props属性值改变后,父组件data选项中的值也需要知道值发生变化,当存在多个这样的props属性时,可以定义我一个对象,这样可以避免多次在组件定义并在父组件接受自定义事件并作逻辑处理,手动将父组件data中的多个属性的值改成自定义事件接受的值。
子组件的props建议使用对象来定义,而不是数组,通过对象定义可以对接受的类型进行校验。
无论是Jq,还是Vue都是建立在原生JS的基础上,所以理解熟悉原生JS特别重要。
来源:https://blog.csdn.net/csdnkongfanhu/article/details/87350728
猜你喜欢
- 如下所示:a = [1,2,3,4,5,6,7,8,9,10,11]step = 3b = [a[i:i+step] for i in ra
- Window.ShowModalDialog使用手册 基本介绍: showModalDialog() (IE 4+ 支持) sho
- osql简单用法:用来将本地脚本执行,适合sql脚本比较大点的情况,执行起来比较方便osql -S serverIP -U sa -P 12
- 本文实例讲述了Python3实现对列表按元组指定列进行排序的方法。分享给大家供大家参考,具体如下:Python版本: python3.+ 运
- Cookie是一种发送到客户浏览器的文本串句柄,并保存在客户机硬盘上,可以用来在某个Web站点会话之间持久地保持数据。Request和Res
- 前言本文提供将多个视频拼接为一个视频的Python工具代码,其中有一些限制条件,下面的代码说明会提到。环境依赖ffmpeg环境安装,可以参考
- 前言近日在做一个报表功能里面有一个这样的需求是统计各部门在某一月入职和离职的人数我的步骤先查出入职的人数SELECT dept ,COUNT
- 前言该脚本的代码大部分是参考自阿里云的官方帮助文档。1, 脚本语言使用的是python, 我个人只是了解python,没有太深入的知识功底2
- 前言本文将深入研究 preg_replace /e 模式下的代码执行问题,其中包括 preg_replace 函数的执行过程分析、正则表达式
- 对于golang, 交换两个数很简单,如下这么写就可以了:i, j = j, i等号左边和右边含有多个表达式,这就是平行赋值。 赋值分为两个
- Python input 等待键盘输入,超时选择默认值,释放input,之后重新进入等待键盘输入状态,直到用户输入可用数据。一、调用 fun
- Expires 属性 Expires 属性指定了在浏览器上缓冲存储的页距过期还有多少时间。如果用户在某个页过期之前又回到此页,就会显示缓冲区
- 1、授权机制的主要作用是什么?授权机制的基本作用是给某个主机上的用户对某个数据库以select,insert,update和detete的权
- 共轭转置共轭转置The symbols (·)T , (·)∗, and (·)H are,respectively, the transp
- 1. 优化你的MySQL查询缓存在MySQL服务器上进行查询,可以启用高速查询缓存。让数据库引擎在后台悄悄的处理是提高性能的最有
- 一、环境介绍操作系统: win10 64位python版本: 3.8IDE: 采用vscode用到的相关安装包CSDN打包下载地址: htt
- 获取计算机名# 获取计算机名,常用的方法有三种,但最常用的是第一种import osimport socket# method onenam
- 今天主要向大家讲述的是优化SQL Server数据库的实际操作经验的总结,同时也有对其优化的实际操作中出现的一些问题的描述,以及对SQL S
- 昨天公司的网络更换,然后在使用git操作代码的时候,遇见了标题所述问题。仅以此文,记录该问题的解决过程。首先第一步: 得到本机的I
- 目录正文开始1. DRF 中的限流2. 限流进阶配置3. 限流思路分析4. 源码分析5. 其它注意事项参考资料正文开始先说一个限流这个概念,