Vue.js 第4章 组件与路由
组件
什么是组件:组件就是一些标签结构的封装,同时为这些结构添加需要的业务逻辑,设置你想要的样式
一个组件中一般可以设置:结构,功能和样式
为什么要使用组件:
使用方便
复用
组件的创建和使用
组件的分类:
全局组件:在vm实例外通过Vue.component来创建的组件,在当前vm实例指定的app模板范围内都能使用
子组件:在组件内部通过components属性来创建的组件
在vue中如何创建组件
组件是可复用的 Vue 实例:这句话告诉我们组件就是一个vue实例,那么就意味着在之前创建vue实例中的配置成员在组件中似乎都能写,也就说明了如何配置Vue实例就如何配置组件实例
通过Vue.component(名称,{配置})来创建组件
在页面中通过组件名称来使用,使用的时候就像使用标签一样
重点说明:在vm实例外来创建
<!DOCTYPE html>
<html lang='en'> <head>
<meta charset='UTF-8'>
<meta name='viewport' content='width=device-width, initial-scale=1.0'>
<meta http-equiv='X-UA-Compatible' content='ie=edge'>
<title>Document</title>
<script src="./js/vue.js"></script>
</head> <body>
<!-- 创建父组件模版 -->
<template id="father">
<div>
<h2>我是爸爸</h2>
<!-- 将子组件放在这里 -->
<son></son> </div>
</template> <!-- 创建子组件模版 -->
<template id="son">
<h2>我是儿子</h2>
</template>
<div id='app'>
<!-- 将父组件放在这里 -->
<father></father>
</div>
<script>
// 创建一个父组件
Vue.component('father', {
template: '#father',
data(){
// 注意:这里如果写了data函数,内部就必须return一个对象(没有数据就写个空对象),否则服务器会爆炸!
return {
}
}, // 使用components创建子组件
components: {
// 子组件名称
son:{
template: '#son',
data(){
return {}
}
}
}
})
var vm = new Vue({
el: '#app',
data: {}
})
</script>
</body> </html>
创建并使用组件
在Vue中如何使用组件,重点关注使用的细节
常见错误:

原因
你的组件的确没有定义
你定义了,但是定义的位置不对,如放在vm实例后定义就会出现这个错误
重点:在组件中如何添加更多 配置
到底可以添加那些配置
之前vm实例可以添加的配置这边基本上都能添加,除了el
el在之前的作用是指定模板,在组件中指定模板是通过template属性
配置具体应该如何进行
template:指定模板
在template属性中直接创建模板
使用template标签创建模板,在template属性中指定
创建模板结构,设置标识id
<template id='lwtemp'>
<p style="color: red">我是隔壁老王~~~~!!!!</p>
</template>
在template属性中指定这个模板
Vue.component('laowang', {
// 指定模板
// 没有语法高亮,没有代码提示,没有层次结构,不方便修改
template: "#lwtemp"
})
细节:

这个错误告诉我们组件只能有一个根元素,如果有多个则会出现这个错误,如何解决,将这多个元素再包含在到一个根元素中
data:
可以定义当前组件中使用到的变量
data必须是一个函数
一个组件的 data 选项必须是一个函数,因此每个实例可以维护一份被返回对象的独立的拷贝
如果不是一个函数,那么有可能造成组件复用的时候,多个组件指向同一个对象,造成操作其中任何一个组件,其它组件会有莫名其妙的变化
函数有作用域,在一个函数中生成的数据与其它的函数没有关系,如果使用函数,就可以做到一个组件内部的数据操作不会影响其它的组件,同时也不会影响组件的复用
data函数中必须返回 一个对象
在函数中必须返回一个对象
错误信息

原因:你在组件中使用到了某些成员,但是这个成员在组件中却没有定义
1.组件是一个单独的结构,一个组件默认不能使用另外一个组件中定义的成员

原因:组件中的Data选项必须是一个函数,这个函数还必须返回 一个对象,我们定义的数据必须写在这个返回的对象中

原因:data函数必须返回一个对象,如果没有成员,也需要返回一个{}
methods:
mounted:
watch:
computed:
// vm外面创建组件
Vue.component('laowang', {
// 指定模板
// 没有语法高亮,没有代码提示,没有层次结构,不方便修改
template: "#lwtemp",
// 添加设置数据
data(){
return {
age:0,
myname:'隔壁老李'
}
},
methods:{
sayHi(){
alert('你好啊')
}
},
mounted(){
alert('页面打开立刻执行')
},
computed:{
myage(){
return this.age - 0 + 10
}
}
})
组件的组织结构
以后真正进行开发的时候,页面可能会比较的复杂,经常会看到元素嵌套的场景出现,如果你将一些结构封装为组件,那么势必会造成组件的嵌套,这样就产生了一个组件相关的组织结构
什么是父组件,什么是子组件
外层组件就可以认为是父组件
父组件中创建的组件就可以认为是这个父组件的子组件
父子只是一个组织结构布局
为什么会出现父子组件这种结构
创建父子组件
先创建父组件
在父组件内部通过components创建子组件
子组件的创建方式和父组件完全一致
Vue.component('father', {
template: '#father',
data() {
return {
fname: '老王'
}
},
// 通过components属性来创建子组件,它是一个对象
components: {
// 定义一个一个的子组件
// 3.定义第一个子组件son
son: {
// 4.可以写与父组件相同的成员
template: '#son',
data() {
return {
sname: '小王'
}
}
}
}
})
components的两个作用
创建子组件
组件注册:如果你从其它地方引入一个组件那么就必须先注册才能使用
使用子组件
在某个父组件中创建的子组件只有在这个父组件中可以使用
所谓在父组件中使用是指在这个父组件的模板中使用
<!-- 2.父组件模板 -->
<template id='father'>
<div class="father">
<p>我是父组件:{{fname}}</p>
<son></son>
</div>
</template>
由于上面的组件的组织结构,在真正进行开发的时候,我们经常需要实现不同的组件之间的数据交互,那么就必须要实现组件之间的数据传递
在一个组件中定义的数据只有在当前组件中可以使用
父子组件之间的数据传递
父传子
父组件中数据要传递给子组件来使用
如果要实现父传子,子组件需要做什么
在子组件中定义props属性,它是一个独立的属性
props是一个数组
在props中定义的成员就相当于在data中定义的成员
在props一般就是你想定义的属性的名称,它们的类型是字符串
这个props相当于一个父组件为子组件赋值的接口,在父组件中可以为子组件的props中定义的成员赋值
如果要实现父传子,在父组件中需要做什么
父组件中要使用子组件
在父组件中使用子组件的位置,使用v-bind为子组件中的prop属性赋值

子传父
大致了解子传父的场景
通过this.$emit可以发射事件
子传父在子组件中需要做什么
添加按钮事件,在事件处理函数中去发射一个事件
发射事件并传入相应的数据,它是通过事件发射向父组件传递数据
子传父在父组件中又需要做什么
父组件中进行指定事件的监听
发现有指定的事件发射,就监听并进行处理
在父组件中使用子组件的位置使用v-on进行监听,在监听处理函数中有一个默认的参数,这个参数就是从子组件事件发射时传递的数据

兄弟组件之间的传值
查看使用场景
为什么不能再使用this
this是指向当前组件,意味着事件只能由father组件进行监听,与我们要求不相合
this我们知道它的本质就是一个vue实例,那么我们能不能直接创建一个全局的Vue实例来进行这个场景的事件发射呢?
创建事件总线:new Vue()
事件总线就是说明所有事件都能通过它来进行发射和监听
说白了,事件总线就是一个单独的全局的Vue实例
源组件中需要做什么事情
发射事件,传递数据
目标组件需要做什么事情
监听事件,接收数据

父传子demo
<!DOCTYPE html>
<html lang='en'> <head>
<meta charset='UTF-8'>
<meta name='viewport' content='width=device-width, initial-scale=1.0'>
<meta http-equiv='X-UA-Compatible' content='ie=edge'>
<title>Document</title>
<script src="./js/vue.js"></script>
</head> <body>
<!-- 创建父组件模版 -->
<template id="father">
<div>
<h2>告诉儿子明天去{{surfing}}!</h2>
<son :surfing="surfing"></son>
</div>
</template> <!-- 创建子组件模版 -->
<template id="son">
<h2>我爸爸告诉我明天去{{surfing}}</h2>
</template>
<div id='app'>
<father></father>
</div>
<script>
// 创建父组件
Vue.component('father',{
template: '#father', data(){
return {surfing:'海上冲浪'}
},
methods: { },
// 创建子组件
components: {
son:{
template: '#son',
props: ['surfing'],
data(){
return {}
},
methods: { }
}
}
})
var vm = new Vue({
el: '#app',
data: {}
})
</script>
</body> </html>
子传父demo
<!--
思路:
1.子组件发射事件,传递数据
2.父组件中使用子组件的位置进行监听,通过v-on:事件名='事件处理函数'
-->
<!DOCTYPE html>
<html lang='en'> <head>
<meta charset='UTF-8'>
<meta name='viewport' content='width=device-width, initial-scale=1.0'>
<meta http-equiv='X-UA-Compatible' content='ie=edge'>
<title>Document</title>
<script src="./js/vue.js"></script>
</head> <body>
<!-- 创建父组件模板 -->
<template id="father">
<div>
<h2>I am Father,我儿子的女朋友是:{{gfname}}</h2>
<son v-on:emitname='getname'></son>
</div>
</template> <!-- 创建子组件模版 -->
<template id="son">
<div>
<h2>I am Son</h2>
<button @click="sendName">点我发送女朋友杨幂给我爸爸</button>
</div>
</template>
<div id='app'>
<father></father>
</div>
<script>
// 创建父组件
Vue.component('father', {
template: '#father',
data() {
return {
gfname: ''
}
},
methods: {
getname(data){
console.log(data)
this.gfname = data;
}
},
// 创建子组件
components: {
son: {
template: '#son',
data() {
return {
gfname: '杨幂'
}
},
methods: {
sendName(){
// $emit可以发射事件
// this.$emit(事件名称,事件参数(数据))
// 注意:在子组件函数中发射一个事件并不需要关心谁去做监听
this.$emit('emitname',this.gfname)
}
}
}
}
})
var vm = new Vue({
el: '#app',
data: {}
})
</script>
</body> </html>
兄弟组件传值demo
<!DOCTYPE html>
<html lang='en'> <head>
<meta charset='UTF-8'>
<meta name='viewport' content='width=device-width, initial-scale=1.0'>
<meta http-equiv='X-UA-Compatible' content='ie=edge'>
<title>Document</title>
<script src="./js/vue.js"></script>
</head> <body>
<!-- 创建父组件模版 -->
<template id="father">
<div>
<alex></alex>
<roger></roger>
</div>
</template> <!-- 创建2个兄弟组件模版 -->
<template id="alex">
<div>
<h2>我要告诉我兄弟今天去{{dosomething}}</h2>
<button @click="tellinfo">点击发送短信</button>
</div>
</template> <template id="roger">
<h2>WoW,我兄弟告诉我今天要去{{dosome}},好兴奋!</h2>
</template>
<div id='app'>
<father></father>
</div>
<script>
//创建事件总线bus实例
var bus = new Vue(); // 创建父组件
Vue.component('father',{
template: '#father',
data(){
return {}
},
methods: { },
// 创建2个兄弟组件
components: {
alex: {
template: '#alex',
data(){
return {
dosomething: '钓鱼',
}
},
methods: {
tellinfo(){
// 使用事件总线来发送事件
bus.$emit('emitname', this.dosomething)
}
}
},
roger:{
template: '#roger',
data(){
return {
dosome:'??'
}
},
methods: { },
mounted () {
bus.$on('emitname', data=>{
console.log(data)
this.dosome = data
})
}
}
}
}) var vm = new Vue({
el: '#app',
data: {}
})
</script>
</body> </html>
路由
可以实现导航跳转(页面跳转)的一种方式,在vue组件的跳转都是通过路由来实现的
为什么要使用路由
因为我们不想实现页面的跳转
但是我们又想展示不同的页面的不同的内容
我们要做什么
我们需要做的是,将组件 (components) 映射到路由 (routes),然后告诉 Vue Router 在哪里渲染它们
基本路由的添加方式
你得路由如何添加:它是一个单独的结构
通过VueRouter进行路由对象的创建
通过routes进行路由配置
路由和组件如何映射
如何指定你组件内容的展示区域
如何使用路由
挂载路由=注入路由
添加router-view结构,指定路由映射组件的展示区域
demo
<!DOCTYPE html>
<html lang='en'> <head>
<meta charset='UTF-8'>
<meta name='viewport' content='width=device-width, initial-scale=1.0'>
<meta http-equiv='X-UA-Compatible' content='ie=edge'>
<title>Document</title>
<script src="./js/vue.js"></script>
<script src="./js/vue-router.js"></script>
</head> <body> <div id='app'>
<router-link to="/index">首页</router-link>
<router-link to="/product">产品页</router-link>
<h3>路由匹配到的组件将渲染在这里</h3>
<div style="width:600px; height: 400px; border: solid">
<router-view></router-view>
</div>
</div>
<script>
// 每个路由对象映射着一个单独的组件,所以我们第一步创建好组件
// 1.创建几个组件
var Index = Vue.component('index', {
template: '<div>首页</div>'
})
var Product = Vue.component('product', {
template: '<div>产品</div>'
})
// 2.创建路由对象,创建之前不要忘了引入vue-router.js文件
// 通过new VueRouter()来创建路由对象,在构造函数中添加路由配置
var router = new VueRouter({
// 3.添加路由配置
// 我们可以配置多个路由,所以使用routes来进行多个路由的配置
routes: [
// 4.添加单个路由配置,俺哥路由都是以对象的方式存在,对于单个路由一般我们
//会配置下面几个属性
{
name: 'Index',
path: '/index',
component: Index
},
{
name: 'Product',
path: '/product',
component: Product
}
]
}) var vm = new Vue({
el: '#app',
// 5.注入/挂载路由
router: router,
data: {}
})
</script>
</body> </html>
思维脑图总结:


Vue.js 第4章 组件与路由的更多相关文章
- 基于Vue.js的表格分页组件
有一段时间没更新文章了,主要是因为自己一直在忙着学习新的东西而忘记分享了,实在惭愧. 这不,大半夜发文更一篇文章,分享一个自己编写的一个Vue的小组件,名叫BootPage. 不了解Vue.js的童鞋 ...
- Vue.js的表格分页组件
转自:http://www.cnblogs.com/Leo_wl/p/5522299.html 有一段时间没更新文章了,主要是因为自己一直在忙着学习新的东西而忘记分享了,实在惭愧. 这不,大半夜发文更 ...
- Vue.js-09:第九章 - 组件基础再探(data、props)
一.前言 在上一章的学习中,我们学习了 Vue 中组件的基础知识,知道了什么是组件,以及如何创建一个全局/局部组件.不知道你是否记得,在上一章中,我们提到组件是一个可以复用的 Vue 实例,它与 Vu ...
- Vue.js中,如何自己维护路由跳转记录?
在Vue的项目中,如果我们想要做返回.回退操作时,一般会调用router.go(n)这个api,但是实际操作中,使用这个api有风险,就是会让用户跳出当前应用,因为它记录的是浏览器的访问记录,而不是你 ...
- 基于 Vue.js 的移动端组件库mint-ui实现无限滚动加载更多
通过多次爬坑,发现了这些监听滚动来加载更多的组件的共同点, 因为这些加载更多的方法是绑定在需要加载更多的内容的元素上的, 所以是进入页面则直接触发一次,当监听到滚动事件之后,继续加载更多, 所以对于无 ...
- vue.js中的全局组件和局部组件
组件(Component)是 Vue.js 最强大的功能之一.组件可以扩展 HTML 元素,封装可重用的代码.在较高层面上,组件是自定义元素, Vue.js 的编译器为它添加特殊功能. 组件的使用有三 ...
- Vue.js 2.x:组件的定义和注册(详细的图文教程)
本文最初发表于博客园,并在GitHub上持续更新前端的系列文章.欢迎在GitHub上关注我,一起入门和进阶前端. 以下是正文. 前言 什么是组件 组件: 组件的出现,就是为了拆分Vue实例的代码量的, ...
- 《前端福音,vue.js 之豆瓣电影组件大揭秘-video》
{{ message }} 小胡子语法 在 Vue 中被称之为双花括号插值表达式 ---------------- http://todomvc.com/ TodoMVC是一款开源的JavaScr ...
- Vue.js 相关知识(组件)
1. 组件介绍 组件(component),vue.js最强大的功能之一 作用:封装可重用的代码,通常一个组件就是一个功能体,便于在多个地方都能调用该功能体 根组件:我们实例化的Vue对象就是一个组件 ...
随机推荐
- 用reduce装逼 之 多个数组中得出公共子数组,统计数组元素出现次数
昨天做了一道美团的面试题,要求是给N个数组,找出N个数组的公共子数组. ,,,,]; ,,,,]; ,,,,]; ,,,,]; 以上四个数组,有公共子数组2, 3,7 function main(){ ...
- 直接删除mysql的日志导致mysql无法启动
--02T08::.750000Z [Warning] [MY-] [Server] 'NO_ZERO_DATE', 'NO_ZERO_IN_DATE' and 'ERROR_FOR_DIVISION ...
- vue前后端分离
axios前后端交互 安装 一定要安装到`项目目录下 cnpm install axios 配置 在main.js中配置 //配置axios import axios from 'axios' Vue ...
- linux升级或安装程序后无法进入图形界面
报错如下: Failed to start the X server (your graphical interface). lt is likely that it is not set up co ...
- GYM 101981E(开关反转性质)
要点 做法是删去连续的k个0或k个1,连消.消消乐的那种,网上博主用个栈\(O(n)\)就很优秀地操作了这个过程 原因是有性质:比如k=3,101000贪心地翻就能翻成000101,所以连续的k个可以 ...
- Leetcode24.Swap Nodes in Pairs两两交换链表中的节点
给定一个链表,两两交换其中相邻的节点,并返回交换后的链表. 示例: 给定 1->2->3->4, 你应该返回 2->1->4->3. 说明: 你的算法只能使用常数的 ...
- Laravel 5.2 使用 JWT 完成多用户认证 | Laravel China 社区 - 高品质的 Laravel 开发者社区 - Powered by PHPHub
Json Web Token# JWT代表Json Web Token.JWT能有效地进行身份验证并连接前后端. 降地耦合性,取代session,进一步实现前后端分离 减少服务器的压力 可以很简单的实 ...
- WPF数据绑定详解
元素绑定 数据绑定最简单的形式是,源对象是WPF元素而且源属性是依赖属性.依赖项属性具有内置的更改通知支持,当在源对象中改变依赖项属性的值时,会立即更新目标对相中的绑定属性. <!--Xaml程 ...
- DirectX11笔记(九)--Direct3D渲染5--CONSTANT BUFFERS
原文:DirectX11笔记(九)--Direct3D渲染5--CONSTANT BUFFERS 版权声明:本文为博主原创文章,未经博主允许不得转载. https://blog.csdn.net/u0 ...
- systemd管理nginx
首先安装nginx,此处不做赘述. 保存以下内容到/lib/systemd/system/nginx.service文件. [Unit] Description=The NGINX HTTP and ...