vue

Vue组件data和created为什么是函数?

"vue"

Posted by ZWW on January 11, 2018

“vue组件”

我们vue中data都是对应的数组,然后写入变量数据,但是组件中为什么却是一个函数,

export default {
name: 'Pos',
mounted: function () {
    var orderHeight = document.body.clientHeight;
    document.getElementById("order-list").style.height = orderHeight + 'px';
},
created() {
    //读取常用商品列表
    axios.get('http://jspang.com/DemoApi/oftenGoods.php')
        .then(response => {
            //console.log(response);
            this.oftenGoods = response.data;
        })
        .catch(error => {
            console.log(error);
            alert('网络错误,不能访问');
        })
    //读取分类商品列表
    axios.get('http://jspang.com/DemoApi/typeGoods.php')
        .then(response => {
            //console.log(response);
            //this.oftenGoods=response.data;
            this.type0Goods = response.data[0];
            this.type1Goods = response.data[1];
            this.type2Goods = response.data[2];
            this.type3Goods = response.data[3];
        })
        .catch(error => {
            console.log(error);
            alert('网络错误,不能访问');
        })
},
data() {
    return {
        tableData: [], //订单列表的值
        oftenGoods: [],
        type0Goods: [],
        type1Goods: [],
        type2Goods: [],
        type3Goods: [],
        totalMoney: 0, //订单总价格
        totalCount: 0  //订单商品总数量
    }
}
}

“why?”

在创建或注册模板的时候,传入一个data属性作为用来绑定的数据。但是在组件中,data必须是一个函数,而不能直接把一个对象赋值给它。

Vue.component('my-component', {
template: '<div>OK</div>',
data() {
    return {} // 返回一个唯一的对象,不要和其他组件共用一个对象进行返回
},
})

你在前面看到,在new Vue()的时候,是可以给data直接赋值为一个对象的。这是怎么回事,为什么到了组件这里就不行了。

你要理解,上面这个操作是一个简易操作,实际上,它首先需要创建一个组件构造器,然后注册组件。注册组件的本质其实就是建立一个组件构造器的引用。使用组件才是真正创建一个组件实例。所以,注册组件其实并不产生新的组件类,但会产生一个可以用来实例化的新方式。

理解这点之后,再理解js的原型链:

var MyComponent = function() {}
MyComponent.prototype.data = {
a: 1,
b: 2,
}
// 上面是一个虚拟的组件构造器,真实的组件构造器方法很多

var component1 = new MyComponent()
var component2 = new MyComponent()
// 上面实例化出来两个组件实例,也就是通过<my-component>调用,创建的两个实例

component1.data.a === component2.data.a // true
component1.data.b = 5
component2.data.b // 5

可以看到上面代码中最后三句,这就比较坑爹了,如果两个实例同时引用一个对象,那么当你修改其中一个属性的时候,另外一个实例也会跟着改。这怎么可以,两个实例应该有自己各自的域才对。所以,需要通过下面方法来进行处理:

var MyComponent = function() {
this.data = this.data()
}
MyComponent.prototype.data = function() {
return {
    a: 1,
    b: 2,
}
}

这样每一个实例的data属性都是独立的,不会相互影响了。所以,你现在知道为什么vue组件的data必须是函数了吧。这都是因为js本身的特性带来的,跟vue本身设计无关。其实vue不应该把这个方法名取为data(),应该叫setData或其他更容易立即的方法名。