# vue编码但不渲染的标签
vue下载包
vue i -s vue-fragment
在main.js里添加代码
import Fragment form 'vue-fragment';
Vue.use(Fragment.Plugin)
在文件里就可以直接使用<fragment>元素了
<template>
<fragment>
<div>test</div>
</fragment>
</template>
最终渲染结果就只有div一种元素了
<div>test</div>
用fragment这个技术的原因,主要是为了把fragment当成根节点,然后循环template标签
因为vue默认的template不能在根节点循环,但我又不想在去渲染多余的标签
这个问题我在循环element NavMenu导航菜单时发现的
<template>
<!-- fragment 在此做根节点 页面不渲染此标签-->
<fragment>
<template v-for="(item,index) in list"></template>
</fragment>
</template>
# Vue3学习笔记之Fragment和Emits
# Fragments
Fragments作为vue3的新特性之一,允许一个vue组件可以有多个根节点。创建一个如下的组件,vue3中开箱即用
<template>
<header>...</header>
<main v-bind="attrs">...</main>
<footer></footer>
</template>
相比于vue3, vue2规定创建一个vue组件,只能有一个根节点,在vue2中创建如上一个vue组件,会报如下错误
Errors compiling template:
Component template should contain exactly one root element.
原因是代表任何组件的vue实例需要绑定到一个单一的DOM元素中。唯一可以创建一个具有多个DOM节点的组件的方法就是创建一个没有底层Vue实例的功能组件
目前可以在vue2中使用vue-fragments库使用Fragments
Fragments用起来像一个普通的DOM元素,但它是虚拟的,根本不会在DOM树中呈现。这样我们就可以将组件功能绑定到一个单一的元素中,而不需要创建一个多余的DOM节点
# Emit Component option
Vue3中组件发送的自定义事件需要定义在emits选项中
若自定义事件名与原生事件冲突,比如'click',倘若没有emits选项中的设置,则会有触发两次事件的坑
更好的指示组件工作方式
<template> <button @click="$emit('click')"> 自定义事件 </button> </template> <script> import { defineComponent } from 'vue'; export default defineComponent({ emits: ['click'] // 此处与原生事件名冲突,若没有设置,则点击会触发两次,一次为自定义事件,一次为原生事件 }) </script>注意:尽量避免自定义事件名与原生事件名冲突
参数有两种形式对象和数组,对象里面可以配置带校验函数的事件,为null表示不校验,校验函数将接收传递给$emit 调用的其他参数,如`$emit('event', 1)被调用,event事件对应的校验函数接收参数1,返回布尔值,表示事件参数是否有效
// search-btn组件
<template>
<a-button @click="onReset">
重置
</a-button>
<a-button
type="primary"
@click="onSearch"
>
搜索
</a-button>
</template>
<script lang="ts">
import { defineComponent } from 'vue';
export default defineComponent({
name: 'search-btn',
emits: {
// 没有校验函数
reset: null,
// 带校验函数
search: playload 为子组件向父组件传的值 => {
// playload 为子组件向父组件传的值
if (playload) {
// 校验通过
return true;
} else {
// 校验不通过
return false;
}
}
},
setup(props, { emit }) {
const onReset = () => {
emit('reset');
};
const onSearch = () => {
emit('search');
};
return {
onSearch
};
}
});
</script>
// 父组件 index.vue
<search-btn @reset="onReset" @search="onSearch" />
// js核心代码
const onSearch = () => {
console.log('执行外部的事件')
}
注意:校验不通过的时候,控制台会输出一个警告,但是emits事件会继续执行。
这里有个坑,一开始理解以为是校验不通过就拦截,不执行外部组件的方法,但经过测试,发现还是会继续执行,只是输出一个警告,所以个人认为这个校验函数还是比较鸡肋
# 思考
问题一:vue2为什么不引入Fragments? (opens new window)
根据Vue贡献者的说法,vue2限制组件只能有一个根节点, 主要原因是虚拟DOM diff算法依赖于具有单个根的组件,如果允许Fragments需要对该算法进行重大更改,不仅要使其正常工作,而且必须使其具有高性能,这是一项非常艰巨的任务。

划重点,vue2不引入主要是diff算法的缘故,
问题二:vue3引入Fragments,diff算法是否变化?渲染机制是否改变?
TODO: diff算法理解。
# 资料
Vue.js 中的片段 (opens new window)