This is a Lengux blog.

We sat and drank with the sun on our shoulders and felt like free men. We could have been tarring the roof of one of our own houses. We were the lords of all creation. As for Andy,he spent that break hunkered in the shade,a strange little smile on his face,watching us drink his beer.

组件基础

组件基础

组件语法注意事项

HTML 中的 attribute 名是大小写不敏感的,所以浏览器会把所有大写字符解释为小写字符。这意味着当你使用 DOM 中的模板时,camelCase (驼峰命名法)的名需要使用其等价的 kebab-case (短横线分隔命名)

1
>Vue.component('myComponentName', { /* ... */ })

那我们在写在页面时标签就要这样写

1
><my-component-name>  </my-component-name>

大写处更换为-连接符

组件的数据data体处理

1
2
根实例写法   //函数
data:{}

因为组件的可复用性,所以如果数据采用对象写法是非常不安全的,首先可复用性问题就非常不友好,会导致所有组件共同操作一个数据源,而组件复用性的原理是重新创建一个一模一样的全新实例,其次对象的内容非常容易被污染,而函数不一样,按照组件复用性原理,那么每个组件的配置对象内部都会有一个函数,在生成时会自动调用retuen出数据对象,避免不同组件的污染问题。

1
2
3
4
5
6
组件实例写法  //函数
data(){
return{

}
}

组件使用三大步骤

一、定义组件(创建组件)

二、注册组件

三、使用组件(写组件标签)

定义组件

使用Vue.extend(options)创建返回值为一个名叫VueComponent的构造函数,其中options和new Vue(options)时传入的那个options几乎一样,但也有点区别;

区别如下:

1.el不要写,为什么? ——— 最终所有的组件都要经过一个vm的管理,由vm中的el决定服务哪个容器。

2.data必须写成函数,为什么? ———— 避免组件被复用时,数据存在引用关系。

备注:使用template可以配置组件结构。

定义一个组件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
const school = Vue.extend({
template: `
<div>
<h2>学校名称:{{ schoolName }}</h2>
<h2>学校地址:{{ address }}</h2>
<button @click="showName">点我提示学校名</button>
</div>
`,
//组件定义不要写el配置项,因为最终所有的组件都要被vm所管理,由vm决定服务于哪个容器
//这里data必须写成函数形式 避免多次使用组件导致共用data对象导致一个问题
data()
return {
schoolName: '武汉科技大学',
address: '武汉',
}
},
methods:{
showName(){
alert(this.schoolName)
}
}
})

定义组件的extend函数可以不写调用,如果不写Vue在注册时会自动帮我们调用

组件name

组件的name在定义时写入,name属性一般建造库时会使用(保持一致性)

name属性可以让组件渲染到页面时,保持name,比如

1
2
3
4
5
6
7
8
Vue.component('hhhh',{
name:'hello'
template: `
<div>
<h1>Hello Word</h1>
</div>
`,
})

当程序员想要使用组件时需要使用,但是在Vue底层里组件的名字仍然是

注册组件

定义组件时只是传入一个配置对象,而注册时需要区分局部注册和全局注册,以及编译组件引用名。

局部注册

1
2
3
4
5
6
7
8
new Vue({
el: "#root",
//配置组件(局部注册)
components: {
//es6对象简写
school,
},
})

全局注册

1
2
//school组件
Vue.component('school', school); //全局注册school 就代表所有的vm都可以用school组件了

组件注册简写

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
Vue.component('school',{
template: `
<div>
<h2>学校名称:{{ schoolName }}</h2>
<h2>学校地址:{{ address }}</h2>
<button @click="showName">点我提示学校名</button>
</div>
`,
//组件定义不要写el配置项,因为最终所有的组件都要被vm所管理,由vm决定服务于哪个容器
//这里data必须写成函数形式 避免多次使用组件导致共用data对象导致一个问题
data()
return {
schoolName: '武汉科技大学',
address: '武汉',
}
},
methods:{
showName(){
alert(this.schoolName)
}
}
})

组件的使用注意点

关于组件名:

一个单词组成:

第一种写法(首字母小写):school

第二种写法(首字母大写):School

多个单词组成:

第一种写法(kebab-case命名):my-school

第二种写法(CamelCase命名):MySchool (需要Vue脚手架支持)

备注:

(1).组件名尽可能回避HTML中已有的元素名称,例如:h2、H2都不行。

(2).可以使用name配置项指定组件在开发者工具中呈现的名字。

2.关于组件标签:

第一种写法:

第二种写法:

备注:不用使用脚手架时,会导致后续组件不能渲染。

3.一个简写方式:

const school = Vue.extend(options) 可简写为:const school = options

组件构造函数Component

关于VueComponent:

1.school组件本质是一个名为VueComponent的构造函数,且不是程序员定义的,是Vue.extend生成的。

2.我们只需要写,Vue解析时会帮我们创建school组件的实例对象,

即Vue帮我们执行的:new VueComponent(options)。

3.特别注意:每次调用Vue.extend,返回的都是一个全新的VueComponent!!!!注意这一点很重要

4.关于this指向:

(1).组件配置中:

data函数、methods中的函数、watch中的函数、computed中的函数 它们的this均是【VueComponent实例对象】。

(2).new Vue(options)配置中:

data函数、methods中的函数、watch中的函数、computed中的函数 它们的this均是【Vue实例对象】。

5.VueComponent的实例对象,以后简称vc(也可称之为:组件实例对象)。

Vue的实例对象,以后简称vm。 vm管理着一个又一个vc,vc里可以注册新vc

6.因为组件是可复用的 Vue 实例,所以它们与 new Vue 接收相同的选项,例如 data、computed、watch、methods 以及生命周期钩子等。仅有的例外是像 el 这样根实例特有的选项。

所以vm与vc属性配置并不是一模一样,尽管vc底层复用了很多vm的逻辑

组件插槽

作用:实现组件内的内容分发,让父组件可以向子组件指定位置插入html结构,也是一种组件间通信的方式,可以实现动画复用

优点:组件更灵活,复用性更强

默认插槽

1
2
3
4
5
6
7
8
9
10
11
父组件中:
<Category>
<div>html结构1</div>
</Category>
子组件中:
<template>
<div>
<!-- 定义插槽 -->
<slot>插槽默认内容...</slot>
</div>
</template>

具名插槽

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
父组件中:
<Category>
<template slot="center">
<div>html结构1</div>
</template>

<template v-slot:footer>
//v-slot是最新版的写法(推荐)简写为#
<div>html结构2</div>
</template>
</Category>
子组件中:
<template>
<div>
<!-- 定义插槽 -->
<slot name="center">插槽默认内容...</slot>
<slot name="footer">插槽默认内容...</slot>
</div>
</template>

作用域插槽

当我们需要使用的数据在子组件内时,那么要想更简洁的拿到数据,就要使用作用域插槽

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
父组件中:
<Category>
//当插槽不具名时
<template scope="scopeData">
//当插槽具名时
<template #center="scope">
<ul>
<li v-for="g in scopeData.games" :key="g">{{g}}</li>
</ul>
</template>
</Category>
子组件中:
<template>
<div>
<slot :games="games" name='left'></slot>
</div>
</template>

<script>
export default {
//数据在子组件自身
data() {
return {
games:['红色警戒','穿越火线','劲舞团','超级玛丽']
}
},
}
</script>

动态异步组件

动态 :is指令

动态组件见名知意就知道是能使一个组件动态化(不死板),具体体现在多组件切换

如果一个页面只有一个组件位,但是内容要随时切换成别的组件,那么要想控制组件的动态渲染则需要以下写法

通过v-if指令来控制渲染,这样写是及其麻烦且没有观赏性的,所以开发了:is指令,也就是动态组件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<template v-if="view == 'vue-home'">
<vue-home></vue-home>
</template>

<template v-if="view == 'vue-order'">
<vue-order></vue-order>
</template>

<template v-if="view == 'vue-help'">
<vue-help></vue-help>
</template>

<template v-if="view == 'vue-my'">。
<vue-my></vue-my>
</template>

上面的写法换成动态组件只需要一个标签即可完成

通过:is指令来绑定组件名进行渲染,这样如果想改变渲染只需要改变根组件的view值即可

1
<component :is="view"></component>

异步

在大型项目中,我们可能需要将组件再分割成小一些的代码块,并且只在需要的时候才从服务器加载一个模块。为了简化,Vue 允许你以一个工厂函数的方式定义你的组件,这个工厂函数会异步解析你的组件定义。Vue 只有在这个组件需要被渲染的时候才会触发该工厂函数,且会把结果缓存起来供未来重渲染。例如:

和promise的写法差不多,有成功回调和失败回调

1
2
3
4
5
6
7
8
Vue.component('async-example', function (resolve, reject) {
setTimeout(function () {
// 向 `resolve` 回调传递组件定义
resolve({
template: '<div>I am async!</div>'
})
}, 1000)
})

这个工厂函数会收到一个 resolve 回调,这个回调函数会在你从服务器得到组件定义的时候被调用。你也可以调用 reject(reason) 来表示加载失败。这里的 setTimeout 是为了演示用的,如何获取组件取决于你自己。

keep-alive缓存标签

写代码到现在,一直有个问题就是如何存档问题,当你从一个页面切换到另一个页面再切换回来时,dom是会重新渲染的,也就是说每次看到都是全新的页面,但是这并不符合网页的正常工作标准,页面缓存一直都是个问题,所以Vue推出了keep标签。

keep-alive的作用就是将他所包裹的内容缓存到本地,再次重绘渲染页面时会保留上一次的浏览状态,原理是每次打开Vue都会使用缓存进度,并在离开时讲状态缓存到本地里。

1
2
3
4
<!-- 失活的组件将会被缓存!-->
<keep-alive>
<component v-bind:is="currentTabComponent"></component>
</keep-alive>

内置关系

也就是组件构造函数Vomponent的显示原型指向的隐式原型是Vue构造函数的显式原型,所以组件的属性和根组件Vue实例的几乎差不多,(复用了很多根组件的属性)

1
VueComponent.prototype.__proto__ === Vue.prototype

为什么要有这个关系:让组件实例对象(vc)可以访问到 Vue原型上的属性、方法。

原型图

img

user@ui-verse:~$
Hey!

In the sea of coding, I am Lengux, pursuing creativity and user experience.

 友情链接
 标签
Made with 💛 by Lengux and some fantastic contributors! hexo blog framework
豫ICP备2022014432号-1