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 相关文章推荐
让mayfish支持mysqli数据库驱动的实现方法
May 22 Javascript
解决ExtJS在chrome或火狐中正常显示在ie中不显示的浏览器兼容问题
Jan 11 Javascript
JavaScript通过字符串调用函数的实现方法
Mar 18 Javascript
javascript截取字符串小结
Apr 28 Javascript
Javascript数组Array基础介绍
Mar 13 Javascript
easyui datagrid 大数据加载效率慢,优化解决方法(推荐)
Nov 09 Javascript
深入理解JS的事件绑定、事件流模型
May 13 Javascript
微信小程序项目总结之点赞 删除列表 分享功能
Jun 25 Javascript
JS中Promise函数then的奥秘探究
Jul 30 Javascript
微信小程序环境下将文件上传到OSS的方法步骤
May 31 Javascript
Vue 实现登录界面验证码功能
Jan 03 Javascript
小程序实现背景音乐播放和暂停
Jun 19 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
基于文本的搜索
2006/10/09 PHP
Ajax+PHP边学边练 之五 图片处理
2009/12/03 PHP
php 文章调用类代码
2011/08/11 PHP
php版银联支付接口开发简明教程
2016/10/14 PHP
PHP消息队列实现及应用详解【队列处理订单系统和配送系统】
2019/05/20 PHP
Javascript 二维数组
2009/11/26 Javascript
纯CSS打造的导航菜单(附jquery版)
2010/08/07 Javascript
JS重要知识点小结
2011/11/06 Javascript
文本框输入时 实现自动提示(像百度、google一样)
2012/04/05 Javascript
jquery仿QQ商城带左右按钮控制焦点图片切换滚动效果
2013/06/27 Javascript
jQuery移除元素自动解绑事件实现思路及代码
2014/05/31 Javascript
javascript的document.referrer浏览器支持、失效情况总结
2014/07/18 Javascript
js使用removeChild方法动态删除div元素
2014/08/01 Javascript
nodeJs爬虫获取数据简单实现代码
2016/03/29 NodeJs
jQuery获取访问者IP地址的方法(基于新浪API与QQ查询接口)
2016/05/25 Javascript
前端面试题及答案整理(二)
2016/08/26 Javascript
JS实现数组去重复值的方法示例
2017/02/18 Javascript
JS 60秒后重新发送验证码的实例讲解
2017/07/26 Javascript
JS实现标签滚动切换效果
2017/12/25 Javascript
vue如何引入sass全局变量
2018/06/28 Javascript
vue结合axios与后端进行ajax交互的方法
2018/07/06 Javascript
如何在Angular应用中创建包含组件方法示例
2019/03/23 Javascript
element的el-table中记录滚动条位置的示例代码
2019/11/06 Javascript
Python新手在作用域方面经常容易碰到的问题
2015/04/03 Python
python fabric使用笔记
2015/05/09 Python
CentOS 7下安装Python 3.5并与Python2.7兼容并存详解
2017/07/07 Python
用Python抢火车票的简单小程序实现解析
2019/08/14 Python
python爬虫调度器用法及实例代码
2020/11/30 Python
世界上最大的巴士旅游观光公司:Big Bus Tours
2016/10/20 全球购物
柯基袜:Corgi Socks
2017/01/26 全球购物
英国最大的老式糖果店:A Quarter Of
2017/04/08 全球购物
宝拉珍选官方旗舰店:2%水杨酸精华液,收缩毛孔粗大和祛痘
2018/07/01 全球购物
医院护理人员的自我评价分享
2013/10/04 职场文书
会计实习生工作总结的自我评价
2013/10/07 职场文书
公司年夜饭通知
2015/04/25 职场文书
利用正则表达式匹配浮点型数据
2022/05/30 Java/Android