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 相关文章推荐
如何快速的呈现我们的网页的技巧整理
Jul 01 Javascript
CSS+jQuery实现的一个放大缩小动画效果
Sep 24 Javascript
javascript实现的平方米、亩、公顷单位换算小程序
Aug 11 Javascript
jquery siblings获取同辈元素用法实例分析
Jul 25 Javascript
AngularJS指令详解及示例代码
Aug 16 Javascript
微信小程序  action-sheet详解及实例代码
Nov 09 Javascript
JS实现一个简单的日历
Feb 22 Javascript
JavaScript设计模式之调停者模式实例详解
Feb 03 Javascript
RequireJS用法简单示例
Aug 20 Javascript
用 js 写一个 js 解释器过程详解
Aug 02 Javascript
vue实现图书管理系统
Dec 29 Vue.js
vue实现轮播图帧率播放
Jan 26 Vue.js
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
区分JS中的undefined,null,&quot;&quot;,0和false
2007/03/08 Javascript
javascript while语句和do while语句的区别分析
2007/12/08 Javascript
几个javascript操作word的参考代码
2009/10/26 Javascript
JQuery选中checkbox方法代码实例(全选、反选、全不选)
2015/04/27 Javascript
Bootstrap精简教程
2015/11/27 Javascript
JS获取时间的相关函数及时间戳与时间日期之间的转换
2016/02/04 Javascript
Bootstrap基本插件学习笔记之模态对话框(16)
2016/12/08 Javascript
微信小程序实现的一键复制功能示例
2019/04/24 Javascript
express + jwt + postMan验证实现持久化登录
2019/06/05 Javascript
Nodejs 识别图片类型的方法
2019/08/15 NodeJs
JS实现简单日历特效
2020/01/03 Javascript
vue中js判断长时间不操作界面自动退出登录(推荐)
2020/01/22 Javascript
js实现盒子移动动画效果
2020/08/09 Javascript
[01:35]2014DOTA2西雅图邀请赛 专访狐狸妈青春献给刀塔
2014/07/08 DOTA
python进阶教程之模块(module)介绍
2014/08/30 Python
在python的类中动态添加属性与生成对象
2016/09/17 Python
用python写一个windows下的定时关机脚本(推荐)
2017/03/21 Python
python解决js文件utf-8编码乱码问题(推荐)
2018/05/02 Python
在python plt图表中文字大小调节的方法
2019/07/08 Python
python 爬取学信网登录页面的例子
2019/08/13 Python
Python3视频转字符动画的实例代码
2019/08/29 Python
python如何基于redis实现ip代理池
2020/01/17 Python
python实现加密的方式总结
2020/01/19 Python
Pycharm-community-2020.2.3 社区版安装教程图文详解
2020/12/08 Python
python实现ping命令小程序
2020/12/28 Python
css3如何绘制一个圆圆的loading转圈动画
2018/01/09 HTML / CSS
中国医药集团国药在线:国药网
2017/02/06 全球购物
全球知名的珠宝首饰品牌:Kay Jewelers
2018/02/11 全球购物
波兰最大的电商平台:Allegro.pl
2021/02/06 全球购物
大学生怎样进行自我评价
2013/12/07 职场文书
销售经理竞聘书
2014/03/31 职场文书
班干部竞选演讲稿
2014/04/24 职场文书
党员对照检查材料思想汇报
2014/09/16 职场文书
2016党员读书思廉心得体会
2016/01/23 职场文书
浅谈vue2的$refs在vue3组合式API中的替代方法
2021/04/18 Vue.js
SpringBoot SpringEL表达式的使用
2021/07/25 Java/Android