Open jiaozitang opened 6 years ago
全局注册组件 它们在注册之后可以用在任何新创建的 Vue 根实例 (new Vue) 的模板中。 在所有子组件中也是如此,也就是说这三个组件在各自内部也都可以相互使用。 全局注册的行为必须在根 Vue 实例 (通过 new Vue) 创建之前发生。
Vue.component("my-nav1",{})
Vue.component("my-nav2",{})
Vue.component("my-nav3",{})
<my-nav1></my-nav1>
<my-nav2></my-nav2>
<my-nav3></my-nav3>
例子:https://github.com/tang119/Vuejs-note/blob/master/components/Quanju.vue
局部注册组件 局部注册的组件在其子组件中不可用
var myNav1 = {};
new Vue({
components:{myNav1}
})
大小写 HTML 中的特性名是大小写不敏感的,所以浏览器会把所有大写字符解释为小写字符。
/*在js中的props是camelCase的*/
props: ['postTitle'],
<!-- 在 HTML 中是 kebab-case 的 -->
<blog-post post-title="hello!"></blog-post>
Prop 类型 可以以对象形式列出 prop,这些属性的名称和值分别是 prop 各自的名称和类型
props: ['title', 'likes', 'isPublished', 'commentIds', 'author'];//字符串数组形式
props: {
title: String,
likes: Number,
isPublished: Boolean,
commentIds: Array,
author: Object
};//对象形式
传递静态或动态 Prop
<v-model :val="val"></v-model>//传入一个字符串变量
<v-model v-bind="obj"></v-model>/传入val对象的所有属性等同于下面这行
<v-model :id="obj.id" :name="obj.name" ></v-model>
data(){
return{
val:"123",
obj:{
id:1,
name:"tangjiao"
}
单向数据流 1.这个 prop 用来传递一个初始值;这个子组件接下来希望将其作为一个本地的 prop 数据来使用。在这种情况下,最好定义一个本地的 data 属性并将这个 prop 用作其初始值:
props: ['initialCounter'],
data: function () {
return {
counter: this.initialCounter
}
}
2.这个 prop 以一种原始的值传入且需要进行转换。在这种情况下,最好使用这个 prop 的值来定义一个计算属性:
props: ['size'],
computed: {
normalizedSize: function () {
return this.size.trim().toLowerCase()
}
}
注意:在 JavaScript 中对象和数组是通过引用传入的,所以对于一个数组或对象类型的 prop 来说,在子组件中改变这个对象或数组本身将会影响到父组件的状态。
Prop 验证 为了定制 prop 的验证方式,你可以为 props 中的值提供一个带有验证需求的对象,而不是一个字符串数组。
替换/合并已有的特性
模板中:<input type="date" class="form-control">
父组件中引入时<bootstrap-date-input
data-date-picker="activated"
class="date-picker-theme-dark"
></bootstrap-date-input>
对于绝大多数特性来说,从外部提供给组件的值会替换掉组件内部设置好的值。所以如果传入 type="text" 就会替换掉 type="date" 并把它破坏!庆幸的是,class 和 style 特性会稍微智能一些,即两边的值会被合并起来,从而得到最终的值:form-control date-picker-theme-dark。
禁用特性继承 如果你不希望组件的根元素继承特性,你可以设置在组件的选项中设置 inheritAttrs: false。例如:
Vue.component('my-component', {
inheritAttrs: false,
// ...
})
这尤其适合配合实例的 $attrs 属性使用,该属性包含了传递给一个组件的特性名和特性值
Vue.component('base-input', {
inheritAttrs: false,
props: ['label', 'value'],
template: `
<label>
{{ label }}
<input
v-bind="$attrs"
v-bind:value="value"
v-on:input="$emit('input', $event.target.value)"
>
</label>
` }) 这个模式允许你在使用基础组件的时候更像是使用原始的 HTML 元素,而不会担心哪个元素是真正的根元素:
<base-input
v-model="username"
class="username-input"
placeholder="Enter your username"
></base-input>
不区分大小写,在子组件中定义了$emit("changeTxt")方法,父组件只能<my-nav @="changeTxt">,而不能<my-nav @="change-txt"> 跟组件和 prop 不同,事件名不会被用作一个 JavaScript 变量名或属性名,所以就没有理由使用 camelCase 或 PascalCase 了。并且 v-on 事件监听器在 DOM 模板中会被自动转换为全小写 (因为 HTML 是大小写不敏感的),所以 v-on:myEvent 将会变成 v-on:myevent——导致 myEvent 不可能被监听到。 因此,我们推荐你始终使用 kebab-case 的事件名。
一个组件上的 v-model 默认会利用名为 value 的 prop 和名为 input 的事件,但是像单选框、复选框等类型的输入控件可能会将 value 特性用于不同的目的。model 选项可以用来避免这样的冲突:
<template>
<input type="checkbox" :checked="checked" @change="$emit('change',$event.target.checked)"/>
<script>
export default {
name: "MyCheckbox",
model: {
prop: 'checked',
event: 'change'
},
props:["checked"]
}
</script>
<base-input v-on:focus.native="onFocus"></base-input>
承载分发内容的出口 它允许你像这样合成组件:
<navigation-link url="/profile">
Your Profile
</navigation-link>
然后你在
<a v-bind:href="url" class="nav-link" >
<slot></slot>
</a>
当组件渲染的时候,这个
如果
需要多个插槽时
在子组件中<slot name="name"></slot>
在父组件中<h1 slot="name"></name>
或者<template slot="name><h1></h1></template>
我们还是可以保留一个未命名插槽,这个插槽是默认插槽,也就是说它会作为所有未匹配到插槽的内容的统一出口。
当在这些组件之间切换的时候,在动态组件上使用 keep-alive,保持这些组件的状态,以避免反复重渲染导致的性能问题。
<keep-alive>
<component :is="currentTab"></component>
</keep-alive>
所有的子组件都可以通过$root访问到根组件的数据
当要给一个组件的每个子组件都传递同一个方法时,可以使用依赖注入,依赖注入包含两个新的实例选项
然而,依赖注入还是有负面影响的。它将你的应用以目前的组件组织方式耦合了起来,使重构变得更加困难。同时所提供的属性是非响应式的。这是出于设计的考虑,因为使用它们来创建一个中心化规模化的数据跟使用 $root做这件事都是不够好的。如果你想要共享的这个属性是你的应用特有的,而不是通用化的,或者如果你想在祖先组件中更新所提供的数据,那么这意味着你可能需要换用一个像 Vuex 这样真正的状态管理方案了。
组件名:
推荐遵循 W3C 规范中的自定义组件名 (字母全小写且必须包含一个连字符)
组件名大小写 1.使用 kebab-case
2.使用 PascalCase
注意:直接在 DOM (即非字符串的模板) 中使用时只有 kebab-case 是有效的。