Vue2 第二天学习

个人小总结:1年多没有写博客,感觉很多知识点生疏了,虽然工作上能解决问题,但是当别人问到某个知识点的时候,还是迷迷糊糊的,所以坚持写博客是硬道理的,因为大脑不可能把所有的知识点记住,有可能某一天忘了,但是我们工作上还是会使用,只是理论忘了,所以写博客的好处是可以把之前的东西重新看一遍后会在大脑里面重新浮现起来,特别在面试的时候,别人问你的知识点的时候答不上来那种尴尬,但是平时经常使用到,只是说不出所以来的,因此写博客是最好的思路。

阅读目录

  • 1.vue属性和方法
  • 2.理解组件的通信。
  • 3.理解自定义事件
  • 4.理解使用自定义事件的表单输入组件
  • 5.单个slot。
  • 6.具名slot
  • 7.理解作用域插槽(2.1.0新增的)
  • 8.理解动态组件
回到顶部

1.vue属性和方法

每个Vue实例都会代理其 data对象里所有的属性。
如下代码:

var data = {
  a: 1
};
var vm = new Vue({
 data: data
});
console.log(vm);
console.log(vm.a === data.a); // true

// 设置属性也会影响到原始数据
vm.a = 2;
console.log(data.a); // 2
// 反之
data.a = 3;
console.log(vm.a); // 3
//除了data属性,Vue实例还暴露了一些有用的实例属性与方法。这些属性与方法都有前缀$, 以便与代理的data属性区分。
var data = { a: 1 }
var vm = new Vue({
  el: '#container1',
  data: data
})
console.log(vm.$data === data) // true
console.log(vm.$el === document.getElementById('container1')) // true
data.a = 5;
// $watch 是一个实例方法
vm.$watch('a', function (newVal, oldVal) {
  // 这个回调将在 `vm.a`  改变后调用
  console.log(newVal);
  console.log(oldVal);
})

1-1. data 必须是函数
通过Vue构造器传入的各种选项大多数都可以在组件里用。 data 是一个例外,它必须是函数。 如下代码Vue 会停止,并在控制台会报错。



  
    
      演示Vue
    
    

data是函数解决该方案
代码如下:



  
    
      演示Vue
    
    

查看效果

由于这三个组件共享了同一个 data , 因此增加一个 counter 会影响所有组件!这不对。我们可以通过为每个组件返回全新的 data 对象来解决这个问题:
代码如下:



  
    
      演示Vue
    
    

查看效果

现在每个 counter 都有它自己内部的状态了.

回到顶部

2.理解组件的通信。

一般情况父子组件是这样的关系,组件A在它的模板中使用了组件B,他们之间必然需要相互通信,父组件要给子组件传递数据,子组件需要将它内部发生的事情告知父组件,为了保证父子组件的解耦,可维护性及可重用性。在vue.js中,父组件通过props向下传递数据给子组件,子组件通过events给父组件发送消息。

2-1 使用props传递数据
不能在子组件的模板内直接引用父组件的数据,要让子组件使用父组件的数据,我们需要通过子组件的props选项。
如下代码:



  
    
      演示Vue
    
    

结果在页面上会打印 hello。

查看效果

注意: HTML特性是不区分大小写的,所以当使用的不是字符串模板,camelCased(驼峰式) 命名的prop需要转换为相对应的 kebab-case(短横线隔开式)命名:
如下代码:



  
    
      演示Vue
    
    

2-2 理解动态prop
在模板中,要动态地绑定父组件的数据到子模板的props,使用v-bind,每当父组件的数据变化时,该变化会传递给子组件。


使用 v-bind 的缩写语法通常更简单:

代码如下:



  
    
      演示Vue
    
    

查看效果

回到顶部

3.理解自定义事件

父组件使用props传递数据给子组件,但是如果子组件需要把数据传回去的话,就需要自定义事件了;
3-1 使用v-on绑定自定义事件
每个vue实例都实现了事件接口,即:
1. 使用 $on(eventName) 监听事件
2. 使用 $emit(eventName) 触发事件
注意: $on 和 $emit 不是 addEventListener 和 dispatchEvent的别名。且 父组件可以在使用组件的地方直接用 v-on 来监听子组件触发的事件。
不能用$on侦听子组件抛出的事件,而必须在模板里直接用v-on绑定,就像以下的例子:



  
    
      演示Vue
    
    

{{ total }}

上面代码: 初始化时候 实例化设置 data: {total: 0}, 设置total为0, 子组件button-counter 默认为0, 当点击子组件的时候调用 increment方法,当前的counter自增1, 然后在子组件触发 $emit('increment')事件,当使用 v-on:increment 会监听到事件后,会调用父组件的incrementTotal方法,因此父组件也自增1.

查看效果

上面代码中 子组件已经和它外部完全解耦了。它所做的只是报告自己的内部事件,至于父组件是否关心则与它无关。

回到顶部

4.理解使用自定义事件的表单输入组件

自定义事件可以用来创建自定义的表单输入组件,使用v-modal来进行数据双向绑定。比如如下代码:

上面的代码是下面的语法糖;如下代码:

<input v-bind:value="something" v-on:input="something=$event.target.value" />

因此在创建组件中时,相当于下面的简写;如下代码:

<custom-input v-bind:value="something" v-on:input="something=arguments[0]">custom-input>

所以要让组件的v-model 生效,必须满足下面的条件:
1. 接受一个value属性。
2. 在有新的value时触发input事件。

如下测试代码:



  
    
      演示Vue
    
    

查看效果

回到顶部

5.单个slot 

标签中的任何内容都被视为 备用内容。备用内容在子组件的作用域内编译,并且只有在宿主元素为空,且没有插入的内容时才显示备用内容。
如果标签中有内容的话,就显示该内容。
比如 my-component 组件有如下代码:

this is a component

如果没有分发内容,则显示slot中的内容

asdsadsdad

父组件有如下代码:

Hello Vue.js

渲染后的结果为:

this is a component

Hello Vue.js

asdsadsdad

this is a component

如果没有分发内容,则显示slot中的内容

asdsadsdad

所有测试实例代码如下:



  
    
      演示Vue
    

    

Hello Vue.js

查看效果

回到顶部

6.具名slot 

元素可以用一个特殊的属性 name 来配置如何分发内容。多个 slot 可以有不同的名字。具名 slot 将匹配内容片段中有对应 slot 特性的元素。
如果没有默认的 slot ,这些找不到匹配的内容片段将被抛弃。
比如:假如有一个 my-component 组件,它的模板为:

父组件的模板如下:

这里可能是一个页面标题

主要内容的一个段落

另一个主要段落

这里是底部信息

页面渲染的结果如下:

这里可能是一个页面标题

主要内容的一个段落

另一个主要段落

这里是底部信息

所有的代码如下:



  
    
      演示Vue
    

    

这里可能是一个页面标题

主要内容的一个段落

另一个主要段落

这里是底部信息

查看效果

回到顶部

7.理解作用域插槽(2.1.0新增的) 

   在slot分发中,无论是单分发还是具名分发,都是父组件替换子组件的数据,或者没有替换,用子组件默认的数据。 但是通过设置作用域槽,就可以改变这种状况,让子组件可以在父组件进行分发时获取自己的数据,至于是什么数据,由子组件决定,这样就能解耦了。
作用域槽通过slot的一个自定义的属性,官方给出的DEMO是text,但也可以是其他,值为暴露的数据。 这个自定义属性已经存放在子组件的prop对象里了。等待着被父组件获取。
怎么获取呢? 在父组件的模板里,使用一个Vue自带的特殊组件