VUE学习-组件
组件
组件是可复用的 Vue 实例,且带有一个名字。
<div id="components-demo">
<button-counter></button-counter>
</div>
<script>
// 定义一个名为 button-counter 的新组件
Vue.component('button-counter', {
data: function () {
return {count: 0}
},
template: '<button v-on:click="count++">You clicked me {{ count }} times.</button>'
});
new Vue({ el: '#components-demo' })
</script>
注意:
- 一个组件的 data 选项必须是一个函数,因此每个实例可以维护一份被返回对象的独立的拷贝
- 每个组件必须只有一个根元素
- 有些 HTML 元素,诸如 <ul>、<ol>、<table> 和 <select>,对于哪些元素可以出现在其内部是有严格限制的。而有些元素,诸如 <li>、<tr> 和 <option>,只能出现在其它某些特定的元素内部。
- 全局注册的组件可以在任何父组件或者子组件使用,局部注册的组件在其子组件中不可用。
- 全局注册的行为必须在根 Vue 实例 (通过 `new Vue`) 创建之前发生。
- 当 prop 验证失败的时候,(开发环境构建版本的) Vue 将会产生一个控制台的警告。
- 对于绝大多数 attribute 来说,从外部提供给组件的值会替换掉组件内部设置好的值。class 和 style attribute 会稍微智能一些,即两边的值会被合并起来
- inheritAttrs: false 选项不会影响 style 和 class 的绑定。
注册组件
- 全局注册:Vue.component('comp-name',{})
- 局部注册:new Vue(components:{ 'comp-name':{},comp-obj })
- 组件命名:
- my-component
- MyComponent
- 使用模块系统注册
<script>
import ComponentA from './ComponentA';
export default {components: {ComponentA}}
</script>
- require.context: 只全局注册这些非常通用的基础组件。
link:https://cn.vuejs.org/v2/guide/components-registration.html
自定义组件的v-model
<div id-"comp">
<base-checkbox v-model="lovingVue" ></base-checkbox>
</div>
<script>
Vue.component('base-checkbox', {
model: {
prop: 'checked',
event: 'change'
},
//注意你仍然需要在组件的 props 选项里声明 checked 这个 prop。
props: {checked: Boolean},
template: `<input type="checkbox" v-bind:checked="checked" v-on:change="$emit('change', $event.target.checked)">`
})
new Vue({
el: '#comp',
data:{return { lovingVue: true}},
methods:{}
})
</script>
传参
props
用一个 props 选项将其包含该组件可接受的 prop 列表- 可以为其指定类型props:{title: String}或者props:{title: {type: String}}
- 为其指定类型域props:
- type: [
String
|Number
|Boolean
|Array
|Object
|Date
|Function
|Symbol
|自定义的构造函数
] - 指定默认值props:{title: {default: "post-title"}}
- 指定是否必须props:{title: {required: true}}
- 指定验证函数 props:{title: {validator: function(v){return ['A','B'].indexOf(v) !== -1}}}
<div id="comp">
<blog-post title="My journey with Vue"></blog-post>
</div>
<script>
Vue.component('blog-post', {
props: {'title'},
template: '<h3>{{ title }}</h3>'
})
new Vue(el:'#comp')
</script>
$emit
通过调用内建的 $emit 方法并传入事件名称来触发一个事件,操作父组件的data<div id="comp">
<blog-post v-on:click-count="click += 1" title="My journey with Vue"></blog-post>
</div>
<script>
Vue.component('blog-post', {
props: {'title'},
template: `<div><button @click="$emit('click-count')">Enlarge text</button><h3>{{ title }}</h3></div>`
})
new Vue(el:'#comp',data:{return {click:1}})
</script>
v-slot
绑定在<slot>
元素上的 attribute 被称为插槽 prop。<div id="comp">
<current-user :user='user'>
<!-- 提取默认命名插槽的props -->
<template v-slot:default="slotProps">
{{ slotProps.user.firstName }}
</template>
</current-user>
<!-- 解构赋值提取默认命名插槽的user -->
<current-user v-slot="{ user }">{{ user.firstName }}</current-user>
<!-- 解构赋值提取默认命名插槽的user并自定义命名person -->
<current-user v-slot="{ user: person }">{{ person.firstName }}</current-user>
<!-- 解构赋值提取默认命名插槽的user并自定义属性默认值,用于插槽 firstName 是 undefined -->
<current-user v-slot="{ user = { firstName: 'Guest' } }">{{ user.firstName }}</current-user>
<!-- 动态指令参数也可以用在 v-slot 上,来定义动态的插槽名 -->
<current-user v-slot:[dynamicSlotName]="{ user }">{{ user.firstName }}</current-user>
<!-- v-slot:slotName="props"可以缩写成#slotName="props" -->
<current-user #default="{ user }">{{ user.firstName }}</current-user>
</div>
<script>
Vue.component('current-user',{
props:{user:Object},
template:`<span><slot v-bind:user="user">{{ user.lastName }}</slot></span>`
})
new Vue({
el: '#comp',
data:{
return {
user{
firstName:'misuha',
lastName:'White'
},
dynamicSlotName:'default'
}
}
})
</script>
slot & slot-scope ( 已废弃 )
<div id="comp">
<current-user :user='user'>
<template slot="default" slot-scope="{user}">{{ user.firstName }}</template>
</current-user>
</div>
<script>
Vue.component('current-user',{
props:{user:Object},
template:`<span><slot v-bind:user="user">{{ user.lastName }}</slot></span>`
})
new Vue({
el: '#comp',
data:{
return {
user:{
firstName:'sa',
lastName:'wh'
},
dynamicSlotName:'default'
}
}
})
</script>
<slot>
和 HTML 元素一样,我们经常需要向一个组件传递内容
当组件渲染的时候,<slot></slot>
将会被替换为“Something bad happened.”。插槽内可以包含任何模板代码,包括 HTML
<div id="alarm-comp">
<alert-box>Something bad happened.</alert-box>
</div>
<script>
Vue.component('alert-box', {
template: `<div class="demo-alert-box"><strong>Error!</strong><slot></slot</div>`
})
new Vue(el:'#alarm-comp')
</script>
<!--默认值,它只会在插槽没有提供内容的时候被渲染。-->
<button type="submit"><slot>Submit</slot></button>
<!--具名插槽(组件名:‘base-layout’),默认值name='default'-->
<div class="container">
<header>
<slot name="header"></slot>
</header>
<main>
<slot></slot>
</main>
<footer>
<slot name="footer"></slot>
</footer>
</div>
<!--为具名插槽赋值-->
<base-layout>
<template v-slot:header>
<h1>Here might be a page title</h1>
</template>
<p>A paragraph for the main content.</p>
<p>And another one.</p>
<template v-slot:footer>
<p>Here's some contact info</p>
</template>
</base-layout>
<!--为具名插槽赋值的缩写-->
<base-layout>
<template #header>
<h1>Here might be a page title</h1>
</template>
<p>A paragraph for the main content.</p>
<p>And another one.</p>
<template #footer>
<p>Here's some contact info</p>
</template>
</base-layout>
<current-user #default="{ user }">{{ user.firstName }}</current-user>
is
在不同组件之间进行动态切换
<!-- 组件会在 `currentTabComponent` 改变时改变 -->
<component v-bind:is="currentTabComponent"></component>
<!-- 这个自定义组件 <blog-post-row> 会被作为无效的内容提升到外部,并导致最终渲染结果出错。 -->
<table>
<blog-post-row></blog-post-row>
</table>
<!-- 这个特殊的 is attribute 给了我们一个变通的办法 -->
<table>
<tr is="blog-post-row"></tr>
</table>
禁用 Attribute 继承
如果你不希望组件的根元素继承 attribute,你可以在组件的选项中设置 inheritAttrs: false。
<script>
Vue.component('my-component', {
inheritAttrs: false,
// ...
})
</script>
$listeners
Vue 提供了一个 $listeners property
,它是一个对象,里面包含了作用在这个组件上的所有监听器。
{ focus: function (event) { /* ... */ }
input: function (value) { /* ... */ },}
有了这个 $listeners property
,你就可以配合 v-on="$listeners" 将所有的事件监听器指向这个组件的某个特定的子元素。
<script>
Vue.component('base-input', {
inheritAttrs: false,
props: ['label', 'value'],
computed: {
inputListeners: function () {
var vm = this
// `Object.assign` 将所有的对象合并为一个新对象
return Object.assign({},
// 我们从父级添加所有的监听器
this.$listeners,
// 然后我们添加自定义监听器,或覆写一些监听器的行为,这里确保组件配合 `v-model` 的工作
{input: function (event) {
vm.$emit('input', event.target.value)
}}
)
}
},
template: ` <label>{{ label }}
<input v-bind="$attrs" v-bind:value="value" v-on="inputListeners" > </label> `
})
</script>
现在
<base-input>
组件是一个完全透明的包裹器了,也就是说它可以完全像一个普通的<input>
元素一样使用了:所有跟它相同的 attribute 和监听器都可以工作,不必再使用.native
监听器。
.sync修饰符
<!--comp: 对其赋新值-->
<script>
Vue.compontent('text-document',{
...
this.$emit('update:title', newTitle)
...
})
</script>
<text-document v-bind:title="doc.title" v-on:update:title="doc.title = $event"></text-document>
<text-document v-bind:title.sync="doc.title"></text-document>
注意带有
.sync
修饰符的v-bind
不能和表达式一起使用 (例如v-bind:title.sync=”doc.title + ‘!’”
是无效的)。注意带有.sync
修饰符的v-bind
不能和表达式一起使用 (例如v-bind:title.sync=”doc.title + ‘!’”
是无效的)。
将
v-bind.sync
用在一个字面量的对象上,例如v-bind.sync=”{ title: doc.title }”
,是无法正常工作的
最新文章
- 1280*720P和1920*1080P的视频在25帧30帧50帧60帧时的参数
- 加密狗的管理层API(C#代码)
- 大熊君JavaScript插件化开发------(第一季)
- Struts2环境搭建
- 源码方式安装mysql5.5
- mac安装最新版本的git
- vasprintf的实现
- CodeIgniter网站静态化管理系统
- stdafx.h的作用以及原理
- 以编程方式使用 Word 中的内置对话框
- Win10使用小技巧
- css实现超连接按钮形式显示
- 莱特币ltc在linux下的多种挖矿方案详解
- CentOS 7.0 安装配置 kafka 消息队列
- Cesium 一个导致浏览器内存一直增长的方法
- springmvc的介绍和第一个例子
- [Alpha阶段]第七次Scrum Meeting
- Windows 10 关闭Hyper-V
- Elasticsearch index fields 重命名
- Django的学习(六)————templates过滤器、Django shell、admin
热门文章
- [图像处理] YUV图像处理入门2
- [OpenCV实战]47 基于OpenCV实现视觉显著性检测
- Docker搭建Cloudreve网盘
- python之路25 面向对象 封装(隐藏、伪装)、多态、反射
- 10分钟做好 Bootstrap Blazor 的表格组件导出 Excel/Word/Html/Pdf
- C语言写的 史上最公平的投票系统
- BBS登录与注册功能的总结
- P32_全局配置 - tabBar
- Zookeeper+SpringCloud微服务(入门二)
- Spring Boot学习笔记(一)----概要与入门