Vue.js进阶系列(4)--模板抽离和组件数据存放

  通过前面语法糖的介绍,我们简化了组件注册的步骤,但是对于template模块的书写还是比较繁琐,下面小编为大家分享两种方法来实现template模板的抽离并且告诉大家组件能否操作Vue实例中的数据

一、模板抽离

1.使用script标签

使用script标签,直接将原本template的内容直接复制到script下即可。

    
        

image.png

  在这个例子中,声明了全局组件cnp,并且通过script标签包裹了template的内容,内容可以正常的显示,但是要注意以下两点:
  ① script标签的类型: 此时script标签的类型变成了x-template,不在是原来的javascript类型
  ② script标签和template的联系script标签和template之间是没有联系的,为了让script标签的内容传递到template中,需要通过选择器建立起链接。比如本例中就为script声明了id名为cnp1的id选择器,然后在template使用cnp1就可以将cnp1的HTML内容模板传递到template中

2.使用template标签

  template标签的用法和普通标签的用法是一样的,直接将模板的内容赋值到该标签即可。

    
        

image.png

  可以看到是同样的效果,同理,为了将template标签和组件中的template建立起联系,也需要通过建立选择器来建立关联。比如本例中为template标签声明了id名为cnp1的id选择器,然后在cnp组件的template中使用“cnp1”.
  以上通过使用script标签和template标签就可以将组件中的模板抽离出来让代码有了更强的可读性

二、组件数据存放

  在前面有关组件的知识中可以发现,小编在组件的template是数据都是写死的,那么我们能不能通过使用"{{变量}}"这种形式来访问Vue实例中的数据呢?让我们来看一下下面的例子:

    
        

image.png

  没有显示出mssage的内容,并且说message是未定义的。
结论:
  组件是不能够使用Vue实例中的data数据,说明组件应该有属于自己的数据data。
分析:
  组件是一个单独功能模块的封装,有属于自己的HTML模板,也应该有属于自己的数据data。即使组件可以访问Vue实例中的数据,但是如果将所有数据都放在Vue实例中,Vue实例就会变得非常臃肿【因为前面提到,所有的组件最终会形成一棵组件树】

1.组件数据存放

  按照上面是思路,组件会有自己的data属性,然后我们将message变量放在data属性中,代码如下:



image.png

  由结果可以看出,组件中的data并不想Vue实例中的data一样是一个对象,而应该是一个函数,并且返回的是一个实例,所以组件中data的书写应该如下:



image.png

因此,对于组件数据的存放总结一下几点:
  ① 组件对象属于自己的data
  ② data是一个函数,并且返回的是一个实例对象
  ③ 对象内部保存着数据
此外呢,组件对象也有像Vue实例一样拥有method等属性,只有data属性必须是一个函数,其余的和Vue实例中的保持一致

接下来我们讨论一个很严肃的问题:

为什么组件中的data是一个函数而不是对象?

这个缘由我们的先从函数说起。先来看下面的代码:

const obje= {
            name:'why',
            age:18,
        }   
function abc(){
    return obje
}   
    let obje1 = abc();
    let obje2 = abc();
    let obje3 = abc();

    obje1.name='Hello'
    console.log('obje1.name:'+ obje2.name);
    console.log('obje2.name:'+ obje2.name);
    console.log('obje3.name:'+ obje3.name);

image.png

  由图可知他们是同一个对象。其实可以这样子理解:声明的obje对象就代表了一块内存地址(假设内存地址为0x110),函数abc返回obje对象时其实就是返回了0x110,不管调用多少次,返回的内存地址都是一样的。当obje1修改的那么值时,其实就相当于修改了内存地址存储的name值,所以obje2和obje3的值也会发生改变。具体如下图:
函数.png

接下来我们再来看一段代码:

function abc(){
    return {
            name:'why',
            age:18,
            }
    }
    let obje1 = abc();
    let obje2 = abc();
    let obje3 = abc();

  在上面的代码中,定义了一个名字为abc的函数,并且返回一个对象,该对象有name属性和age属性,然后调用三次abc函数并以此存储在变量obje1,obje2,obje3中。那我们思考一下,obje1、obje2、obje3是不是同一个对象?
  结论是** 它们并不是同一个对象,因为函数每次被调用的时候,都会在自己的栈空间创建很多的变量。想要验证是不是同一个对象其实很简单,如果是同一个对象,有一个特点:牵一发而动全身**,我们修改obje1的值,如果obje2和obje3的值也跟着改变,说明是同一个对象,否则就不是,让我们来看下面的例子:

obje1.name='Hello'
console.log('obje1.name:'+ obje2.name);
console.log('obje2.name:'+ obje2.name);
console.log('obje3.name:'+ obje3.name);

image.png

  可以发现,obje2和obje3的值么有发生变化,说明他们不是同一个对象,具体分析如下:
  声明的变量obje1会指向abc函数返回的结果,因为每次调用函数时,函数都会在自己的栈空间创建,所以调用三次函数,相当于创建了三块东西,而变量存储的内容就是这三块东西的地址,具体如下图所示:
函数.png

  这也就是为什么组件数据存放是函数而不是属性的原因
  组件是具有特定功能的单独的个体,我们希望在页面1中定义的组件也能在页面2中使用,如果组件的数据存储不是函数,当我们修改页面1中的组件就会导致页面2中的组件也发生改变,这是我们不希望看到的。下面通过例子来为大家讲解:

    
        
组件.gif

  在这里例子中,我们在组件中用了简单的计数器。这是我们希望看到的效果,当点击第一个计数器,不会影响到下面两个计数器,而如果把组件中的数据代码块换成下面这就写法,就会产生十分恐怖的事情:

const obje = {
            title:"当前数值:",
            counter:0
        }
Vue.component('cnp',{
    template:'#cnp1',
    data:function(){
            return obje
        },
组件.gif

  所以这就是为什么在开发Vue的时候,组件数据存储的data必须是函数而不是属性。

  以上就是小编今天为大家分享的知识,可能后面关于组件数据的存放讲解的不是很到位,希望大家多多包涵。

你可能感兴趣的:(Vue.js进阶系列(4)--模板抽离和组件数据存放)