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 相关文章推荐
用js实现预览待上传的本地图片
Mar 15 Javascript
javascript判断单选框或复选框是否选中方法集锦
Apr 04 Javascript
Javascript selection的兼容性写法介绍
Dec 20 Javascript
js 通过cookie实现刷新不变化树形菜单
Oct 30 Javascript
jQuery中:lt选择器用法实例
Dec 29 Javascript
jQuery AjaxUpload 上传图片代码
Feb 02 Javascript
BootStrap日期控件在模态框中选择时间下拉菜单无效的原因及解决办法(火狐下不能点击)
Aug 18 Javascript
jQuery实现的网页换肤效果示例
Sep 20 Javascript
JSON对象 详解及实例代码
Oct 18 Javascript
在vue项目中使用Nprogress.js进度条的方法
Jan 31 Javascript
微信小程序网络请求封装示例
Jul 24 Javascript
Vue使用Canvas绘制图片、矩形、线条、文字,下载图片
Apr 26 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
PHP中显示格式化的用户输入
2006/10/09 PHP
php chr() ord()中文截取乱码问题解决方法
2008/09/08 PHP
解析php常用image图像函数集
2013/06/24 PHP
PHP扩展迁移为PHP7扩展兼容性问题记录
2016/02/15 PHP
thinkPHP5框架分页样式类完整示例
2018/09/01 PHP
Firefox getBoxObjectFor getBoundingClientRect联系
2008/10/26 Javascript
javascript中利用数组实现的循环队列代码
2010/01/24 Javascript
js实现单一html页面两套css切换代码
2013/04/11 Javascript
js 本地预览的简单实现方法
2014/02/18 Javascript
jQuery leonaScroll 1.1 自定义滚动条插件(推荐)
2016/09/17 Javascript
教大家轻松制作Bootstrap漂亮表格(table)
2016/12/13 Javascript
JS实现间歇滚动的运动效果实例
2016/12/22 Javascript
Javascript前端经典的面试题及答案
2017/03/14 Javascript
jQuery Layer弹出层传值到父页面的实现代码
2017/08/17 jQuery
深入理解Vue生命周期、手动挂载及挂载子组件
2017/09/27 Javascript
Validform验证时可以为空否则按照指定格式验证
2017/10/20 Javascript
纯html+css+javascript实现楼层跳跃式的页面布局(实例代码)
2017/10/25 Javascript
webpack中CommonsChunkPlugin详细教程(小结)
2017/11/09 Javascript
Servlet返回的数据js解析2种方法
2019/12/12 Javascript
原生js实现日期选择插件
2020/05/21 Javascript
JavaScript this关键字指向常用情况解析
2020/09/02 Javascript
python版简单工厂模式
2017/10/16 Python
Python设计模式之工厂模式简单示例
2018/01/09 Python
使用Python爬取最好大学网大学排名
2018/02/24 Python
python实现扫雷游戏
2020/03/03 Python
简单介绍一下pyinstaller打包以及安全性的实现
2020/06/02 Python
python代码中怎么换行
2020/06/17 Python
基于Django快速集成Echarts代码示例
2020/12/01 Python
Java面试笔试题大全
2016/11/23 面试题
Ruby如何实现动态方法调用
2012/11/18 面试题
美术专业学生个人自我评价
2013/09/19 职场文书
计算机本科生自荐信
2013/10/15 职场文书
中学学校门卫岗位职责
2014/08/15 职场文书
入党申请书怎么写?
2019/06/11 职场文书
PyMongo 查询数据的实现
2021/06/28 Python
cypress测试本地web应用
2022/06/01 Javascript