vue.js页面加载执行created,mounted的先后顺序说明


Posted in Javascript onNovember 07, 2020

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,页面初始化如下

vue.js页面加载执行created,mounted的先后顺序说明

当在文本框输入其他值时

vue.js页面加载执行created,mounted的先后顺序说明

会提醒你避免直接更改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>

页面

vue.js页面加载执行created,mounted的先后顺序说明

可以看到无论原始类型msgA和引用类型值msgB都和接受的props值时严格相等的。

分别改变两个文本框的值

vue.js页面加载执行created,mounted的先后顺序说明

只有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都是的引用都是相同的,也就是引用同一个对象,其中一个属性值发生变化时,都会发生变化。而原始类型不会。

vue.js页面加载执行created,mounted的先后顺序说明

所以这里其实延伸到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特别重要。

以上这篇vue.js页面加载执行created,mounted的先后顺序说明就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
javascript 闭包疑问
Dec 30 Javascript
基于JQuery的Select选择框的华丽变身
Aug 23 Javascript
基于JavaScript 声明全局变量的三种方式详解
May 07 Javascript
如何书写高质量jQuery代码(使用jquery性能问题)
Jun 30 Javascript
jQuery中scrollTop()方法用法实例
Jan 16 Javascript
JS简单实现DIV相对于浏览器固定位置不变的方法
Jun 17 Javascript
对Angular.js Controller如何进行单元测试
Oct 25 Javascript
jQuery用FormData实现文件上传的方法
Nov 21 Javascript
AngularJS 表单验证手机号的实例(非必填)
Nov 12 Javascript
浅谈vue-cli 3.0.x 初体验
Apr 11 Javascript
vue的keep-alive中使用EventBus的方法
Apr 23 Javascript
解决vant的Toast组件时提示not defined的问题
Nov 11 Javascript
Node.js path模块,获取文件后缀名操作
Nov 07 #Javascript
解决vue props传Array/Object类型值,子组件报错的情况
Nov 07 #Javascript
解决Vue watch里调用方法的坑
Nov 07 #Javascript
浅谈vue.watch的触发条件是什么
Nov 07 #Javascript
html+vue.js 实现漂亮分页功能可兼容IE
Nov 07 #Javascript
解决vue watch数据的方法被调用了两次的问题
Nov 07 #Javascript
vue 避免变量赋值后双向绑定的操作
Nov 07 #Javascript
You might like
php5.2以下版本无json_decode函数的解决方法
2014/05/25 PHP
Laravel 5框架学习之环境与配置
2015/04/08 PHP
PHP编程中的__clone()方法使用详解
2015/11/27 PHP
php从数据库读取数据,并以json格式返回数据的方法
2018/08/21 PHP
Extjs学习笔记之六 面版
2010/01/08 Javascript
jquery实现带复选框的表格行选中删除时高亮显示
2013/08/01 Javascript
Javascript表格翻页效果实现思路及代码
2013/08/23 Javascript
IE网页js语法错误2行字符1、FF中正常的解决方法
2013/09/09 Javascript
jquery选择器原理介绍($()使用方法)
2014/03/25 Javascript
jQuery 如何先创建、再修改、后添加DOM元素
2014/05/20 Javascript
微信小程序开发animation心跳动画效果
2017/08/16 Javascript
node.js-v6新版安装具体步骤(分享)
2017/09/06 Javascript
vue+element项目中过滤输入框特殊字符小结
2019/08/07 Javascript
使用vue实现多规格选择实例(SKU)
2019/08/23 Javascript
js实现九宫格抽奖
2020/03/19 Javascript
vue tab滚动到一定高度,固定在顶部,点击tab切换不同的内容操作
2020/07/22 Javascript
[01:23:35]Ti4主赛事胜者组 DK vs EG 1
2014/07/19 DOTA
[01:07:34]DOTA2-DPC中国联赛定级赛 RNG vs Aster BO3第二场 1月9日
2021/03/11 DOTA
使用Protocol Buffers的C语言拓展提速Python程序的示例
2015/04/16 Python
Python设计实现的计算器功能完整实例
2017/08/18 Python
Python安装模块的常见问题及解决方法
2018/02/05 Python
python OpenCV学习笔记实现二维直方图
2018/02/08 Python
python查找指定文件夹下所有文件并按修改时间倒序排列的方法
2018/10/21 Python
python爬虫获取小区经纬度以及结构化地址
2018/12/30 Python
解决Python正则表达式匹配反斜杠''\''问题
2019/07/17 Python
Tensorflow的梯度异步更新示例
2020/01/23 Python
Python如何使用ElementTree解析xml
2020/10/12 Python
Python return语句如何实现结果返回调用
2020/10/15 Python
英国门把手公司:Door Handle Company
2019/05/12 全球购物
本科生学习总结的自我评价
2013/10/02 职场文书
优秀毕业生求职信范文
2014/01/02 职场文书
运动会通讯稿150字
2014/02/15 职场文书
生产部厂长助理职位说明书
2014/03/03 职场文书
电话客服工作职责
2014/07/27 职场文书
乡村教师党员四风问题对照检查材料思想汇报
2014/10/08 职场文书
Python面向对象之成员相关知识总结
2021/06/24 Python