Vue3复习和总结(Component)组件v-model参数和动态组件和Attribute 继承
Vue3复习和总结(Component)组件v-model参数和动态组件和Attribute 继承
代码全部放在->github仓库:https://github.com/zyugat/vue-review-all
前言:分为base、Component、router、Vuex、组合式API。5个部分。
base和Component中的例子不使用脚手架运行,需自行浏览器运行。位置->noCli
组件v-model参数和动态组件和Attribute 继承
- Vue3复习和总结(Component)组件v-model参数和动态组件和Attribute 继承
- 组件v-model参数
- 动态组件
- Attribute 继承
组件v-model参数
需求:通过props将数据传递给子组件,保持数据的响应性。
思路:通过
v-model
绑定Props值传递给子组件,子组件通过自定义事件emit
修改。
默认情况下,组件上的 v-model
使用 modelValue
作为 prop 和 update:modelValue
作为事件。我们可以通过向 v-model
传递参数来修改这些名称:
绑定的方法:v-model:propname="xxx"
抛出的事件名 update:propname
结构,前面uptede是固定是。
1、父组件通过v-model绑定props:v-model:my-name="myName1"
2、子组件中接受 props 值 myName
。
3、组件输入框 input 发送自定义事件。当值被改变时把值发出去。
<div id="app">
<!-- 第一步 -->
<user-name v-model:my-name="myName1"></user-name>
<p>myName: {{ myName1 }}</p>
</div>
<script>
const app = Vue.createApp({
data() {
return {
myName1: '123',
}
},
})
app.component('user-name', {
// 第二步
props: {
myName: String,
},
// 声明自定义事件
emits: ['update:myName'],
// 第三步
template: `
<input
type="text"
:value="myName"
@input="$emit('update:myName', $event.target.value)">
`,
})
app.mount('#app')
</script>
动态组件
在动态组件上使用keep-alive
可以使组件实例被缓存。
1、新建三个组件:tab-home、tab-posts、tab-archive
2、通过计算属性拼接属性名:currentTabComponent() {}
3、通过点击按钮切换组件名
4、通过:is=""
选择显示的组件
<div id="dynamic-component-demo" class="demo">
<button
v-for="tab in tabs"
:key="tab"
:class="['tab-button', { active: currentTab === tab }]"
@click="currentTab = tab"
>
{{ tab }}
</button>
<!-- Inactive components will be cached! -->
<keep-alive>
<component :is="currentTabComponent"></component>
</keep-alive>
</div>
<script>
const app = Vue.createApp({
data() {
return {
currentTab: 'Home',
tabs: ['Home', 'Posts', 'Archive'],
}
},
computed: {
currentTabComponent() {
return 'tab-' + this.currentTab.toLowerCase()
},
},
})
app.component('tab-home', {
template: `<div class="demo-tab">Home component</div>`,
})
app.component('tab-posts', {
template: `<div class="demo-tab">Posts component</div>`,
})
app.component('tab-archive', {
template: `<div class="demo-tab">Archive component</div>`,
})
app.mount('#dynamic-component-demo')
</script>
Attribute 继承
效果:组件数据不使用props接收,将这些数据将作为属性绑定到HTML元素中。
- 问题1、
inheritAttrs: false
:如果你不希望组件的根元素继承 attribute,就在选项中设置。- 当你关闭继承后,如果想要将所有 prop attribute 应用于别的元素,而不是根元素,可以使用:
v-bind="$attrs"
- 当你关闭继承后,如果想要将所有 prop attribute 应用于别的元素,而不是根元素,可以使用:
<!-- 如果不关闭则会变成这样, 根元素继承所有属性 -->
<div mydata="test" class="my-class" id="custom-layout">
<h2>father</h2>
</div>
<!-- 当关闭后,给h2标签绑定 $attrs -->
<h2 v-bind="$attrs">father</h2>
<div>
<h2 mydata="test" class="my-class" id="custom-layout">father</h2>
</div>
-
问题2、
$attrs
包含什么?- 包含父作用域中不作为组件 props 或自定义事件的 attribute 绑定和事件,包括
class
和style
。当一个组件没有声明任何 prop 时,这里会包含所有父作用域的绑定。v-bind="$attrs"
- 包含父作用域中不作为组件 props 或自定义事件的 attribute 绑定和事件,包括
-
问题3、当存在父组件传递 Props 后
- 当组件没有接收 Props,那么Props 会存在于
$attrs
中。 - 当组件接收 Props,那么 Props 不会存在于
$attrs
中,而存在于$props
中。
- 当组件没有接收 Props,那么Props 会存在于
-
问题4、如果我传递的属性中存在 方法的调用
- 例如我给父组件绑定了点击事件
@click="show"
,虽然没有在attrs中显示,但是他是存在的。 - 例如:下面案例中,我点击
father
child
text
,是会触发控制台输出的。然而点击$attrs
、$props
是不会有反应的,因为我没有给他们绑定v-bind="$attrs"
。
- 例如我给父组件绑定了点击事件
<style>
.my-class{
color:red
}
</style>
<div id="app">
<grandfather />
</div>
<script>
const App = {}
const app = Vue.createApp(App)
app.component('grandfather', {
// inheritAttrs: false,
data() {
return {
test: 'test',
}
},
methods: {
show() {
console.log('1111')
},
},
template: `
<div>
<h2>grandfather</h2>
<father :myData="test" class="my-class" id="custom-layout"
@click="show"></father>
</div>
`,
// father组件
components: {
father: {
inheritAttrs: false,
template: `
<div>
<h2 v-bind="$attrs">father</h2>
<p>$attrs: {{ $attrs }}</p>
<p>$props:{{ $props }}</p>
<child v-bind="$attrs"></child>
</div>
`,
// child组件
components: {
child: {
props: ['myData'],
template: `
<div>
<h2>child</h2>
<p>{{ myData }}</p>
</div>
`,
},
},
},
},
})
app.mount('#app')
</script>