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 07 Javascript
js模拟select下拉菜单控件的代码
May 08 Javascript
jQuery实现企业网站横幅焦点图切换功能实例
Apr 30 Javascript
跨域资源共享 CORS 详解
Apr 26 Javascript
详解Js模板引擎(TrimPath)
Nov 22 Javascript
微信小程序 使用canvas制作K线实例详解
Jan 12 Javascript
AngularJs表单校验功能实例代码
Feb 09 Javascript
用js实现每隔一秒刷新时间的实例(含年月日时分秒)
Oct 25 Javascript
javascript数据类型中的一些小知识点(推荐)
Apr 18 Javascript
Vue的双向数据绑定实现原理解析
Feb 17 Javascript
vue data对象重新赋值无效(未更改)的解决方式
Jul 24 Javascript
React 并发功能体验(前端的并发模式)
Jul 01 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/12/05 PHP
php记录日志的实现代码
2011/08/08 PHP
php画图实例
2014/11/05 PHP
PHP实现通过正则表达式替换回调的内容标签
2015/06/15 PHP
PHP框架自动加载类文件原理详解
2017/06/06 PHP
extjs fckeditor集成代码
2009/05/10 Javascript
IE6下focus与blur错乱的解决方案
2011/07/31 Javascript
关于JS判断图片是否加载完成且获取图片宽度的方法
2013/04/09 Javascript
jQuery Mobile的loading对话框显示/隐藏方法分享
2013/11/26 Javascript
JS实现图片放大镜效果的方法
2015/02/27 Javascript
js删除Array数组中指定元素的两种方法
2016/08/03 Javascript
JavaScript定义函数_动力节点Java学院整理
2017/06/27 Javascript
Require.js的基本用法详解
2017/07/03 Javascript
vue2手机APP项目添加开屏广告或者闪屏广告
2017/11/28 Javascript
Angular项目从新建、打包到nginx部署全过程记录
2017/12/09 Javascript
旺旺在线客服代码 旺旺客服代码生成器
2018/01/09 Javascript
jQuery实现的下雪动画效果示例【附源码下载】
2018/02/02 jQuery
快速解决Vue项目在IE浏览器中显示空白的问题
2018/09/04 Javascript
[01:02:25]2014 DOTA2华西杯精英邀请赛5 24 NewBee VS VG
2014/05/25 DOTA
[00:17]游戏风云独家报道:DD赛后说出数字秘密 吓死你们啊!
2014/07/13 DOTA
Python 流程控制实例代码
2009/09/25 Python
Tensorflow 合并通道及加载子模型的方法
2018/07/26 Python
python射线法判断一个点在图形区域内外
2019/06/28 Python
django项目简单调取百度翻译接口的方法
2019/08/06 Python
python每天定时运行某程序代码
2019/08/16 Python
关于tf.reverse_sequence()简述
2020/01/20 Python
python mysql自增字段AUTO_INCREMENT值的修改方式
2020/05/18 Python
Python  word实现读取及导出代码解析
2020/07/09 Python
Css3实现无缝滚动防抖
2020/09/14 HTML / CSS
世界上最大的曲棍球商店:Pro Hockey Life
2017/10/30 全球购物
大学生蛋糕店创业计划书
2014/01/13 职场文书
大三学年自我鉴定范文(3篇)
2014/09/28 职场文书
2014年宣传部个人工作总结
2014/12/06 职场文书
安全员岗位职责
2015/02/10 职场文书
部门优秀员工推荐信
2015/03/24 职场文书
2015年学校关工委工作总结
2015/04/03 职场文书