0
点赞
收藏
分享

微信扫一扫

Vue--为什么data是个函数--实例讲解

星河出山 2022-02-15 阅读 176


简介

说明

        本文用示例介绍Vue中的data设计为函数的原因。

        分别用Vue和原生JavaScript进行展示。

结论

        对象是一个引用数据类型,如果data是一个对象会造成所有组件共用一个data。若data是一个函数,每次函数都会返回一个新的对象,这样每个组件都会维护一份独立的对象(data)。

        根实例对象data可以是对象也可以是函数(根实例是单例),不会产生数据污染情况。

        vue支持将一个对象作为vue构造参数中data属性的值,如果data是方法的话,也会先取得内部返回的对象结果。详见代码:

// vue/src/core/instance/state.js
function initData (vm: Component) {
var data = vm.$options.data;
data = vm._data = typeof data === 'function'
? getData(data, vm)
: data || {};
if (!isPlainObject(data)) {
data = {};
process.env.NODE_ENV !== 'production' && warn(
'data functions should return an object:\n' +
'https://vuejs.org/v2/guide/components.html#data-Must-Be-a-Function',
vm
);
}
...
}

官网

​​组件基础 — Vue.js​​

问题引出

        大家都知道,Vue的组件一般是下边这样写的。

        可以看到,data是个函数,那么为什么不写成对象呢?就像这样:data: { msg: 'Hello'}

<template>
<div class="hello">
hello world
</div>
</template>

<script>
export default {
name: 'Demo',
data () {
return {
msg: 'Hello'
}
}
}
</script>

<style scoped>

</style>

实例:使用Vue创建计数器

例1:data为函数

<!doctype html>
<html lang="en">

<head>
<meta charset="UTF-8">
<title>this is title</title>
</head>

<body>

<div id="components-demo">
<button-counter></button-counter>
<button-counter></button-counter>
<button-counter></button-counter>
</div>

<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
<script>Vue.config.productionTip = false</script>

<script>
// 定义一个名为 button-counter 的新组件
Vue.component('button-counter', {
data: function () {
return {
count: 0
}
},
template: '<button v-on:click="count++">你点击了 {{ count }} 次</button>'
})

new Vue({
el: '#components-demo'
})
</script>

</body>
</html>

结果:每个计数器单独计数

例2:data为对象

<!doctype html>
<html lang="en">

<head>
<meta charset="UTF-8">
<title>this is title</title>
</head>

<body>

<div id="components-demo">
<button-counter></button-counter>
<button-counter></button-counter>
<button-counter></button-counter>
</div>

<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
<script>Vue.config.productionTip = false</script>

<script>
// 定义一个名为 button-counter 的新组件
Vue.component('button-counter', {
data: {
count: 0
},
template: '<button v-on:click="count++">你点击了 {{ count }} 次</button>'
})

new Vue({
el: '#components-demo'
})
</script>

</body>
</html>

结果:直接报错

Vue--为什么data是个函数--实例讲解_javascript_02

是因为新版的Vue2直接进行了检测,如果不是函数,就会报错。

如果是旧版的Vue2,那么结果是:点击了一个按钮,所有按钮都会增加次数(它们共享data里的count这个属性)。

实例:原生JS

例1:data为函数

<!doctype html>
<html lang="en">

<head>
<meta charset="UTF-8">
<title>This is title</title>
</head>

<body>

<div class="container">
这是个Demo
</div>

<script>
function MyComponent() {
this.data = this.data();
}

MyComponent.prototype.data = function() {
return {
age: 12
}
};

let user1 = new MyComponent();
let user2 = new MyComponent();

console.log(user1.data === user2.data) // false

user1.data = {age: 13};

console.log('user1的age:' + user1.data.age); //user1的age:13
console.log('user2的age:' + user2.data.age); //user2的age:12
</script>
</body>
</html>

结果:输出的结果不同

Vue--为什么data是个函数--实例讲解_前端_03

例2:data为对象

<!doctype html>
<html lang="en">

<head>
<meta charset="UTF-8">
<title>This is title</title>
</head>

<body>

<div class="container">
这是个Demo
</div>

<script>
function MyComponent() {
}

MyComponent.prototype.data = {
age: 12
}

let user1 = new MyComponent();
let user2 = new MyComponent();

console.log(user1.data === user2.data) // false

user1.data = {age: 13};

console.log('user1的age:' + user1.data.age); //user1的age:13
console.log('user2的age:' + user2.data.age); //user2的age:12
</script>
</body>
</html>

结果:输出的结果相同

Vue--为什么data是个函数--实例讲解_前端_04


举报

相关推荐

0 条评论