vue——(key、ref、 slot、 slot-scope、 scope、 is)介绍及用法

1.key

key 的特殊属性主要用在 Vue 的虚拟 DOM 算法,在新旧 nodes 对比时辨识 VNodes。如果不使用 key,Vue 会使用一种最大限度减少动态元素并且尽可能的尝试修复/再利用相同类型元素的算法。使用 key,它会基于 key 的变化重新排列元素顺序,并且会移除 key 不存在的元素。
有相同父元素的子元素必须有独特的 key。重复的 key 会造成渲染错误。
最常见的用例是结合 v-for:

  • ...

它也可以用于强制替换元素/组件而不是重复使用它。当你遇到如下场景时它可能会很有用:
完整地触发组件的生命周期钩子
触发过渡
例如:


  {{ text }}

当 text 发生改变时, 会随时被更新,因此会触发过渡。
1.v-if 用 key 管理可复用的元素
Vue 会尽可能高效地渲染元素,通常会复用已有元素而不是从头开始渲染。这么做,除了使 Vue 变得非常快之外,还有一些有用的好处。例如,如果你允许用户在不同的登录方式之间切换:

  
  

那么在上面的代码中切换 loginType 将不会清除用户已经输入的内容。因为两个模版使用了相同的元素, 不会被替换掉——仅仅是替换了它的 placeholder。
这样也不总是符合实际需求,所以 Vue 为你提供了一种方式来声明“这两个元素是完全独立的——不要复用它们”。只需添加一个具有唯一值的 key 属性即可:

  

现在,每次切换时,输入框都将被重新渲染。注意,

2.v-for中的key
当 Vue.js 用 v-for 正在更新已渲染过的元素列表时,它默认用 “就地复用” 策略。如果数据项的顺序被改变,Vue将不是移动 DOM 元素来匹配数据项的顺序, 而是简单复用此处每个元素,并且确保它在特定索引下显示已被渲染过的每个元素。
这个默认的模式是有效的,但是只适用于不依赖子组件状态或临时 DOM 状态(例如:表单输入值)的列表渲染输出。
为了给 Vue 一个提示,以便它能跟踪每个节点的身份,从而重用和重新排序现有元素,你需要为每项提供一个唯一 key 属性。理想的 key 值是每项都有唯一 id。

建议尽可能使用 v-for 来提供 key ,除非迭代 DOM 内容足够简单,或者你是故意要依赖于默认行为来获得性能提升。因为它是 Vue 识别节点的一个通用机制, key 并不特别与 v-for 关联,key 还具有其他用途,我们将在后面的指南中看到其他用途。

2.ref

ref 被用来给元素或子组件注册引用信息。引用信息将会注册在父组件的 $refs 对象上。如果在普通的 DOM 元素上使用,引用指向的就是 DOM 元素;如果用在子组件上,引用就指向组件实例:


hello

当 v-for 用于元素或组件的时候,引用信息将是包含 DOM 节点或组件实例的数组。
关于 ref 注册时间的重要说明:因为 ref 本身是作为渲染结果被创建的,在初始渲染的时候你不能访问它们 - 它们还不存在!$refs 也不是响应式的,因此你不应该试图用它在模板中做数据绑定。
例子1

//如template里使用购物车组件
 
//methods里就能使用refs来指向购物车组件的实例,比如定义在购物车组件里的drop()方法就能被调用:
this.$refs.shopcart.drop(target);

例子2

例子3

//一、ref使用在外面的组件上

ref在外面的组件上

var refoutsidecomponentTem={ template:"
我是子组件
" }; var refoutsidecomponent=new Vue({ el:"#ref-outside-component", components:{ "component-father":refoutsidecomponentTem }, methods:{ consoleRef:function () { console.log(this); // #ref-outside-component vue实例 console.log(this.$refs.outsideComponentRef); // div.childComp vue实例 } } }); //二、ref使用在外面的元素上

ref在外面的元素上

var refoutsidedomTem={ template:"
我是子组件
" }; var refoutsidedom=new Vue({ el:"#ref-outside-dom", components:{ "component-father":refoutsidedomTem }, methods:{ consoleRef:function () { console.log(this); // #ref-outside-dom vue实例 console.log(this.$refs.outsideDomRef); //

ref在外面的元素上

} } }); //三、ref使用在里面的元素上---局部注册组件

ref在里面的元素上

var refinsidedomTem={ template:"
" + "
我是子组件
" + "
", methods:{ consoleRef:function () { console.log(this); // div.childComp vue实例 console.log(this.$refs.insideDomRef); //
我是子组件
} } }; var refinsidedom=new Vue({ el:"#ref-inside-dom", components:{ "component-father":refinsidedomTem } }); //ref使用在里面的元素上---全局注册组件
Vue.component("ref-inside-dom-quanjv",{ template:"
" + "" + "

ref在里面的元素上--全局注册

" + "
", methods:{ showinsideDomRef:function () { console.log(this); //这里的this其实还是div.insideFather console.log(this.$refs.insideDomRefAll); // } } }); var refinsidedomall=new Vue({ el:"#ref-inside-dom-all" });

3.slot

用于标记往哪个具名插槽中插入子组件内容。
1.匿名slot使用

//定义组件my-component
//使用方法

我就是slot的替代内容,这里可以放任何标签元素,即使是一长串ul>li列表

2.具名slot使用

//定义组件my-component
//使用方法

我就是这个叫mySlot的slot替代内容,这里可以放任何标签元素,即使是一长串ul>li列表,但是我是一个有名字的宝宝,所以你必须给我加上slot="mySlot",不然我就报错给你看!

4.slot-scope

2.5.0 新增
用于将元素或组件表示为作用域插槽。特性的值应该是可以出现在函数签名的参数位置的合法的 JavaScript 表达式。这意味着在支持的环境中,你还可以在表达式中使用 ES2015 解构。它在 2.5.0+ 中替代了 scope。
此属性不支持动态绑定。
最后,就是我们的作用域插槽。这个稍微难理解一点。官方叫它作用域插槽,实际上,对比前面两种插槽,我们可以叫它带数据的插槽。什么意思呢,就是前面两种,都是在组件的template里面写

匿名插槽

具名插槽

但是作用域插槽要求,在slot上面绑定数据。也就是你得写成大概下面这个样子。


 export default {
    data: function(){
      return {
        data: ['zhangsan','lisi','wanwu','zhaoliu','tianqi','xiaoba']
      }
    },
}

我们再来对比,作用域插槽和单个插槽和具名插槽的区别,因为单个插槽和具名插槽不绑定数据,所以父组件是提供的模板要既包括样式由包括内容的,上面的例子中;而作用域插槽,父组件只需要提供一套样式(在确实用作用域插槽绑定的数据的前提下)。
下面的例子,你就能看到,父组件提供了三种样式(分别是flex、ul、直接显示),都没有提供数据,数据使用的都是子组件插槽自己绑定的那个人名数组。
父组件


子组件:



 export default {
    data: function(){
      return {
        data: ['zhangsan','lisi','wanwu','zhaoliu','tianqi','xiaoba']
      }
    }
}

5.scope

用于表示一个作为带作用域的插槽的