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