组件

组件是可复用的 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 }”,是无法正常工作的

VUE学习-组件的更多相关文章

  1. vue学习—组件的定义注册

    组件的定义注册 效果: 方法一: <div id="box"> <v-header></v-header> <hr /> <b ...

  2. Vue学习—组件的学习

    1.什么是组件? 组件(Component)是 Vue.js 最强大的功能之一.组件可以扩展 HTML 元素,封装可重用的代码.在较高层面上,组件是自定义元素, Vue.js 的编译器为它添加特殊功能 ...

  3. 39.VUE学习--组件,子组件中data数据的使用,x-template模板的使用,改变for循环里的某条数据里的值

    多处引用相同组件时,操作data不会相互影响 <!DOCTYPE html> <html> <head> <meta charset="utf-8& ...

  4. vue学习--组件之间的传值方式

    1.概述 vue由多个组件构成页面,在不同的组件中有不同的联系,组件之间的传值是十分有必要的 2.父子组件之间传值 --props和$emit 父传子:通过props 方法:子组件:props:['m ...

  5. Vue学习-组件的基本使用(局部组件)

    目录 示例代码 1.创建组件(构造器对象创建-Vue.extend) 2.注册组件 3.使用组件 4.语法糖创建并注册组件 示例代码 http://jsrun.net/H8vKp/edit 1.创建组 ...

  6. vue学习目录 vue初识 this指向问题 vue组件传值 过滤器 钩子函数 路由 全家桶 脚手架 vuecli element-ui axios bus

    vue学习目录 vue学习目录 Vue学习一之vue初识 Vue学习二之vue结合项目简单使用.this指向问题 Vue学习三之vue组件 Vue学习四之过滤器.钩子函数.路由.全家桶等 Vue学习之 ...

  7. day 83 Vue学习三之vue组件

    本节目录 一 什么是组件 二 v-model双向数据绑定 三 组件基础 四 父子组件传值 五 平行组件传值 六 xxx 七 xxx 八 xxx 一 什么是组件 首先给大家介绍一下组件(componen ...

  8. 【整理】解决vue不相关组件之间的数据传递----vuex的学习笔记,解决报错this.$store.commit is not a function

    解决vue不相关组件之间的数据传递----vuex的学习笔记,解决报错this.$store.commit is not a function https://www.cnblogs.com/jaso ...

  9. vue学习笔记(七)组件

    前言 在前面vue的一些博客中,我们几乎将vue的基础差不多学习完了,而从本篇博客开始将会进入到vue的另一个阶段性学习,本篇博客的内容在以后的vue项目中占很大的比重,所以小伙伴们需要认真学习,本篇 ...

  10. vue学习笔记(八)组件校验&通信

    前言 在上一章博客的内容中vue学习笔记(七)组件我们初步的认识了组件,并学会了如何定义局部组件和全局组件,上一篇内容仅仅只是对组件一个简单的入门,并没有深入的了解组件当中的其它机制,本篇博客将会带大 ...

随机推荐

  1. .Net引用根目录子文件夹下的dll文件

    在.Net开发的时候,有时候会引用一套库,这些库是由多个dll文件.正常情况下,这些dll文件需要拷贝到运行根目录下.如果这些dll文件比较多,加上其他直接引用的dll,这样会导致根目录下非常乱.我们 ...

  2. PostgreSQL(02): PostgreSQL常用命令

    目录 PostgreSQL(01): Ubuntu20.04/22.04 PostgreSQL 安装配置记录 PostgreSQL(02): PostgreSQL常用命令 PostgreSQL 常用命 ...

  3. day07-Vue04

    Vue04 12.Vue2 脚手架模块化开发 目前开发模式的问题: 开发效率低 不够规范 维护和升级,可读性比较差 12.1基本介绍 官网地址 什么是Vue Cli脚手架 12.2环境配置,搭建项目 ...

  4. Codeforces Round #844 (Div.1 + Div.2) CF 1782 A~F 题解

    点我看题 A. Parallel Projection 我们其实是要在这个矩形的边界上找一个点(x,y),使得(a,b)到(x,y)的曼哈顿距离和(f,g)到(x,y)的曼哈顿距离之和最小,求出最小值 ...

  5. Stream流中的常用方法_skip-Stream流中的常用方法_concat

    Stream流中的常用方法_skip 如果希望跳过前几个元素,可以使用skip方法获取一个截取之后的新流∶ 如果流的当前长度大于n,则跳过前n个;否则将会得到一个长度为0的空流.基本使用: Strea ...

  6. FLASH-CH32F203替换CH32F103 FLASH快速编程移植说明

    因CH32F203 相对于CH32F103 flash操作的快速编程模式由单次128字节编程变成了单次256字节编程,该文档说明主要目的是为了方便客户在原先CH32F103工程的基础上实现flash ...

  7. LeetCode_单周赛_332

    6354. 找出数组的串联值 题意 将数组首尾元素接在一起,就是串联值. 串联之后删除,如果只剩下一个元素,加上这个元素即可 双指针,从首和尾向中间移动即可 code 注意:用 long 没看题目用了 ...

  8. Vue21 组件

    1 模块及组件简介 组件(component)是vue.js最强大的功能之一.组件的作用就是封装可重用的代码,通常一个组件就是一个功能体,便于在多个地方都能够调用这个功能体. 每个组件都是Vue的实例 ...

  9. Vue框架:6、Vue组件间通信,动态组件,插槽,计算属性,监听属性

    目录 前端开发之Vue框架 一.Vue组件间通信 1.组件间通讯父传子 2.组件间通讯子传父 3.ref属性 二.动态组件 1.不使用动态组件 2.使用动态组件 3.keep-alive保持组件不销毁 ...

  10. Dapr Workflow构建块的.NET Demo

    Dapr 1.10版本中带来了最有亮点的特性就是工作流构建块的的发布,虽然是Alpha 阶段,可以让我们尽早在应用系统中规划工作流, 在使用Dapr的系统中更好的编写负责的分布式应用系统.Dapr 工 ...