今日内容详细:
- 组件化开发
- Vue自动化工具的安装
- 单文件组件的使用
- template
- script
- style
- 案例-点击加减数字
- 组件的嵌套
- 练习:选项卡和天气系统的封装
5. 组件化开发
5.1 组件[component]
组件(Component)是自定义封装的功能。在前端开发过程中,经常出现多个网页的功能是重复的,而且很多不同的页面之间,也存在同样的功能。
而在网页中实现一个功能,需要使用html定义功能的内容结构,使用css声明功能的外观样式,还要使用js来定义功能的特效,因此就产生了把一个功能相关的[HTML、css和javascript]代码封装在一起组成一个整体的代码块封装模式,我们称之为“组件”。
所以,组件就是一个html网页中的功能,一般就是一个标签,标签中有自己的html内容结构,css样式和js特效。
这样,前端人员就可以在组件化开发时,只需要书写一次代码,随处引入即可使用。
vue的组件有两种:默认组件[全局组件] 和 单文件组件
5.1.1 默认组件
<!DOCTYPE html>
6. Vue自动化工具(Vue-cli)
前面学习了普通组件以后,接下来我们继续学习单文件组件则需要提前先安装准备一些组件开发工具。否则无法使用和学习单文件组件。
一般情况下,单文件组件,我们运行在 自动化工具vue-CLI中,可以帮我们把单文件组件编译成普通的js代码。所以我们需要在系统中先搭建vue-CLI工具,
官网:https://cli.vuejs.org/zh/
Vue CLI 需要 Node.js 8.9 或更高版本 (推荐 8.11.0+)。你可以使用 nvm 或 nvm-windows在同一台电脑中管理多个 Node 版本。
nvm工具的下载和安装: https://www.jianshu.com/p/d0e0935b150a
https://www.jianshu.com/p/622ad36ee020
安装记录:
打开:https://github.com/coreybutler/nvm-windows/releases
安装完成以后,先查看环境变量是否设置好了.
常用的nvm命令
nvm list # 列出目前在nvm里面安装的所有node版本
nvm install node版本号 # 安装指定版本的node.js
nvm uninstall node版本号 # 卸载指定版本的node.js
nvm use node版本号 # 切换当前使用的node.js版本
如果使用nvm工具,则直接可以不用自己手动下载,如果使用nvm下载安装 node的npm比较慢的时候,可以修改nvm的配置文件(在安装根目录下)
# settings.txt
root: C:toolnvm [这里的目录地址是安装nvm时自己设置的地址,要根据实际修改]
path: C:toolnodejs
arch: 64
proxy: none
node_mirror: http://npm.taobao.org/mirrors/node/
npm_mirror: https://npm.taobao.org/mirrors/npm/
6.1 安装node.js
Node.js是一个新的后端(后台)语言,它的语法和JavaScript类似,所以可以说它是属于前端的后端语言,后端语言和前端语言的区别:
- 运行环境:后端语言一般运行在服务器端,前端语言运行在客户端的浏览器上
- 功能:后端语言可以操作文件,可以读写数据库,前端语言不能操作文件,不能读写数据库。
我们一般安装LTS(长线支持版本 Long-Time Support):
下载地址:https://nodejs.org/en/download/【上面已经安装了nvm,那么这里不用手动安装了】
node.js的版本有两大分支:
官方发布的node.js版本:0.xx.xx 这种版本号就是官方发布的版本
社区发布的node.js版本:xx.xx.x 就是社区开发的版本
Node.js如果安装成功,可以查看Node.js的版本,在终端输入如下命令:
node -v
6.2 npm
在安装node.js完成后,在node.js中会同时帮我们安装一个npm包管理器npm。我们可以借助npm命令来安装node.js的包。这个工具相当于python的pip管理器。
npm install -g 包名 # 安装模块 -g表示全局安装,如果没有-g,则表示在当前项目安装
npm list # 查看当前目录下已安装的node包
npm view 包名 engines # 查看包所依赖的Node的版本
npm outdated # 检查包是否已经过时,命令会列出所有已过时的包
npm update 包名 # 更新node包
npm uninstall 包名 # 卸载node包
npm 命令 -h # 查看指定命令的帮助文档
6.3 安装Vue-cli
npm install -g vue-cli
如果安装速度过慢,一直超时,可以考虑切换npm镜像源:http://npm.taobao.org/
vue -V 查看版本
6.4 使用Vue-CLI初始化创建前端项目
6.4.1 生成项目目录
使用vue自动化工具可以快速搭建单页应用项目目录。
该工具为现代化的前端开发工作流提供了开箱即用的构建配置。只需几分钟即可创建并启动一个带热重载、保存时静态检查以及可用于生产环境的构建配置的项目:
// 生成一个基于 webpack 模板的新项目
vue init webpack 项目目录名
例如:
vue init webpack myproject
// 启动开发服务器 ctrl+c 停止服务
cd myproject
npm run dev # 运行这个命令就可以启动node提供的测试http服务器
运行了上面代码以后,终端下会出现成功效果:
那么访问:http://localhost:8080/
6.4.2 项目目录结构
直接通过pycharm打开创建的文件夹
启动vue项目
vue执行流程
src 主开发目录,要开发的单文件组件全部在这个目录下的components目录下
static 静态资源目录,所有的css,js文件放在这个文件夹
dist项目打包发布文件夹,最后要上线单文件项目文件都在这个文件夹中[后面打包项目,让项目中的vue组件经过编译变成js 代码以后,dist就出现了]
这个是编译后生成的代码的目录
node_modules目录是node的包目录,
这个目录是可以删除之后找回的,记住文件目录,在项目目录下pycharm里用npm install命令找回
config是配置目录,
autoOpenBrowser: true, //项目重启 是否自动在浏览器中打开项目,true表示自动打开
build是项目打包时依赖的目录(编译配置目录,就是vue格式编译成普通的js格式)
src/router 路由,后面需要我们在使用Router路由的时候,自己声明.
在cmd创建时有个选项是询问是否创建这个目录,这个目录就是编写路由的
index.html是前端的总文件
src/components/main:里面是给index用的,代码如下:
import Vue from 'vue' // 基于node_modules目录中保存的目录名
import App from './App' // 基于当前文件(components)相对路径 ./
// .一点表示当前目录, ..两点表示上一级目录
// 前端导包写法,导入模块
// import 对象/类 from "目录路劲"
// 结尾是vue或者js的时候,可以不写后缀
Vue.config.productionTip = false
/* eslint-disable no-new */
// 在这里已经创建好vue对象了
new Vue({
el: '#app',
render: h => h(App)
})
App.vue
<template>
<!-- template有且只有一个大标签-->
<!-- 这里面放页面的内容-->
<div>
<Helloworld/>
</div>
</template>
<script>
这里放js
可以导入文件
import HelloWorld from './components/HelloWorld'
export default {
name: 'App',
components: {
Helloworld
}
</script>
<style>
这里放css
</style>
在src/components文件夹下创建Home.vue文件,写完导入到App.vue里面
一个vue文件操作一个vue对象,一个vue对象操作一个div标签
<template>
<!-- 这里面有且只有一个div双标签-->
<div>
Home里面的东西
</div>
</template>
<script>
// 抛出对象,只有通过export关键字抛出的对象,才能被其他的js文件导入
export default {
name: "Home"
}
</script>
<style scoped>
div{
color: red;
}
</style>
加载一个组件的的内容显示到页面中,需要三个步骤
1.在App中导入组件, import Home form "./components/Home"
2.注册组件
3.调用组件名
App.vue
<template>
<div id="app">
<h1>App组件的文本内容</h1>
<input type="text">
<!-- 3.调用组件名-->
<!-- 两种写法-->
<Home></Home>
<Home/>
</div>
</template>
<script>
// 1.导入组件名
import Home from "./components/Home"
export default {
name: 'App',
components: { // 2.注册组件
Home
}
}
</script>
<style scoped>
/*直接在style标签写css样式,默认是全局样式,所有的组件都被css渲染*/
/*为了保证css在各个组件相互独立,不会相互影响,我们需要编写局部css样式*/
/*编写局部css样式,只允许在当前组件中使用,可以给组件的style标签加上scoped*/
</style>
写样式的话,写组件文件里面,并且给style里面 加scoped
导入数据
1.新建一个js文件,名称为settings.js
export default {
url: "http://baidu.com"
};
2.在主文件App.vue里面
<template>
<div id="app"></div>>
</template>
<script>
import settings from "./settings" // 导入文件,第一个settings是as的意思
export default {
name: 'App',
components: {},
created() {
console.log(settings.url) // 用的时候直接用settings.url
}
}
</script>
<style scoped>
</style>
3.在App.vue中使用
<template>
<div id="app">
<input type="text" v-model="urll">
</div>
</template>
<script>
import settings from "./settings"
export default {
name: 'App',
data(){
return{
urll : '',
}
},
components: {},
created() {
console.log(settings.url);
this.urll = settings.url
},
}
</script>
<style scoped>
</style>
6.4.3 项目执行流程图
整个项目是一个主文件index.html,index.html中会引入src文件夹中的main.js,main.js中会导入顶级单文件组件App.vue,App.vue中会通过组件嵌套或者路由来引用components文件夹中的其他单文件组件。
7. 单文件组件的使用
组件有两种:普通组件、单文件组件
普通组件的缺点:
- html代码是作为js的字符串进行编写,所以组装和开发的时候不易理解,而且没有高亮效果。
- 普通组件用在小项目中非常合适,但是复杂的大项目中,如果把更多的组件放在html文件中,那么维护成本就会变得非常昂贵。
- 普通组件只是整合了js和html,但是css代码被剥离出去了。使用的时候的时候不好处理。
将一个组件相关的html结构,css样式,以及交互的JavaScript代码从html文件中剥离出来,合成一个文件,这种文件就是单文件组件,相当于一个组件具有了结构、表现和行为的完整功能,方便组件之间随意组合以及组件的重用,这种文件的扩展名为“.vue”,比如:"Home.vue"。
- 创建组件
在组件中编辑三个标签,编写视图、vm对象和css样式代码。
7.1 template 编写html代码的地方
<template>
<div id="Home">
<span @click="num--" class="sub">-</span>
<input type="text" size="1" v-model="num">
<span @click="num++" class="add">+</span>
</div>
</template>
7.2 script编写vue.js代码
<script>
export default {
name:"Home",
data: function(){
return {
num:0,
}
}
}
</script>
7.3 style编写当前组件的样式代码
<style scoped>
.sub,.add{
border: 1px solid red;
padding: 4px 7px;
}
</style>
7.4 完成案例-点击加减数字
创建Homes.vue
<template>
<div class="add_num">
<span @click="num++">+</span>
<input type="text" size="2" v-model="num">
<span @click="num--">-</span>
</div>
</template>
<script>
export default{
name:"AddNum",
data: function(){
return {
num: 0,
}
}
}
</script>
<style scoped>
.add_num{
font-size: 32px;
}
</style>
在App.vue组件中调用上面的组件
<template>
<div id="Home">
<span @click="num--" class="sub">-</span>
<input type="text" size="1" v-model="num">
<span @click="num++" class="add">+</span>
</div>
</template>
<script>
export default {
name:"Home",
data: function(){
return {
num:0,
}
}
}
</script>
<style scoped>
.sub,.add{
border: 1px solid red;
padding: 4px 7px;
}
</style>
在开发vue项目之前,需要手动把 App.vue的HelloWorld组件代码以及默认的css样式,清楚。
7.4 组件的嵌套
有时候开发vue项目时,页面也可以算是一个大组件,同时页面也可以分成多个子组件.
因为,产生了父组件调用子组件的情况.
例如,我们可以声明一个组件,作为父组件
在components/创建一个保存子组件的目录HomeSon
在HomeSon目录下,可以创建当前页面的子组件,例如,是Menu.vue
// 组件中代码必须写在同一个标签中
<template>
<div id="menu">
<span>{{msg}}</span>
<div>hello</div>
</div>
</template>
<script>
export default {
name:"Menu",
data: function(){
return {
msg:"这是Menu组件里面的菜单",
}
}
}
</script>
然后,在父组件中调用上面声明的子组件。
最后,父组件被App.vue调用.就可以看到页面效果.
效果:
练习:选项卡和天气系统
Card.vue
<template>
<div id="card">
<div class="title">
<span :class="num==0?'current':''" @click="num=0">国内新闻</span>
<span :class="num==1?'current':''" @click="num=1">国际新闻</span>
<span :class="num==2?'current':''" @click="num=2">银河新闻</span>
<!--<span>{{num}}</span>-->
</div>
<div class="content">
<div class="list" :class="num==0?'active':''">国内新闻列表</div>
<div class="list" :class="num==1?'active':''">国际新闻列表</div>
<div class="list" :class="num==2?'active':''">银河新闻列表</div>
</div>
</div>
</template>
<script>
export default {
name: "Card",
data(){
return {
num: 0,
}
},
}
</script>
<style scoped>
#card{
width: 500px;
height: 350px;
}
.title{
height:50px;
}
.title span{
width: 100px;
height: 50px;
background-color:#ccc;
display: inline-block;
line-height: 50px; /* 设置行和当前元素的高度相等,就可以让文本内容上下居中 */
text-align:center;
}
.content .list{
width: 500px;
height: 300px;
background-color: yellow;
display: none;
}
.content .active{
display: block;
}
.title .current{
background-color: yellow;
}
</style>
Weather.vue
<template>
<div id="app">
<p>输入城市查看天气:
<input type="text" v-model="city">
<button @click="sele">点我</button>
<span v-show="is_show" style="color: red">{{war}}</span>
</p>
<table>
<thead>
<tr>
<td>日期</td>
<td>最高温度</td>
<td>最低温度</td>
<td>风向</td>
<td>天气</td>
</tr>
</thead>
<tbody>
<tr>
<td>{{yesday.date}}</td>
<td>{{yesday.high}}</td>
<td>{{yesday.low}}</td>
<td>{{yesday.fx}}</td>
<td>{{yesday.type}}</td>
</tr>
<tr v-for="x in mylist">
<td>{{x.date}}</td>
<td>{{x.high}}</td>
<td>{{x.low}}</td>
<td>{{x.fx}}</td>
<td>{{x.type}}</td>
</tr>
</tbody>
</table>
</div>
</template>
<script>
export default {
name: "Weather",
data(){
return{
city: '',
mylist : null,
war: '',
is_show: false,
yesday: '',
}
},
methods:{
sele(){
this.$axios.get('http://wthrcdn.etouch.cn/weather_mini',{
params: {
'city': this.city
}
}
).then(
response=>{
this.mylist = response.data.data.forecast;
this.yesday = response.data.data.yesterday;
console.log(this.mylist)
}
).catch(
error=>{
this.is_show = true;
this.war = '请求失败啦,弟弟'
}
)
}
}
}
</script>
<style scoped>
</style>
App.vue
<template>
<div id="app">
<!--1. 把课堂案例选项卡封装成组件,组件名:Card.vue-->
<Card></Card>
<!--2. 把课堂案例获取天气封装成组件,组件名:Weather.vue-->
<Weather></Weather>
</div>
</template>
<script>
import Card from "./components/Card"
import Weather from "./components/Weather"
export default {
name: 'App',
components: {
Card,
Weather,
},
}
</script>
<style scoped>
</style>