>[success] # 动态组件 -- is
1. `component` 标签和`is` 属性进行搭配可以实现动态组件
2. 使用 html的 tag 标签想渲染 `vue` 组件 `is`attribute 的值中加上`vue:`,因为`web componet` 中 `is ` 是一个特殊的属性因此在vue3 不在像 2 一样可以在普通tag 标签上使用`is`
3. `v-is` 作为三系列的新指令标签在`vue3.1`已经被废弃了
4. `is` 不仅仅可以渲染是`vue `组件也可以是 类似`input `这种原生元素
>[danger] ##### 案例
![](https://img.kancloud.cn/4b/37/4b37f91945f32f300670491fb6321aba_514x245.png)
* [案例](https://sfc.vuejs.org/#eNqlVUtPFEEQ/ivFXEYjsxP1Nu4Sn4kHTTx4czjMzvTCwE7PprtngWxIMMEXiph4gotoQiQxaqKJIYHon9mdhX9h9WMeoAiJB9ip6urvq/q6unpg3ej1Gv2MWJ7V5CGLe2LKp3HSS5mAu2lCoMPSBOyGKw0ZaJfLD1IueLmurOMBN1g4G/crCGObIACfkkUVGJFOkHUFDKQ3THE3JVRwTztAJTKpPxWN+TZ40lhWrigQwYWLxS5GRMZoYSFwxhjCPgzaHtgS0jY4ACJoI9sj4wVbscgPQ2FP68hlxeVT9Sv/XBfy77ujp68WSFtljgTj/dXh/g9VSjfgHB7gfxGHNzMhUgpkURAacbj78P497brTJQluK6qnXLAsFCmrKuFZj6B5TVtiNuYNLpa6pNEOwvkZlmY0ghb4FiORb/m0FhZE0Z0+gt+LOdIiiG+F3Tic961JQPzWVCUPlnKbBQvA1akHNFyCAE8yELHMutMhoeATpZaYZooJdNOZC5evXL1o5NEpVgKFGRdpYgrkDTznmBLMoaclcdpKAJnMMZEmYVDo5GFZRZTGb7pln6IhSIJggqAF0Izivha95VsRSVLfUn5cMRgmfeg7nZRhEB48xFSdv1TOrHrzZEkv1p0F8CMbF0zq2CMDCEKBPeLVGgxarZYEheXpGsJ1JT0i1ANlWBljsgUYDPR2pSOm72q6opoJxzn8tTn+uD5a281XHucvD/LXO8O99eHB1uGHT/net/zdW8eRCgmjihfL1G28ep59qeJHUYuyVB5TTRejazT55pejla3x1qoIZiDffjb+/HO0tj3cW5NIMHqxPj5YGW18He7vaFZ0g74Ax/kVvdwjr9iZrOUMgKMn66M3z3E71FkUtgquIhWDRke80v+fqFq3umB/Aa8ooJgDerfGzXffjw42KnR9ljrhkzdh6pbsEbhPJmpnrnrbSNR0ay3vU2vS0tPWSYJeY46nFCe5utO+WcDGLgepOgJp+9asED3uuS7vhHIgz/FGymZc/GqwjIoYhz3hidNm6QInDIHxktYwXHT2CXNQlYgwwv6FeSL0D9xiZGApxSMjX6PTb7bumeppqAQ/RShELp+n80Pr9+0c2LV37fzoxeN4Jv7ybxletSw=)
~~~html
<script>
import Home from './Home.vue'
import Posts from './Posts.vue'
import Archive from './Archive.vue'
export default {
components: {
Home,
Posts,
Archive
},
data() {
return {
currentTab: 'Home',
tabs: ['Home', 'Posts', 'Archive']
}
}
}
// 注册web compent组件
class PlasticButton extends HTMLButtonElement {
constructor() {
super();
this.style.background = "red"
this.addEventListener("click", () => {
// Draw some fancy animation effects!
console.log(123)
});
}
}
customElements.define("plastic-button", PlasticButton, { extends: "button" });
</script>
<template>
<div class="demo">
<button
v-for="tab in tabs"
:key="tab"
:class="['tab-button', { active: currentTab === tab }]"
@click="currentTab = tab"
>
{{ tab }}
</button>
<!--这种动态拼接不会被渲染-->
<div :is="'vue:'+currentTab" class="tab"></div>
<!--普通的tag 标签加上vue: 前缀可以渲染vue 组件-->
<div is="vue:Home" class="tab"></div>
<!--component 配合 is 可以渲染-->
<component is="Home"></component>
<!--component 配合 is 可以渲染-->
<component :is="currentTab"></component>
<!-- web component 渲染模式-->
<button is="plastic-button">Click Me!</button>
</div>
</template>
~~~
>[danger] ##### v-model 在使用上区别
如果在`<component>`标签上使用`v-model`,模板编译器会将其扩展为`modelValue`prop 和`update:modelValue`事件监听器,就像对任何其他组件一样。但是,这与原生 HTML 元素不兼容,例如`<input>`或`<select>`。因此,在动态创建的原生元素上使用`v-model`将不起作用,**可以手动将`v-model`拆分为 attribute 和事件**
~~~
<script setup>
import { ref } from 'vue'
const tag = ref('input')
const username = ref('')
</script>
<template>
<!-- 由于 'input' 是原生 HTML 元素,因此这个 v-model 不起作用 -->
<component :is="tag" v-model="username" />
</template>
~~~
>[info] ## 官网对应位置
[is](https://cn.vuejs.org/api/built-in-special-attributes.html#ref)
[# 内置特殊元素](https://cn.vuejs.org/api/built-in-special-elements.html)
[## 动态组件](https://cn.vuejs.org/guide/essentials/component-basics.html#dynamic-components)
- 官网给的工具
- 声明vue2 和 vue3
- 指令速览
- Mustache -- 语法
- v-once -- 只渲染一次
- v-text -- 插入文本
- v-html -- 渲染html
- v-pre -- 显示原始的Mustache标签
- v-cloak -- 遮盖
- v-memo(新)-- 缓存指定值
- v-if/v-show -- 条件渲染
- v-for -- 循环
- v-bind -- 知识
- v-bind -- 修饰符
- v-on -- 点击事件
- v-model -- 双向绑定
- 其他基础知识速览
- 快速使用
- 常识知识点
- key -- 作用 (后续要更新)
- computed -- 计算属性
- watch -- 侦听
- 防抖和节流
- vue3 -- 生命周期
- vue-cli 和 vite 项目搭建方法
- vite -- 导入动态图片
- 组件
- 单文件组件 -- SFC
- 组件通信 -- porp
- 组件通信 -- $emit
- 组件通信 -- Provide / Inject
- 组件通信 -- 全局事件总线mitt库
- 插槽 -- slot
- 整体使用案例
- 动态组件 -- is
- keep-alive
- 分包 -- 异步组价
- mixin -- 混入
- v-model-- 组件
- 使用计算属性
- v-model -- 自定义修饰符
- Suspense -- 实验属性
- Teleport -- 指定挂载
- 组件实例 -- $ 属性
- Option API VS Composition API
- Setup -- 组合API 入口
- api -- reactive
- api -- ref
- 使用ref 和 reactive 场景
- api -- toRefs 和 toRef
- api -- readonly
- 判断性 -- API
- 功能性 -- API
- api -- computed
- api -- $ref 使用
- api -- 生命周期
- Provide 和 Inject
- watch
- watchEffect
- watch vs. watchEffect
- 简单使用composition Api
- 响应性语法糖
- css -- 功能
- 修改css -- :deep() 和 var
- Vue3.2 -- 语法
- ts -- vscode 配置
- attrs/emit/props/expose/slots -- 使用
- props -- defineProps
- props -- defineProps Ts
- emit -- defineEmits
- emit -- defineEmits Ts
- $ref -- defineExpose
- slots/attrs -- useSlots() 和 useAttrs()
- 自定义指令
- Vue -- 插件
- Vue2.x 和 Vue3.x 不同点
- $children -- 移除
- v-for 和 ref
- attribute 强制行为
- 按键修饰符
- v-if 和 v-for 优先级
- 组件使用 v-model -- 非兼容
- 组件
- h -- 函数
- jsx -- 编写
- Vue -- Router
- 了解路由和vue搭配
- vueRouter -- 简单实现
- 安装即使用
- 路由懒加载
- router-view
- router-link
- 路由匹配规则
- 404 页面配置
- 路由嵌套
- 路由组件传参
- 路由重定向和别名
- 路由跳转方法
- 命名路由
- 命名视图
- Composition API
- 路由守卫
- 路由元信息
- 路由其他方法 -- 添加/删除/获取
- 服务器配置映射
- 其他
- Vuex -- 状态管理
- Option Api -- VUEX
- composition API -- VUEX
- module -- VUEX
- 刷新后vuex 数据同步
- 小技巧
- Pinia -- 状态管理
- 开始使用
- pinia -- state
- pinia -- getter
- pinia -- action
- pinia -- 插件 ??
- Vue 源码解读
- 开发感悟
- 练手项目