Vue的四种特殊attribute:is key ref v-slot (更新中)

Is的用法
<!DOCTYPE html>
<html>
  <head>
    <title>Dynamic Components Example</title>
    <script src="https://unpkg.com/vue"></script>
    <style>
      .tab-button {
        padding: 6px 10px;
        border-top-left-radius: 3px;
        border-top-right-radius: 3px;
        border: 1px solid #ccc;
        cursor: pointer;
        background: #f0f0f0;
        margin-bottom: -1px;
        margin-right: -1px;
      }
      .tab-button:hover {
        background: #e0e0e0;
      }
      .tab-button.active {
        background: #e0e0e0;
      }
      .tab {
        border: 1px solid #ccc;
        padding: 10px;
      }
    </style>
  </head>
  <body>
    <div id="dynamic-component-demo" class="demo">
      <button
        v-for="tab in tabs"
        v-bind:key="tab"
        v-bind:class="['tab-button', { active: currentTab === tab }]"
        v-on:click="currentTab = tab"
      >
        {{ tab }}
      </button>

      <component v-bind:is="currentTabComponent" class="tab"></component>
    </div>

    <script>
      Vue.component("tab-home", {
        template: "<div>Home component</div>"
      });
      Vue.component("tab-posts", {
        template: "<div>Posts component</div>"
      });
      Vue.component("tab-archive", {
        template: "<div>Archive component</div>"
      });

      new Vue({
        el: "#dynamic-component-demo",
        data: {
          currentTab: "Home",
          tabs: ["Home", "Posts", "Archive"]
        },
        computed: {
          currentTabComponent: function() {
            return "tab-" + this.currentTab.toLowerCase();
          }
        }
      });
    </script>
  </body>
</html>

解析 DOM 模板时的注意事项
有些 HTML 元素,诸如 <ul>、<ol>、<table> 和 <select>,对于哪些元素可以出现在其内部是有严格限制的。而有些元素,诸如 <li>、<tr> 和 <option>,只能出现在其它某些特定的元素内部。

这会导致我们使用这些有约束条件的元素时遇到一些问题。例如:

<table>
  <blog-post-row></blog-post-row>
</table>
这个自定义组件 <blog-post-row> 会被作为无效的内容提升到外部,并导致最终渲染结果出错。幸好这个特殊的 is attribute 给了我们一个变通的办法:

<table>
  <tr is="blog-post-row"></tr>
</table>
需要注意的是如果我们从以下来源使用模板的话,这条限制是不存在的:

字符串 (例如:template: '...')
单文件组件 (.vue)
<script type="text/x-template">

  

ref的用法

  1、ref 加在普通的元素上,用this.ref.name 获取到的是dom元素

  2、ref 加在子组件上,用this.ref.name 获取到的是组件实例,可以使用组件的所有方法。

  3、如何利用 v-for 和 ref 获取一组数组或者dom 节点

  4.官方文档说,$refs不是响应式的,但是$refs.aa是响应式的,我们去监听$refs,是监听不到变化的

注意点:

       1、ref 需要在dom渲染完成后才会有,在使用的时候确保dom已经渲染完成。比如在生命周期 mounted(){} 钩子中调用,或者在 this.$nextTick(()=>{}) 中调用。在生命周期mounted之前的钩子函数中去调用           会获取不到,原因是DOM节点都没有生成this.refs的组件在v-if为false的父节点下,导致这个子组件未渲染,所以获取不到。组件已经渲染成功才能调用组件的数据。而不是页面加载完成后就一定能获取到

  2、如果ref 是v-for循环出来的,有多个重名,那么ref的值会是一个数组 ,此时要拿到单个的ref 只需要循环就可以了

  比如: <Form v-for="item in list" ref="form"></Form> 这种情况,你可以直接遍历form,然后操作。

  也可以 <Form v-for="item in list" :ref="'form'+item.key"></Form> ,然后取值的时候遍历list,

   this.list.forEach((item,index) => {

      this.$refs['form'+index][0]; //注意:这里要加个[0],因为v-for生成的ref都是数组

    })

 

key的用法

有相同父元素的子元素必须有独特的 key。重复的 key 会造成渲染错误。(这里是重点,同一个.vue文件中,不是所有Key重复都会报错)

最常见的用例是结合 v-for

<ul>
  <li v-for="item in items" :key="item.id">...</li>
</ul>

它也可以用于强制替换元素/组件而不是重复使用它。当你遇到如下场景时它可能会很有用:

  ①完整地触发组件的生命周期钩子

  ②触发过渡

拓展:如果没有key,会带来性能问题。比如一个数组三个元素,从最前面或中间插入一个元素时,dom会重新渲染这个元素后面的所有元素。但如果有key的话,就只会渲染新插入的元素。而使用数组的index作为key的话,会带来一个问题,但这个问题并不常见。需要满足被遍历的标签内有input输入框并且这个输入框没有被绑定任何值。这时候改变数组的话,input标签和输入的内容都会被复用,数据就会发生错乱。总的来说,不加key和使用index作为key的效果是一样的。都会带来一些问题,下面的参考文档代码那里不用key的时候,数组列表的顺序也会错乱。

  vue官方文档关于v-if的key的说明,也是基于输入框没有被:value或v-model绑定任何值,才会有切换时内容不清空的现象。link

  一般来说,只有同时满足以下三种情况,才会选择使用index作为key。

  ①列表和项目是静态的,它们不会计算,也不会更改  ②列表中的项目没有id  ③该列表永远不会被重新排序或过滤

  参考文档  参考文档代码

  而且不能用Math.random()来作为key,不然旧节点会被全部删掉,新节点重新创建,还不如不加

 

v-slot
详情看官方文档https://cn.vuejs.org/v2/api/#v-slot
注意:① v-slot只能用在template标签或者只有一个默认插槽的组件标签上 ② v-slot:aa可以简写成 #aa
posted @ 2021-08-19 16:42  太阳锅锅  阅读(212)  评论(0编辑  收藏  举报