Vue(四)组件
组件的复用
这里的工程和上一节的一样
先建立一个组件
MyButton.vue
<template>
<button @click="count++">You clicked me {{ count }} times</button>
</template> <script>
export default {
name: "MyButton",
data: () => ({
count: 0
})
}
</script> <style scoped> </style>
引用这个组件
About.vue
<template>
<div class="about">
<my-button></my-button>
<my-button></my-button>
<my-button></my-button>
</div>
</template>
<script>
import MyButton from '../components/MyButton'
export default {
components: {MyButton}
}
</script>
页面:

1. MyButton.vue 就是一个组件,其它位置通过import来引入这个组件,就可以来使用了
2. 注意 一个组件的 data 选项必须是一个函数,因此每个实例可以维护一份被返回对象的独立的拷贝
如果不是这样:
data: () => ({
count: 0
})
而是这样:
data: {
count: 0
}
额,会报错~

页面也不能正常:

..
通过 Prop 向子组件传递数据
新建一个子组件
MyTitle.vue
<template>
<h3>{{blog}}</h3>
</template> <script>
export default {
name: "MyTitle",
props: ['blog']
}
</script> <style scoped> </style>
这里通过自定义的属性blog来传递数据,定义在子组件里面
在父组件里面使用,并传入数据
<template>
<div class="about">
<my-title v-for="t in items" :blog="t"></my-title>
</div>
</template>
<script>
import MyTitle from '../components/MyTitle'
export default {
components: {MyTitle},
data: () => ({
items: ['My journey with Vue','Blogging with Vue','Why Vue is so fun']
})
}
</script>
将数据绑定到blog属性上 :blog
页面:

当组件变得复杂,我们需要传递的不止一个数据,如果是多个数据可以通过以下方式:
子组件:MyTitle.vue
<template>
<div>
<h3>{{blog.title}}</h3>
<p>{{blog.content}}</p>
</div>
</template> <script>
export default {
name: "MyTitle",
props: ['blog']
}
</script> <style scoped> </style>
父组件:About.vue
<template>
<div class="about">
<my-title v-for="t in items" :blog="t"></my-title>
</div>
</template>
<script>
import MyTitle from '../components/MyTitle'
export default {
components: {MyTitle},
data: () => ({
items: [
{title:'My journey with Vue',content:'every component must have a single root element (每个组件必须只有一个根元素)'},
{title:'Blogging with Vue',content:'你可以将模板的内容包裹在一个父元素内,来修复这个问题'},
{title:'Why Vue is so fun',content:'看起来当组件变得越来越复杂的时候,我们的博文不只需要标题和内容,还需要发布日期、评论等等。为每个相关的信息定义一个 prop 会变得很麻烦'},
]
})
}
</script>
页面:

通过事件向父级组件发送消息
一些功能可能要求我们和父级组件进行沟通。例如我们可能会引入一个可访问性的功能来放大博文的字号,同时让页面的其它部分保持默认的字号。
Vue 实例提供了一个自定义事件的系统来解决这个问题。我们可以在子组件里调用内建的 $emit 方法并传入事件的名字,来向父级组件触发一个事件
子组件:
<template>
<div>
<h3>{{blog.title}}</h3>
<!--$emit('enlarge-text') 自定义事件,click的时候触发父组件的enlarge-text事件,下同-->
<button v-on:click="$emit('enlarge-text')">放大</button>
<button v-on:click="$emit('shrink-text')">缩小</button>
<p>{{blog.content}}</p>
</div>
</template> <script>
export default {
name: "MyTitle",
props: ['blog']
}
</script> <style scoped> </style>
父组件:
<template>
<div class="about" :style="{ fontSize: postFontSize + 'em' }">
<!--@enlarge-text和@shrink-text 监听来自子组件的自定义事件-->
<my-title v-for="t in items" :blog="t" @enlarge-text="postFontSize += 0.1" @shrink-text="postFontSize -= 0.1"></my-title>
</div>
</template>
<script>
import MyTitle from '../components/MyTitle'
export default {
components: {MyTitle},
data: () => ({
// 控制字号
postFontSize: 1,
items: [
{title:'My journey with Vue',content:'every component must have a single root element (每个组件必须只有一个根元素)'},
{title:'Blogging with Vue',content:'你可以将模板的内容包裹在一个父元素内,来修复这个问题'},
{title:'Why Vue is so fun',content:'看起来当组件变得越来越复杂的时候,我们的博文不只需要标题和内容,还需要发布日期、评论等等。为每个相关的信息定义一个 prop 会变得很麻烦'},
]
})
}
</script>
页面:可以点击放大或者缩小

有的时候我们可能想让子组件来决定文本放大多少,那么也就是用一个事件来抛出一个特定的值,只需要修改子组件的$emit,加上第二个参数:

然后当在父级组件监听这个事件的时候,我们可以通过 $event 访问到被抛出的这个值

或者,父组件的处理函数是一个方法,那么从子组件传过来的$event变成这个方法的第一个参数:

处理方法:

插槽
匿名插槽【木有名字的插槽:<slot></slot>】
新建一个子组件:
NoNameSlot.vue
<template>
<p>
<slot></slot>
</p>
</template> <script>
export default {
name: "NoNameSlot"
}
</script> <style scoped> </style>
父组件:
<template>
<div class="about">
<no-name-slot v-for="i in items">
{{i.content}}
</no-name-slot>
</div>
</template>
<script>
import NoNameSlot from '../components/NoNameSlot'
export default {
components: {NoNameSlot},
data: () => ({
items: [
{title:'My journey with Vue',content:'当组件渲染的时候,这个 <slot></slot> 元素将会被替换为父组件传入的当前内容。'},
{title:'Blogging with Vue',content:'插槽内可以包含任何模板代码,包括 HTML'},
{title:'Why Vue is so fun',content:'嗯嗯嗯'},
]
})
}
</script>
一句话:子组件的 <slot></slot> 会被替换成父组件传入的任何内容,但是如果子元素里面没有<slot></slot>,父组件传入的内容会被抛弃
页面:

不信你看,三个p

具名插槽【有名字的插槽:<slot name="header"></slot>】
有时候我们需要多个插槽,不同的位置渲染不同的内容,那么就需要具名插槽了
子组件:MyLayout.vue
<template>
<div id="container">
<header>
<slot name="header"></slot>
</header>
<main>
<slot></slot>
</main>
<footer>
<slot name="footer"></slot>
</footer>
</div>
</template> <script>
export default {
name: "MyLayout"
}
</script> <style scoped> </style>
父组件:About.vue
<template>
<div class="about">
<my-layout>
<template slot="header">
<h1>这里是标题啊!</h1>
</template>
<p>A paragraph for the main content.</p>
<p>And another one.</p>
<template slot="footer">
<h2>这里是脚丫子</h2>
</template>
</my-layout>
</div>
</template>
<script>
import MyLayout from '../components/MyLayout'
export default {
components: {MyLayout}
}
</script>
页面:

可以看出,父组件在使用的时候,只需要通过指定slot的名字,就可以把指定内容送到对应的插槽上;而那些没有指定名字的,如果存在匿名插槽则会被送到匿名插槽的位置上。如果不存在,则不渲染。

作用域插槽【2.1.0+新增:可从子组件获取数据的可复用的插槽。引申:scope 用于表示一个作为带作用域的插槽的 <template> 元素,它在 2.5.0+ 中被 slot-scope 替代。】
前面两个都是从父组件获取数据,这个恰好反过来,从子组件获取数据。
子组件:
<template>
<div>
<!--只需要绑定数据即可-->
<slot :items="items"></slot>
</div>
</template> <script>
export default {
name: "MyScopeSlot",
data: () => ({
items: ['White','Black','Pink']
})
}
</script> <style scoped> </style>
父组件:
<template>
<div class="about">
<h3>按套路输出数据</h3>
<my-scope-slot>
<template slot-scope="childData">
<ul>
<li v-for="item in childData.items">{{item}}</li>
</ul>
</template>
</my-scope-slot>
<h3>一锅端</h3>
<my-scope-slot>
<template slot-scope="childData">
{{childData.items}}
</template>
</my-scope-slot>
<h3>不使用子组件提供的数据</h3>
<my-scope-slot>
作用域插槽退化为匿名插槽
</my-scope-slot>
</div>
</template>
<script>
import MyScopeSlot from '../components/MyScopeSlot'
export default {
components: {MyScopeSlot}
}
</script>
slot-scope 任何名字都可以,注意在父组件里,childData通过引用子组件的
绑定属性名称来获取数据
页面

动态组件【在不同组件之间进行动态切换】
建立三个子组件 ComponentA、ComponentB、ComponentC
<template>
<h2>组件A</h2>
</template> <script>
export default {
name: "ComponentA"
}
</script> <style scoped> </style>
内容一样,只是改个字母,这里不重复了。
父组件
<template>
<div class="about">
<button @click="next">下一个</button>
<!--切换的关键,参数是组件的名字-->
<component :is="view"></component>
</div>
</template>
<script>
import ComponentA from '../components/ComponentA'
import ComponentB from '../components/ComponentB'
import ComponentC from '../components/ComponentC' export default {
components: {ComponentA,ComponentB,ComponentC},
data: ()=> ({
index:0,
componentName:['ComponentA','ComponentB','ComponentC']
}),
computed:{
// 这是一个计算属性,返回当前index对应的组件名字
view: function () {
return this.componentName[this.index];
}
},
methods:{
// 循环index
next: function () {
this.index = ++this.index % 3;
}
}
}
</script>
页面:

--
当在这些组件之间切换的时候,你有时会想保持这些组件的状态,以避免反复重渲染导致的性能问题。也就是说,切换是一个销毁/渲染的过程,失效的被销毁,展示的时候重新渲染。那么如果我们不想要这一浪费的行为,我们更希望那些标签的组件实例能够被在它们第一次被创建的时候缓存下来,只需要把组件用<keep-alive>包裹起来:
<!-- 失活的组件将会被缓存!-->
<keep-alive>
<component v-bind:is="currentTabComponent"></component>
</keep-alive>
Vue(四)组件的更多相关文章
- vue中组件的四种方法总结
希望对大家有用 全局组件的第一种写法 html: <div id = "app"> <show></show></div> js: ...
- vue+element ui项目总结点(四)零散细节概念巩固如vue父组件调用子组件的方法、拷贝数据、数组置空问题 等
vue config下面的index.js配置host: '0.0.0.0',共享ip (假设你的电脑启动了这个服务我电脑一样可以启动)-------------------------------- ...
- vue.js组件化开发实践
前言 公司目前制作一个H5活动,特别是有一定统一结构的活动,都要码一个重复的轮子.后来接到一个基于模板的活动设计系统的需求,便有了下面的内容.借油开车. 组件化 需求一到,接就是怎么实现,技术选型自然 ...
- VUE.JS组件化
VUE.JS组件化 前言 公司目前制作一个H5活动,特别是有一定统一结构的活动,都要码一个重复的轮子.后来接到一个基于模板的活动设计系统的需求,便有了下面的内容.借油开车. 组件化 需求一到,接就是怎 ...
- [转] Vue + Webpack 组件式开发(练习环境)
前言 研究了下别人的 vue 多页面框架, 都是直接复制 package.json 文件,然后在本地 npm install 一下即可, 或者使用官网 vue-cli 工具生成一个项目, 觉得这样虽然 ...
- vue父子组件的传值总结
久违的博客园我又回来了.此篇文章写得是vue父子组件的传值,虽然网上已经有很多了.写此文章的目的就是记录下个人学习的一部分.接下来我们就进入主题吧! 在开发vue项目中,父子组件的传值是避免不掉的. ...
- 从零开始学 Web 之 Vue.js(六)Vue的组件
大家好,这里是「 从零开始学 Web 系列教程 」,并在下列地址同步更新...... github:https://github.com/Daotin/Web 微信公众号:Web前端之巅 博客园:ht ...
- vue学习—组件的定义注册
组件的定义注册 效果: 方法一: <div id="box"> <v-header></v-header> <hr /> <b ...
- vue的组件传输
vue的组件传输有四种,我个人觉得pubsub(订阅/发布)是最好用的,因为他不用去考虑关系,所以我们下面就只讲解pubsub吧 1) 优点: 此方式可实现任意关系组件间通信(数据) 首先我们需要 ...
- Vue兄弟组件通信
Vue兄弟组件通信之借助中央事件总线 下载链接:https://www.yinxiangit.com 其实要实现兄弟组件通信,就算是通过父子组件通信的方式也是可以达到的,如 子 ——>父——&g ...
随机推荐
- Odoo 菜单美化的扩展模块
详见: http://www.oejia.net/blog/2018/07/07/oejia_menu_about.html Odoo 菜单美化主题,odoo默认的菜单算是简洁好用的,如果您觉得还少了 ...
- 基于geotools的(两个)SHP要素变化提取方法预研
文章版权由作者李晓晖和博客园共有,若转载请于明显处标明出处:http://www.cnblogs.com/naaoveGIS/ 1. 背景 我们用遥感的手段进行卫星特征提取.多幅影像间的特征变化提取的 ...
- 一个GIS开源工具集架构的总结
文章版权由作者李晓晖和博客园共有,若转载请于明显处标明出处:http://www.cnblogs.com/naaoveGIS/ 1.背景 最近由团队HWG主导的GIS开源工具集基本告一段落,该项目虽然 ...
- row_number() over()分页查询
1.首先讲下row_number() over() 是干什么的? 是一个分析函数,会在数据表生成一个排序列. 案例SQL: select ROW_NUMBER() over(order by book ...
- 海思uboot启动流程详细分析(一)
第一阶段 start.S 首先我们可以在u-boot.lds中看到ENTRY(_start),即指定了入口_start,_start也就是整个start.S的最开始: 1. reset 在arch\a ...
- maven项目更换本地仓库
由于电脑重装系统更换原来maven项目的本地仓库 以前的仓库位置如图 需要更换的仓库位置 更换步骤如下: 更换后:
- 金蝶K3外购入库单单价取数规则调整
涉及界面: 问题:财务抱怨外购入库单价格取错,单价多除了一次税率 例如,采购单里面注明了价格是不含税15.3256 结果在外购入库单里面,又自做主张除以税率17%,把采购成本搞成了13.0988, 咨 ...
- Python:time模块/random模块/os模块/sys模块
time 模块 #常用方法 1.time.sleep(secs) (线程)推迟指定的时间运行.单位为秒. 2.time.time() 获取当前时间戳 python中时间日期格式化符号: %y 两位数的 ...
- 初识gauge自动化测试框架(二)
看到一些同学对该工具有点一兴趣,那么我将继续介绍Gauge自动化测试工具. Gauge本质上一个BDD(Behavior Driven Development)测试框架.所以,首先你要了解BDD的操作 ...
- 如何在FineUIMvc(ASP.NET MVC)中显示复杂的表格列数据(列表和对象)?
起源 最初,这个问题是知识星球内的一个网友提出的,如何在FineUIMvc中展现复杂的列数据? 在FineUIPro中,我们都知道有一个 TemplateField 模板列可以使用,我们只需要在后台定 ...