前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >声明式渲染与 data 函数

声明式渲染与 data 函数

作者头像
LIYI
发布2020-01-13 16:36:44
5590
发布2020-01-13 16:36:44
举报
文章被收录于专栏:艺述论专栏艺述论专栏
目录

声明式渲染
data 必须是一个函数
为什么 data 必须是一个函数?
提一个 data 作为箭头函数的写法
源码

声明式渲染

这是学习vue开发,必先了解的第一个特征。如前已经实现的App.vue组件,已经包括声明式渲染:

<template>
  <div>{{message}}</div>
</template>

<script>
export default {
  name: 'App',
  components: {},
  data: () => ({
    message:'hi'
  }),
};
</script>

message是在data中声明的一个文本,直接以{{message}}内嵌于模板中。当message改变时,模板会自动更新。

这是由于vue2基于Object.defineProperty()data中的每个属性定义了一对setter/getter。当模板渲染时,getter被调用,视图依赖的数据项被记录下来;当数据改变时,检查改变的数据有没有被依赖,如果有,重新渲染视图。

这就是MVVM框架在viewdata-view之间实现的BI-DataBinding机制。

data 必须是一个函数

如果直接返回一个对象,在vue-cli3中,编译阶段直接就报错了。

vue组件的导出是唯一的,如果返回的是一个对象,那么所有该组件的实例将共享同一块内存的数据对象,改变任何一个组件实例的数据,其它均会受到影响。

例如,将App.vue修改为:

<template>
  <div>
    <HellWorld></HellWorld>
    <HellWorld></HellWorld>
    <HellWorld></HellWorld>
  </div>
</template>

<script>
import HellWorld from './HelloWorld.vue'
export default {
  name: 'App',
  components: {HellWorld},
};
</script>

并新增一个HelloWorld.vue组件:

<template>
  <div @click="message+='!'">{{message}}</div>
</template>

<script>
const data = {
  message:'hi'
}
export default {
  name: 'HelloWorld',
  components: {},
  data: ()=>data,
};
</script>

当单击div时,message尾部追求一个符号。data虽然是一个函数,但是返回的却是一个const对象。const data在项目仅会声明一次,在多个组件实例中是唯一的。

如图所示,单击任何一个组件,其它组件亦受影响:

解决方法也很简单,直接让data返回一个局部的临时对象:

<script> // const data = { // message:'hi' // } export default { name: 'HelloWorld', components: {}, data: ()=>({ message:'hi' }), }; </script>

运行效果:

为什么 data 必须是一个函数?

这是vue2内部源码要求的。通过查看Vue->_init->initState->initData源码:

发现,如果data未定义,一个默认的data对象会被创建,否则data会被当成一个function被调用。

而在initData中,data function被以call的方式调用了:

其中pushTarget(),疑为对data observer的处理。

即使data function是一个函数,也仅是在初始化时调用一次,然后函数返回的值就一直保存在了vm._data上。在后续的运行时数据发生时,改变的也是vm._data,这个对象在组件的生命内,其引用一直保持不变。

提一个 data 作为箭头函数的写法

细心的读者会发现,data function没有return

  data: ()=>({
    message:'hi'
  }),

这是一个箭头函数,当函数体代码只有一句时, return可以省略。

那么,花括号外面的()能不能省略?

不能,因为函数返回的是一个字面值对象。如果这里的()省略了,编译器不清楚后面的{}究竟表示对象,还是函数的边界了。

源码

https://git.code.tencent.com/shiqiaomarong/vue-go-rapiddev-example/tags/v20200108

参考链接

  • https://www.liaoxuefeng.com/wiki/1022910821149312/1031549578462080
  • https://juejin.im/entry/59225ff8a22b9d005885cb15
  • https://blog.rxliuli.com/p/2f1f8cdf/
本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2020-01-08,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 艺述论 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 声明式渲染
  • data 必须是一个函数
  • 为什么 data 必须是一个函数?
  • 提一个 data 作为箭头函数的写法
  • 源码
  • 参考链接
相关产品与服务
云函数
云函数(Serverless Cloud Function,SCF)是腾讯云为企业和开发者们提供的无服务器执行环境,帮助您在无需购买和管理服务器的情况下运行代码。您只需使用平台支持的语言编写核心代码并设置代码运行的条件,即可在腾讯云基础设施上弹性、安全地运行代码。云函数是实时文件处理和数据处理等场景下理想的计算平台。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档