vue深入组件
组件注册
局部注册
如果将全部组件全局注册的话,尽管不适用这个组件,使用webpack等工具构建系统后仍然会包含在构建的结果中,增加了下载量
可以通过局部注册解决
直接在js中
//局部注册 var component1 = { data: function () { return { count: 0 } }, template: ' <button @click="count++">你点了 {{count}}次 </button>' }
然后再vue实例中
var app = new Vue({ el: '#app', components: { 'componentOne': component1 }, })
Prop
prop类型
常见的字符串形式:
prop:['title','like','isPublish']
如果想给给个prop指定值类型,可以用数组形式
props: { title: String, likes: Number, isPublished: Boolean, commentIds: Array, author: Object, callback: Function, contactsPromise: Promise // or any other constructor } //接受错误时还可以从控制台提示给用户错误
prop传值
静态的值:
<!--可以直接在组件中写属性名和值--> <blog-post title="My journey with Vue"></blog-post> <!--这里的title是prop中的名,后面跟着的是值-->
动态的值:
需要用到v-bind
<!-- 动态赋予一个变量的值 --> <blog-post v-bind:title="post.title"></blog-post> <!-- 动态赋予一个复杂表达式的值 --> <blog-post v-bind:title="post.title + ' by ' + post.author.name" ></blog-post>
单向数据流
所有的 prop 都使得其父子 prop 之间形成了一个单向下行绑定:父级 prop 的更新会向下流动到子组件中,但是反过来则不行
每次父级组件发生变更时,子组件中所有的 prop 都将会刷新为最新的值。
不应该在子组件内部更改prop的值,如果需要使用变更的prop值得话可以有一下处理
//1.prop传递一个初始值,子组件中将其保存为一个本地data数据 props:['initialCounter'], data:function(){ return { counter : this.initialCounter } }
//2.这个prop以一种原始值传入,且需要进行转换。则利用计算属性 props: ['size'], computed: { normalizedSize: function () { return this.size.trim().toLowerCase() } }
插槽
插槽内容
插槽允许这样组合
//注册组件 Vue.component('achacao', { template: '<div>这是子元素中得内容:: <slot></slot></div>' })
<!--调用组件--> <achacao> 我是插槽得内容 <button>可以在这里添加各种模板代码,包括html</button> </achacao>
插槽作用域
父级模板里的所有内容都是在父级作用域中编译的;子模板里的所有内容都是在子作用域中编译的。
如果写了
<achacao> 插槽作用域: message(父组件中得数据):{{message}} <!-- subMessage:{{subMessage}} --> </achacao>
那么这个message对应的是父组件中的数据,而不是该子组件中的数据
后备内容
插槽的后背内容相当于就是默认内容,会在父组件中没写内容时应用
如:
<!--父组件中没有插槽内容--> <submit-button></submit-button>
<!--子组件中加入默认内容--> <button type="submit"> <slot>Submit</slot> </button>
slot标签中的就是默认内容
具名插槽
当需要多个插槽是,我们可以这样使用
Vue.component('base-layout', { template: `<div class="container"> <header> <!-- 我们希望把页头放这里 --> <slot name='header'></slot> </header> <main> <!-- 我们希望把主要内容放这里 --> <slot name='mian'></slot> </main> <footer> <!-- 我们希望把页脚放这里 --> <slot name='footer'></slot> </footer> </div>`, })
在子组件中这样定义
<slot name='***'></slot>
<base-layout> <template v-slot:header> <h1>这是header插槽</h1> </template> <template v-slot:mian> <h1>这是main插槽</h1> </template> <template v-slot:footer> <h1>这是footer插槽</h1> </template> </base-layout> <!--下面是缩写形式--> <base-layout> <template #header> <h1>这是header插槽</h1> </template> <template #mian> <h1>这是main插槽</h1> </template> <template #footer> <h1>这是footer插槽</h1> </template> </base-layout>
父组件中通过
<template v-slot:***>内容<template>
这样来定义使用多个具名插槽跟
v-on
和v-bind
一样,v-slot
也有缩写,即把参数之前的所有内容 (v-slot:
) 替换为字符#
。例如v-slot:header
可以被重写为#header
: