Vue组件是Vue.js最强大的功能之一,把页面抽象成一颗组件树,这颗树由独立的可复用的小组件构成!
组件(component)
组件(Component)是自定义封装的功能。在前端开发过程中,经常出现多个网页的功能是重复的,而且很多不同的页面之间,也存在同样的功能。
而在网页中实现一个功能,需要使用html定义功能的内容结构,使用css声明功能的外观样式,还要使用js来定义功能的特效,因此就产生了把一个功能相关的[HTML、css和javascript]代码封装在一起组成一个整体的代码块封装模式,我们称之为“组件”。
- 所以,组件就是一个html网页中的功能,一般就是一个标签,标签中有自己的html内容结构,css样式和js特效。就如下图中页面像一个拼图,每一个组件是一块小的拼图,来构成整个页面。
- 将页面抽象为一颗组件树,由一个根组件以及独立的,可复用的小组件构成。
- vue的组件有两种:默认组件[全局组件] 和 单文件组件
默认组件(全局组件)
组件名称命名建议:驼峰体!
格式为:
1 | Vue.component("组件名称", { |
- 在我们使用
Vue.component
定义了全局组件后,还需要用new Vue({ el: '#container '})
在每个页面内指定一个容器元素。 - 与我们定义vm对象中的data有所差别,这里的data的属性是函数,返回值必须是json对象。
例子:
1 | <div id="container"> |
全局组件的优点在于简单上手,适用于小规模项目,但它的缺点也非常明显:
- 全局定义 (Global definitions) 强制要求每个 component 中的命名不得重复
- 字符串模板 (String templates) 缺乏语法高亮,在 HTML 有多行的时候,需要用到丑陋的
\
- 不支持 CSS (No CSS support) 意味着当 HTML 和 JavaScript 组件化时,CSS 明显被遗漏
- 没有构建步骤 (No build step) 限制只能使用 HTML 和 ES5 JavaScript, 而不能使用预处理器,如 Pug (formerly Jade) 和 Babel
单文件组件
单文件组件(single-file components)的文件扩展名为
.vue
,它解决了全局组件存在的问题,并且还可以使用 webpack 或 Browserify 等构建工具。在介绍单文件组件之前,我们需要安装准备一些组件开发工具,一般情况下,单文件组件,我们运行在自动化工具 Vue-cli 中
准备工作
已经配置好的,这块可以跳过。
如果没有配置的推荐阅读 [Ubuntu安装Vue-cli](待补充!!!
Vue自动化工具(Vue-cli)
vue-cli 是脚手架工具,其作用就是用配置好的模板迅速搭建起一个前端项目工程
创建前端项目
生成项目目录
使用vue自动化工具可以快速搭建单页应用项目目录。
该工具为现代化的前端开发工作流提供了开箱即用的构建配置。只需几分钟即可创建并启动一个带热重载、保存时静态检查以及可用于生产环境的构建配置的项目:
生成一个基于 webpack 模板的新项目:
1 | vue init webpack 项目目录名 |
例如:
进入项目目录可以启动开发服务器, ctrl+c 停止服务:
1 | cd myproject |
简化操作:
当我们修改内容后就需要手动关闭,然后手动开启,这样太过繁琐。使用 pycharm 来简化操作:
这样只需要点击绿三角,启动后,当我们修改了内容,pycharm会自动重新执行。
项目目录结构
1 | |-- build // 项目构建(webpack)相关代码:开发/生产环境 |
项目执行流程图
整个项目是一个主文件
index.html
index.html
中会引入src文件夹中的main.js
main.js
中会导入顶级单文件组件App.vue
App.vue
中会通过组件嵌套或者路由来引用 components 文件夹中的其他单文件组件。
单文件组件的使用
template 编写html代码的地方
1 | <template> |
note:只能有一个根标签,其它标签都写在根标签下
script编写vue.js代码
1 | <script> |
note:
- 在这里 export default 只能有一个。
- data是一个函数,返回的是一个json对象。
style编写当前组件的样式代码
1 | <style scoped> |
note:scoped是为了保证只在当前组件范围内生效。
完整例子:点击加减数字
上面的三块是对于当前组件的定义,那么如何调用这个组件呢?
在 App.vue 中调用这个组件:
- 导入组件,注册组件,使用标签。
1 | <template> |
组件的嵌套
一个页面是一颗组件树,对于组件特别复杂时,我们可以把子组件分目录存储:将父组件下的子组件存在一个目录下。
例如,我们可以声明一个组件,作为父组件(Home),在components/创建一个保存子组件的目录HomeSon,这里存放的是 Home 组件的子组件。
传递数据
父组件的数据传递给子组件
① 父组件中通过子组件标签的属性来传递数据:
1 | <Menu :sonnum="num" title="这是:父组件传递给子组件的字符串数据"/> |
上面表示在父组件调用Menu子组件的时候传递了2个数据:
如果要传递变量[变量可以各种类型的数据],属性名左边必须加上冒号
:
,同时,属性名是自定义的,会在子组件中使用。如果要传递普通字符串数据,则不需要加上冒号:
② 子组件通过 props
来接接收数据:
1 | <script> |
③ 对于接收到的数据,按使用data中的变量使用就可以:
1 | <template> |
note:
传递数据是变量,则需要在属性左边添加冒号.
传递数据是变量,这种数据称之为”动态数据传递“
传递数据不是变量,这种数据称之为”静态数据传递“
父组件中修改了数据,在子组件中会被同步修改,但是,子组件中的数据修改了,是不是影响到父组件中的数据.
- 这种情况,在开发时,也被称为”单向数据流“
子组件传递数据给父组件
① 子组件监听父组件传来的变量,如果在子组件中改变这个变量的值,就使用 this.$emit("父元素的自定义事件","要传递的数据");
来向父组件提交这个改变的数据[事件的方式进行传递]。
例中,使用 $emit 提交的事件名称为:sendparentdata
。
1 | <template> |
② 父组件中,声明一个和子组件中this.$emit("自定义事件名称")
对应的事件属性。
例中,使用子组件中的同名事件 sendparentdata
1 | <Menu :sonnum="num" title="这是:父组件传递给子组件的字符串数据" @sendparentdata="getnum"/> |
③ 父组件中,声明一个自定义方法,在事件被调用时执行。
例中,自定义 getnum
方法,需要使用参数(sondata
)接收传递过来的数据,然后赋给父组件的变量就可以
1 | <template> |
在组件中使用axios获取数据
全局组件
- 在全局组件的方法中使用
axios.get
发送 ajax 请求即可。
1 | <div id="app"> |
单文件组件
- 只需要在事件的定义中,使用
axios.get
来发送 ajax 请求
1 | <!--Getweather.vue--> |