组件
-
什么是组件:组件就是一些标签结构的封装,同时为这些结构添加需要的业务逻辑,设置你想要的样式
-
一个组件中一般可以设置:结构,功能和样式
-
-
-
使用方便
-
复用
-
组件的创建和使用
-
组件的分类:
-
全局组件:在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>
-
-
常见错误:
你的组件的确没有定义
你定义了,但是定义的位置不对,如放在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函数必须返回一个对象,如果没有成员,也需要返回一个{}
-
-
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: '小王' } } } } })
-
-
创建子组件
-
组件注册:如果你从其它地方引入一个组件那么就必须先注册才能使用
-
-
使用子组件
-
在某个父组件中创建的子组件只有在这个父组件中可以使用
-
所谓在父组件中使用是指在这个父组件的模板中使用
-
<!-- 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="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>
思维脑图总结: