Vue04-组件开发与单页面

87 阅读7分钟

携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第1天,点击查看活动详情

组件:

1.什么是: 拥有专属的HTML+JS+CSS+数据的可重用的独立的页面功能区域。

2.为什么: 重用

3.何时: 今后,只要发现网页中有一个功能,可能被多处反复使用,都应该封装为组件。

4.如何: 2步:

(1). 创建一个组件

Vue.component("组件名",{
	/*特例: template*/
	template:`组件的HTML片段`, //相当于 el:"#app",
	data(){
		return { //相当于以前的data
			模型变量:值, 
			... ...
		}
	},
	/*每个组件内都是一个缩微的小new Vue()
	new Vue()中有什么,组件中也应该有什么*/
	methods:{ ... },
	watch:{ ... },
	computed:{ ... },
	八个生命周期钩子函数...
})

(2). 在页面中使用组件: 每个自定义组件其实就是一个自定义的HTML标签而已!

<组件名></组件名>

5.原理: 每当new Vue()扫描到一个不认识的标签时,都会去内存中,vue类型中找有没有同名的组件。如果找到同名的vue组件,就会做三件事:

(1). 复制组件template中的HTML片段代替页面上<组件></组件>标签位置

(2). 自动调用data()函数,返回一个新创建的模型对象,其中包含当前组件专属的模型变量

(3). 自动为当前组件区域创建一个缩微版的new Vue(),负责组件这个小区域的所有事宜。

6.为什么组件的data必须是一个函数:

可反复调用;反复创建新对象;避免组件间数据冲突

组件工作原理.png

组件化开发:

1.问题: 前端一个页面的功能和代码量越来越多,但是操作系统禁止多人协作编写一个文件。

2.解决: 将一个大的页面,划分为多个组件区域,分别保存在不同的文件中,由多人协作开发。最后运行时,还能合并在一个页面中运行给人看!——组件化开发

3.何时: 今后所有的页面,几乎都采用组件化开发。

4.为什么: 2个好处

(1). 便于多人协作开发,提高开发效率

(2). 松耦合,一人出错,不影响全局!

5.如何:

(1). 每当拿到一个页面后,先划分组件区域: 3个原则:

a. 位置

b. 功能

c. 是否重用

(2). 为每个组件创建独立的js文件,来保存组件的代码。

(3). 回到原页面中引入并使用组件标签,将组件重新拼接回一个完整的页面。

6.组件分类: vue中有三大类组件:

(1). 根组件: new Vue()

整个页面甚至整个项目只有一个new Vue()监控全局

根组件.png

(2). 全局组件: Vue.component()

可放在任何位置,没有限制

父组件.png

(3). 子组件:

a. 什么是: 规定只能在指定父组件范围内使用的组件

子组件.png

b. 如何: 3步:

1). 只创建一个普通的js对象,保存组件的内容

var 子组件对象名={ 组件内容 }

2). 为父组件添加新成员: components

父组件:{
	... : ...,
	components:{ 子组件对象名, ... ,  }
}

3). 在父组件界面中: <子组件标签名></子组件标签名>

7.示例: 实现待办事项列表的界面部分划分组件

组件开发1.png

组件开发2.png

组件开发3.png

组件间传值:

(1). 问题: 子组件无权使用父组件中的成员。

(2). 解决: 其实,vue中提供了多种组件间传值的机制。

(3). 重点讲父给子传值: 3步:

a. 父给子:

  父组件:{
   template:`
    <子组件标签  :自定义属性名="父组件的变量">
   `
   }

b. 子组件接收属性值:

  子组件对象:{
    props:[ "自定义属性名" ]
   }

c. 在子组件内,props中的属性用法和data中的变量用法完全一样!只不过props的属性值来自于外部传入,data中的变量值由自己定义。

d. 示例: 使用父给子传值,实现待办事项列表功能

组件传值.png

组件传传值V.png

SPA(Single Page Application)

S单 P页面 A应用

1.什么是: 整个应用程序只有一个唯一完整的HTML页面。其它所谓的页面,其实都是组件片段而已。所谓的切换页面,只是切换一个HTML中显示不同的组件片段而已。

2.为什么:

多页面应用单页面应用
请求次数每切换一次页面,都想服务器端重新发送请求。反复切换页面,就会反复发送请求。请求次数多!在首次加载时,就将唯一完整的HTML页面和所有其余页面组件一起下载下来。今后,即使反复切换页面,也不需要反复向服务器发送请求。请求次数绝对少.
公共资源每次切换页面,都要重新请求页面中的bootstrap.css、jquery.js、bootstrap.js等多个页面都要用到的资源。请求次数多,加载慢。每次切换页面时,唯一完整的HTML外壳没有切换,所以不会重复发送请求,下载css和js文件。所以,请求次数又少了很多,同时加载效率高
加载效率每次切换页面,都要删除旧的整棵DOM树,重建整棵DOM树。效率低每次切换页面时,因为只跟换部分组件片段显示,整个页面没有更换。则DOM树,也只更换部分节点,不用重建整棵DOM树。效率高
页面切换动画几乎不可能实现页面切换动画。因为页面切换需要同时看到前一个页面的后一半以及后一个页面的前一半。比较容易实现页面切换动画。因为单页面应用的所有页面组件已经同时保存在客户端了。同时显示,也是有可能的

3.何时: 今后几乎所有的项目都是单页面应用

4.缺点: 默认,单页面应用要在首次加载时,将所有需要的页面组件都下载到客户端本地,而不管用户是不是想看。所以,首屏加载速度极慢

5.解决: (未完待续...)

6.如何:

(1). 先创建唯一完整的HTML页面

要求: 是一个支持vue基本结构的空页面

<script src="js/vue.js">
<div id="app">
    //...
</div>
<script>
	new Vue({
		el:"#app"
	})
</script>

(2). 再创建所有"页面"组件文件:

a. 将来项目中,有几个"页面",就要创建几个页面组件文件

b. 按惯例,所有页面组件都要集中放在一个名为views的文件夹中.

c. 每个页面组件其实都是一个子组件。

d. 在唯一完整的HTML页面顶部引入页面组件

e. 创建404页面组件,也要在唯一完整的HTML页面顶部引入。还要加入到路由字典中最后一项:

{ path:"*", component:NotFound }

(3). 创建路由器对象:

a. 在唯一完整的HTML页面顶部引入vue-router.js(官方)

b. 创建路由器对象:

1). 按惯例,路由器对象应该保存在router/index.js文件中。

2). 先创建路由字典

var routes=[
	{path:"/相对路径", component:页面组件对象名},
	//...
]

3). 再创建路由器对象

var router=new VueRouter({ routes })

c. 先引入唯一完整的HTML页面中:

d. 必须将router对象加入到new Vue()中,router对象才有权修改页面中的内容。

new Vue({
	el:"#app",
	router
})

e. 在唯一完整的HTML页面中<div id="app">内,添加<router-view></router-view>标签,用于为将来的页面组件占位。

f. 结果: 路由器对象三大功能

  1. 监视地址栏变化

  2. 查找当前路径对应的页面组件是谁

  3. 将找到的页面组件替换到<router-view>的位置

  4. 创建除页面以外的其它全局组件或子组件: (页头)

a. 所有不足以成为一个页面的组件片段都要集中创建在components文件夹中

b. 所有的组件,暂时都创建为子组件,且都要在唯一完整的HTML页面中引入

c. 如果是全局组件,则只要在new Vue()之前,使用Vue.component()将子组件对象转为全局组件即可。

Vue.component("组件标签名", 组件对象名);

d. 2种情况:

1). 如果所有页面都需要显示页头,则只要在<router-view>上方添加<页头组件>标签即可

2). 如果有的页面有页头,有的页面不需要页头,就应该只在那些需要页头的组件中添加<页头组件>。不需要页头的组件,就不要加组件标签。

7.示例: 实现单页面应用:

SPA1.png

SPA2.png

SPA3.png

SPA4.png