- A+
一篇文章带你了解网页框架——Vue简单入门
这篇文章将会介绍我们前端入门级别的框架——Vue的简单使用
如果你以后想从事后端程序员,又想要稍微了解前端框架知识,那么这篇文章或许可以给你带来帮助
温馨提醒:在学习该文章前,请先学习HTML,CSS,JavaScript,Ajax等前端知识
Vue基础
首先,我们从官方文档中可以得到下述描述:
- Vue是一套用于构建用户界面的渐进式框架。
- Vue的核心库只关注视图层,不仅易于上手,还便于与第三方库或既有项目整合。
- 另一方面,当与现代化的工具链以及各种支持类库结合使用时,Vue 也完全能够为复杂的单页应用提供驱动。
其中我们需要格外注意的是:
- Vue只负责前端页面的设计,并不能完全实现前端的所有功能
Vue主要特点:
-
采用JavaScript框架
-
简化Dom操作
-
响应式数据驱动
VsCode插件推荐
在正式开始介绍Vue之前,我想向大家安利一个VsCode插件——Live Server
Live Server 插件可以同步代码和网页的更新:
- 当你保存代码时,你的页面将会同步进行刷新,省略了手动点击页面的步骤,在开发中提供便利
Vue代码框架
首先我们需要学会Vue的基本使用
- 导入相关包
<!--Vue为我们提供了两个版本,我们通常采用开发环境版本,具有检错功能便于学习--> <!-- 开发环境版本,包含了有帮助的命令行警告 --> <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script> <!-- 生产环境版本,优化了尺寸和速度 --> <script src="https://cdn.jsdelivr.net/npm/vue"></script>
- 基本框架使用
<!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>Vue基础</title> </head> <body> <!--首先我们创建一个div,并绑定id为app--> <div id="app"> <!--我们采用{{}}来调用相关Vue中的data中存放的数据--> {{ message }} </div> <!-- 导入vue:开发环境版本,包含了有帮助的命令行警告 --> <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script> <!--书写js代码--> <script> <!-- 以下为vue基本框架 new Vue({el,data,method})--> var app = new Vue({ <!--el实现挂载点--> el:"#app", <!--data存放相关数据--> data:{ <!--数据属性--> message:" 你好 小黑! " } }) </script> </body> </html>
EL挂载点介绍
学习过Vue的基本使用后,我们先对EL挂载点做出最基本的介绍:
- EL挂载点负责设置页面中属性与Vue属性的连接
- EL挂载点设置后,页面属性可以调用Vue中的数据(data)和方法(method)
EL挂载点注意点:
- Vue的作用范围在EL挂载点的本体元素以及后代元素中
- Vue的EL挂载点可以依赖于各种选择器,例如类选择器等,但推荐使用ID选择器
- Vue的EL挂载点不可以作用在HTML和BODY两个页面最大元素上
我们给出简单示例:
<!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>el:挂载点</title> </head> <body id="body"> <!--这里的{{ message }}不会有所显示,因为未与Vue连接--> {{ message }} <h2 id="app" class="app"> <!-- 这里的{{ message }}会显示,因为属于Vue连接本体--> {{ message }} <!-- 这里的{{ message }}会显示,因为属于Vue连接后代元素--> <span> {{ message }} </span> </h2> <!-- 开发环境版本,包含了有帮助的命令行警告 --> <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script> <script> var app = new Vue({ // 以下均可使用, // el:"#app", // el:".app", // el:"div", // body无法连接 el:"#body", data:{ message:"秋落" } }) </script> </body> </html>
Data数据对象介绍
学习过Vue的基本使用后,我们对Data做出最基本的介绍:
- Data用于存储页面元素中使用的各类属性
- 属性可以包括各种类型,例如文本,数组等复杂类型
- 渲染复杂类型数据时,遵循JavaScript的语法基本都可以使用
我们给出简单示例:
<!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>data:数据对象</title> </head> <body> <div id="app"> <!--使用{{}}调用data数据--> {{ message }} <!--对象采用.来调用内部元素--> <h2> {{ school.name }} {{ school.mobile }}</h2> <ul> <!--数组采用[index]来选择内部元素--> <li>{{ campus[0] }}</li> <li>{{ campus[3] }}</li> </ul> </div> <!-- 开发环境版本,包含了有帮助的命令行警告 --> <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script> <script> var app = new Vue({ el:"#app", data:{ message:"你好!", school:{ name:"河南师范大学", mobile:"0373-3325000" }, campus:["东校区","西校区","新乡校区","平原湖校区"] } }) </script> </body> </html>
Vue本地应用
在介绍了Vue的基本使用后,我们针对Vue内部的各种属性方法来做出一一介绍
每条属性或方法我们都会给出解释和相关案例
v-text
文本解释:
v-text:设置标签的文本值
代码解释:
<!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>v-text指令</title> </head> <body> <div id="app"> <!--我们采用v-text来设置标签内文本,注意会覆盖掉内部文本,“深圳”将不再显示--> <h2 v-text="message+'!'">深圳</h2> <h2 v-text="info+'!'">深圳</h2> <!--另一种文本书写方式{{}}--> <h2>{{ message +'!'}}深圳</h2> </div> <!-- 开发环境版本,包含了有帮助的命令行警告 --> <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script> <script> var app = new Vue({ el:"#app", data:{ message:"河南师范大学", info:"软件学院" } }) </script> </body> </html>
v-html
文本解释:
v-html:以html的格式来设置标签的文本值
代码解释:
<!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>v-html指令</title> </head> <body> <!--v-html:设置元素的innerHTML--> <!--采用v-html后显示的是河南师范大学的加粗版,但采用v-text后显示的是<strong>河南师范大学</strong>--> <div id="app" v-html="context"> </div> <!-- 开发环境版本,包含了有帮助的命令行警告 --> <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script> <script> var app = new Vue({ el:"#app", data:{ content:"<strong>河南师范大学</strong>" } }) </script> </body> </html>
v-on
文本解释:
v-on:为元素绑定事件,可以采用@代替
代码解释:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>v-on</title> </head> <body> <div id="app"> <!--v-on:后面跟事件名 用于绑定事件 可以用@代替 后面用methods中的方法即可--> <input type="button" value="点击" v-on:click="doIt"> <input type="button" value="点击" @click="doIt"> </div> <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script> <script> var app = new Vue({ el:"#app", methods:{ doIt:function(){ alert("河南师范大学"); } } }) </script> </body> </html>
v-show
文本解释:
v-show:根据表达值的真假,切换元素的显示和隐藏(隐藏后源代码仍存在)
代码解释:
<!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>v-show指令</title> </head> <body> <div id="app"> <!--点击后改变isShow的值,将isShow变为true或false,以此控制img的显示与隐藏--> <input type="button" value="切换显示状态" @click="changeIsShow"> <!--点击增加年龄值--> <input type="button" value="累加年龄" @click="addAge"> <!--v-show用于控制元素的存在或隐藏,这里采用isShow变量,根据isShow的值来判断是否存在--> <img v-show="isShow" src="./img/monkey.gif" alt="一篇文章带你了解网页框架——Vue简单入门" alt=""> <!--根据年龄值大小控制元素的存在或隐藏,只是为了表示v-show的参数需要是一个true或false的判定--> <img v-show="age>=18" src="./img/monkey.gif" alt="一篇文章带你了解网页框架——Vue简单入门" alt=""> </div> <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script> <script> var app = new Vue({ el:"#app", data:{ isShow:false, age:17 }, methods: { // 进行 isShow 的true或false更改 changeIsShow:function(){ this.isShow = !this.isShow; }, addAge:function(){ this.age++; } }, }) </script> </body> </html>
v-if
文本解释:
v-if:根据表达值的真假,切换元素的显示和隐藏(隐藏后,源代码不存在)
代码解释:
<!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>v-if指令</title> </head> <body> <div id="app"> <!--以下操作实际效果同v-show相同,但隐藏后在页面的展示栏中无法看到源代码,属于彻底隐藏--> <input type="button" value="切换显示" @click="toggleIsShow"> <p v-if="isShow">河南师范大学</p> <p v-show="isShow">河南师范大学 - v-show修饰</p> <h2 v-if="temperature>=35">热死啦</h2> </div> <!-- 开发环境版本,包含了有帮助的命令行警告 --> <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script> <script> var app = new Vue({ el:"#app", data:{ isShow:false, temperature:20 }, methods: { toggleIsShow:function(){ this.isShow = !this.isShow; } }, }) </script> </body> </html>
v-bind
文本解释:
v-bind:设置元素的属性(比如:src,title。class)
代码解释:
<!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>v-bind指令</title> <style> .active{ border: 1px solid red; } </style> </head> <body> <!--v-bind通常可以隐藏,直接写 :属性 即可--> <div id="app"> <!--这里采用v-bind设置页面图片--> <img v-bind:src="imgSrc" alt=""> <br> <!--这里采用v-bind略写方式设置页面图片,后面采用 data 变量控制图片展示--> <!--同样采用v-bind控制title,class等属性,采用三元运算符来控制active--> <img :src="imgSrc" alt="" :title="imgTitle+'!!!'" :class="isActive?'active':''" @click="toggleActive"> <br> <!--通过点击事件来控制class--> <img :src="imgSrc" alt="" :title="imgTitle+'!!!'" :class="{active:isActive}" @click="toggleActive"> </div> <!-- 开发环境版本,包含了有帮助的命令行警告 --> <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script> <script> var app = new Vue({ el:"#app", data:{ imgSrc:"https://www.ztsky.cn/wp-content/uploads/2022/10/logo.png" alt="一篇文章带你了解网页框架——Vue简单入门", imgTitle:"黑马程序员", isActive:false }, methods: { toggleActive:function(){ this.isActive = !this.isActive; } }, }) </script> </body> </html>
v-for
文本解释:
v-for:根据数据生成列表结构
代码解释:
<!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>v-for指令</title> </head> <body> <div id="app"> <!--简单的添加删除操作,针对h2的数据--> <input type="button" value="添加数据" @click="add"> <input type="button" value="移除数据" @click="remove"> <ul> <!--简单v-for,参数为(数据名称[任起],下标[index]) in data数组--> <li v-for="(it,index) in arr"> <!--在内部,可以使用数据名称和下标值--> {{ index+1 }}城市推荐:{{ it }} </li> </ul> <!--数组中装有对象也是同样的使用方法--> <h2 v-for="item in vegetables" v-bind:title="item.name"> {{ item.name }} </h2> </div> <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script> <script> var app = new Vue({ el:"#app", data:{ arr:["北京","上海","广州","深圳"], vegetables:[ {name:"鱼"}, {name:"鸡"} ] }, methods: { add:function(){ this.vegetables.push({ name:"红烧鱼" }); }, remove:function(){ this.vegetables.shift(); } }, }) </script> </body> </html>
v-on+
文本解释:
v-on+:补充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>v-on补充</title> </head> <body> <div id="app"> <!--方法中可以携带参数,正常调用即可--> <input type="button" value="点击" @click="doIt(666,'老铁')"> <!--可以选取事件的部分事件做反应,例如@keyup.enter就是点击enter键生效,我们通常采用"."来表示事件限制--> <input type="text" @keyup.enter="sayHi"> </div> <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script> <script> var app = new Vue({ el:"#app", methods: { doIt:function(p1,p2){ console.log("做it"); console.log(p1); console.log(p2); }, sayHi:function(){ alert("吃了没"); } }, }) </script> </body> </html>
v-model
文本解释:
v-model:实现双向绑定,便捷设置
代码解释:
<!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>v-model指令</title> </head> <body> <div id="app"> <!--点击按钮实现setM方法--> <input type="button" value="修改message" @click="setM"> <!--我们将文本内容与message数据双向绑定--> <!--当我们修改文本的值时,VsCode中的代码不会发生变化,但实际上message已经发生变化,我们将message的值单独列出来--> <input type="text" v-model="message" @keyup.enter="getM"> <!--当上述message发生改变时,message本身发生变化,那么调用它的显示值也发生变化--> <h2>{{ message }}</h2> </div> <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script> <script> var app = new Vue({ el:"#app", data:{ message:"河南师范大学" }, methods: { getM:function(){ alert(this.message); }, setM:function(){ this.message ="软件学院"; } }, }) </script> </body> </html>
案例:计算器
下面我们通过一个案例来巩固前面所学习的一些知识点
案例要求:
- 我们希望通过"-"和"+"控制中间数字的大小(最小为0,最大为10)
知识点复习:
- EL挂载点,Data数据,Methods方法
- v-on,v-text方法
代码展示:
<!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>计算器</title> <!--css配置--> <style> #app { width: 480px; height: 100px; margin: 200px auto; } .input-num { margin-top: 20px; height: 100%; display: flex; border-radius: 10px; overflow: hidden; box-shadow: 0 0 4px black; } .input-num button { width: 150px; height: 100%; font-size: 40px; color: gray; cursor: pointer; border: none; outline: none; } .input-num span { height: 100%; font-size: 40px; flex: 1; text-align: center; line-height: 100px; } </style> </head> <body> <!--index主页--> <!--设置Vue的id绑定--> <div id="app"> <img src="https://www.ztsky.cn/wp-content/uploads/2022/10/logo.png" alt="一篇文章带你了解网页框架——Vue简单入门" alt="" /> <!-- 计数器 --> <div class="input-num"> <!--绑定事件sub--> <button @click="sub"> - </button> <!--数字展示--> <span>{{ num }}</span> <!--绑定事件add--> <button @click="add"> + </button> </div> </div> </body> </html> <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script> <!-- 编码 --> <script> /* 1. data中定义num属性,类型是数字,渲染到2个按钮中间 2. 减号绑定点击事件,对应的方法名叫sub,大于0之前递减 3. 加号绑定点击事件,对应的方法名叫add,小于0之前累加 */ // 创建Vue实例 var app = new Vue({ el: "#app", data: { // 修改的数字 num:1 }, methods: { // 减 sub:function(){ // 递减 if(this.num>0){ this.num--; }else{ alert("数字最小为0"); } }, // 加 add:function(){ // 累加 if(this.num<10){ this.num++; }else{ alert("数字最大为10"); } } } }); </script>
案例:图片切换
下面我们通过一个案例来巩固前面所学习的一些知识点
案例要求:
- 我们通过点击左右两边的图片切换符号来切换中间图片
知识点复习:
- EL挂载点,Data数据,Methods方法
- v-on,v-show,v-bind方法
代码展示:
<!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> <!--css样式在下面单列--> <link rel="stylesheet" href="./css/index.css" /> </head> <body> <div id="mask"> <div class="center"> <h2 class="title"><img src="./images/logo.png" alt="一篇文章带你了解网页框架——Vue简单入门" alt=""> 学校环境 </h2> <!--展示图片,切换的中心点--> <img :src="imgList[index]" alt="" /> <!--左转图片--> <!--添加绑定事件prev,用于图片的切换--> <!--添加v-show,当左侧无图片时,隐藏--> <a href="javascript:void(0)" @click="prev" class="left" v-show="index>0" > <img src="./images/prev.png" alt="一篇文章带你了解网页框架——Vue简单入门" alt="" /> </a> <!--右转图片--> <!--添加绑定事件right,用于图片的切换--> <!--添加v-show,当右侧无图片时,隐藏--> <a href="javascript:void(0)" @click="next" class="right" v-show="index<imgList.length-1" > <img src="./images/next.png" alt="一篇文章带你了解网页框架——Vue简单入门" alt="" /> </a> </div> </div> <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script> <script> const app = new Vue({ el: "#mask", data: { // 图片元素 imgList: [ "./images/00.jpg" alt="一篇文章带你了解网页框架——Vue简单入门", "./images/01.jpg", "./images/02.jpg", "./images/03.jpg", "./images/04.jpg", "./images/05.jpg", "./images/06.jpg", "./images/07.jpg", "./images/08.jpg", "./images/09.jpg", "./images/10.jpg", ], // 图片序号 index: 0 }, methods: { // 上一张 prev() { this.index--; }, // 下一张 next() { this.index++; } } }); </script> </body> </html>
* { margin: 0; padding: 0; } html, body, #mask { width: 100%; height: 100%; } #mask { background-color: #c9c9c9; position: relative; } #mask .center { position: absolute; background-color: #fff; left: 50%; top: 50%; transform: translate(-50%, -50%); padding: 10px; } #mask .center .title { position: absolute; display: flex; align-items: center; height: 56px; top: -61px; left: 0; padding: 5px; padding-left: 10px; padding-bottom: 0; color: rgba(175, 47, 47, 0.8); font-size: 26px; font-weight: normal; background-color: white; padding-right: 50px; z-index: 2; } #mask .center .title img { height: 40px; margin-right: 10px; } #mask .center .title::before { content: ""; position: absolute; width: 0; height: 0; border: 65px solid; border-color: transparent transparent white; top: -65px; right: -65px; z-index: 1; } #mask .center > img { display: block; width: 700px; height: 458px; } #mask .center a { text-decoration: none; width: 45px; height: 100px; position: absolute; top: 179px; vertical-align: middle; opacity: 0.5; } #mask .center a :hover { opacity: 0.8; } #mask .center .left { left: 15px; text-align: left; padding-right: 10px; border-top-right-radius: 10px; border-bottom-right-radius: 10px; } #mask .center .right { right: 15px; text-align: right; padding-left: 10px; border-top-left-radius: 10px; border-bottom-left-radius: 10px; }
案例:记事本
下面我们通过一个案例来巩固前面所学习的全部知识点
案例要求:
- 新增:书写内容,点击Enter后,便利贴放于页面
- 删除:点击内容后方的"x"号后,该内容消失
- 统计:统计内容数量,在左下角显示
- 清空:点击右下角清空键,内容全部清空
- 隐藏:当无内容时,下述记事本部分隐藏
代码展示:
<html> <head> <meta http-equiv="content-type" content="text/html; charset=UTF-8" /> <title>小黑记事本</title> <meta http-equiv="content-type" content="text/html; charset=UTF-8" /> <meta name="robots" content="noindex, nofollow" /> <meta name="googlebot" content="noindex, nofollow" /> <meta name="viewport" content="width=device-width, initial-scale=1" /> <!--css样式在下列出--> <link rel="stylesheet" type="text/css" href="./css/index.css" /> </head> <body> <!-- 主体区域 --> <section id="todoapp"> <!-- 输入框 --> <header class="header"> <h1>小黑记事本</h1> <!--输入栏,实现双向绑定,当点击时使用add方法--> <input v-model="inputValue" @keyup.enter="add" autofocus="autofocus" autocomplete="off" placeholder="请输入任务" class="new-todo" /> </header> <!-- 列表区域 --> <section class="main"> <ul class="todo-list"> <!--记事主题内容,采用v-for遍历记事内容list的内容,输出在页面--> <li class="todo" v-for="(item,index) in list"> <div class="view"> <!--记事内容--> <span class="index">{{ index+1 }}.</span> <label>{{ item }}</label> <!--删除按钮,点击时触发remove功能,参数为当前index--> <button class="destroy" @click="remove(index)"></button> </div> </li> </ul> </section> <!-- 统计和清空 --> <!--记事本主体,当不存在记事内容时,隐藏--> <footer class="footer" v-show="list.length!=0"> <span class="todo-count" v-if="list.length!=0"> <!--统计值:直接采用list的长度代替--> <strong>{{ list.length }}</strong> items left </span> <!--记事本主体,当不存在记事内容时,隐藏--> <button v-show="list.length!=0" class="clear-completed" @click="clear"> Clear </button> </footer> </section> <!-- 底部 --> <footer class="info"> <p> <a href="http://www.itheima.com/"><img src="./img/black.png" alt="一篇文章带你了解网页框架——Vue简单入门" alt="" /></a> </p> </footer> <!-- 开发环境版本,包含了有帮助的命令行警告 --> <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script> <script> var app = new Vue({ // 实现Vue绑定 el: "#todoapp", data: { // list表示记事内容 list: ["写代码", "吃饭饭", "睡觉觉"], // 表示目前输入内容,双向绑定 inputValue: "好好学习,天天向上" }, methods: { // 新添方法,将输入值填入计时内容中 add: function () { this.list.push(this.inputValue); }, // 删除方法,删除当前下表为index的内容 remove: function (index) { this.list.splice(index, 1); }, // 清除方法,清除所有方法 clear: function () { this.list = []; } }, }) </script> </body> </html>
html, body { margin: 0; padding: 0; } body { background: #fff; } button { margin: 0; padding: 0; border: 0; background: none; font-size: 100%; vertical-align: baseline; font-family: inherit; font-weight: inherit; color: inherit; -webkit-appearance: none; appearance: none; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; } body { font: 14px "Helvetica Neue", Helvetica, Arial, sans-serif; line-height: 1.4em; background: #f5f5f5; color: #4d4d4d; min-width: 230px; max-width: 550px; margin: 0 auto; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; font-weight: 300; } :focus { outline: 0; } .hidden { display: none; } #todoapp { background: #fff; margin: 180px 0 40px 0; position: relative; box-shadow: 0 2px 4px 0 rgba(0, 0, 0, 0.2), 0 25px 50px 0 rgba(0, 0, 0, 0.1); } #todoapp input::-webkit-input-placeholder { font-style: italic; font-weight: 300; color: #e6e6e6; } #todoapp input::-moz-placeholder { font-style: italic; font-weight: 300; color: #e6e6e6; } #todoapp input::input-placeholder { font-style: italic; font-weight: 300; color: gray; } #todoapp h1 { position: absolute; top: -160px; width: 100%; font-size: 60px; font-weight: 100; text-align: center; color: rgba(175, 47, 47, .8); -webkit-text-rendering: optimizeLegibility; -moz-text-rendering: optimizeLegibility; text-rendering: optimizeLegibility; } .new-todo, .edit { position: relative; margin: 0; width: 100%; font-size: 24px; font-family: inherit; font-weight: inherit; line-height: 1.4em; border: 0; color: inherit; padding: 6px; border: 1px solid #999; box-shadow: inset 0 -1px 5px 0 rgba(0, 0, 0, 0.2); box-sizing: border-box; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; } .new-todo { padding: 16px; border: none; background: rgba(0, 0, 0, 0.003); box-shadow: inset 0 -2px 1px rgba(0, 0, 0, 0.03); } .main { position: relative; z-index: 2; border-top: 1px solid #e6e6e6; } .toggle-all { width: 1px; height: 1px; border: none; /* Mobile Safari */ opacity: 0; position: absolute; right: 100%; bottom: 100%; } .toggle-all + label { width: 60px; height: 34px; font-size: 0; position: absolute; top: -52px; left: -13px; -webkit-transform: rotate(90deg); transform: rotate(90deg); } .toggle-all + label:before { content: "❯"; font-size: 22px; color: #e6e6e6; padding: 10px 27px 10px 27px; } .toggle-all:checked + label:before { color: #737373; } .todo-list { margin: 0; padding: 0; list-style: none; max-height: 420px; overflow: auto; } .todo-list li { position: relative; font-size: 24px; border-bottom: 1px solid #ededed; height: 60px; box-sizing: border-box; } .todo-list li:last-child { border-bottom: none; } .todo-list .view .index { position: absolute; color: gray; left: 10px; top: 20px; font-size: 16px; } .todo-list li .toggle { text-align: center; width: 40px; /* auto, since non-WebKit browsers doesn't support input styling */ height: auto; position: absolute; top: 0; bottom: 0; margin: auto 0; border: none; /* Mobile Safari */ -webkit-appearance: none; appearance: none; } .todo-list li .toggle { opacity: 0; } .todo-list li .toggle + label { /* Firefox requires `#` to be escaped - https://bugzilla.mozilla.org/show_bug.cgi?id=922433 IE and Edge requires *everything* to be escaped to render, so we do that instead of just the `#` - https://developer.microsoft.com/en-us/microsoft-edge/platform/issues/7157459/ */ background-image: url("data:image/svg+xml;utf8,%3Csvg%20xmlns%3D%22http%3A//www.w3.org/2000/svg%22%20width%3D%2240%22%20height%3D%2240%22%20viewBox%3D%22-10%20-18%20100%20135%22%3E%3Ccircle%20cx%3D%2250%22%20cy%3D%2250%22%20r%3D%2250%22%20fill%3D%22none%22%20stroke%3D%22%23ededed%22%20stroke-width%3D%223%22/%3E%3C/svg%3E"); background-repeat: no-repeat; background-position: center left; } .todo-list li .toggle:checked + label { background-image: url("data:image/svg+xml;utf8,%3Csvg%20xmlns%3D%22http%3A//www.w3.org/2000/svg%22%20width%3D%2240%22%20height%3D%2240%22%20viewBox%3D%22-10%20-18%20100%20135%22%3E%3Ccircle%20cx%3D%2250%22%20cy%3D%2250%22%20r%3D%2250%22%20fill%3D%22none%22%20stroke%3D%22%23bddad5%22%20stroke-width%3D%223%22/%3E%3Cpath%20fill%3D%22%235dc2af%22%20d%3D%22M72%2025L42%2071%2027%2056l-4%204%2020%2020%2034-52z%22/%3E%3C/svg%3E"); } .todo-list li label { word-break: break-all; padding: 15px 15px 15px 60px; display: block; line-height: 1.2; transition: color 0.4s; } .todo-list li.completed label { color: #d9d9d9; text-decoration: line-through; } .todo-list li .destroy { display: none; position: absolute; top: 0; right: 10px; bottom: 0; width: 40px; height: 40px; margin: auto 0; font-size: 30px; color: #cc9a9a; margin-bottom: 11px; transition: color 0.2s ease-out; } .todo-list li .destroy:hover { color: #af5b5e; } .todo-list li .destroy:after { content: "×"; } .todo-list li:hover .destroy { display: block; } .todo-list li .edit { display: none; } .todo-list li.editing:last-child { margin-bottom: -1px; } .footer { color: #777; padding: 10px 15px; height: 20px; text-align: center; border-top: 1px solid #e6e6e6; } .footer:before { content: ""; position: absolute; right: 0; bottom: 0; left: 0; height: 50px; overflow: hidden; box-shadow: 0 1px 1px rgba(0, 0, 0, 0.2), 0 8px 0 -3px #f6f6f6, 0 9px 1px -3px rgba(0, 0, 0, 0.2), 0 16px 0 -6px #f6f6f6, 0 17px 2px -6px rgba(0, 0, 0, 0.2); } .todo-count { float: left; text-align: left; } .todo-count strong { font-weight: 300; } .filters { margin: 0; padding: 0; list-style: none; position: absolute; right: 0; left: 0; } .filters li { display: inline; } .filters li a { color: inherit; margin: 3px; padding: 3px 7px; text-decoration: none; border: 1px solid transparent; border-radius: 3px; } .filters li a:hover { border-color: rgba(175, 47, 47, 0.1); } .filters li a.selected { border-color: rgba(175, 47, 47, 0.2); } .clear-completed, html .clear-completed:active { float: right; position: relative; line-height: 20px; text-decoration: none; cursor: pointer; } .clear-completed:hover { text-decoration: underline; } .info { margin: 50px auto 0; color: #bfbfbf; font-size: 15px; text-shadow: 0 1px 0 rgba(255, 255, 255, 0.5); text-align: center; } .info p { line-height: 1; } .info a { color: inherit; text-decoration: none; font-weight: 400; } .info a:hover { text-decoration: underline; } /* Hack to remove background from Mobile Safari. Can't use it globally since it destroys checkboxes in Firefox */ @media screen and (-webkit-min-device-pixel-ratio: 0) { .toggle-all, .todo-list li .toggle { background: none; } .todo-list li .toggle { height: 40px; } } @media (max-width: 430px) { .footer { height: 50px; } .filters { bottom: 10px; } }
Vue网络应用
我们在本篇开头说过Vue的作用仅仅是用来完成静态页面
所以如果想要完成项目开发功能,还需要与后台交互的技术Ajax(主要采用Axios技术)
Axios技术
Axios技术是原生的Ajax进行封装,简化书写
我们在之前的Ajax专题中有完整的介绍过Ajax和Axios技术,在这里我们仅做简单回忆:
<!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>axios基本使用</title> </head> <body> <!--两个按钮分别用来实现两种数据获取--> <input type="button" value="get请求" class="get"> <input type="button" value="post请求" class="post"> <!-- 官网提供的 axios 在线地址 --> <script src="https://unpkg.com/axios/dist/axios.min.js"></script> <script> /* 接口1:随机笑话 请求地址:https://autumnfish.cn/api/joke/list 请求方法:get 请求参数:num(笑话条数,数字) 响应内容:随机笑话 */ // 事件绑定 document.querySelector(".get").onclick = function () { // axios的get格式:get后跟url,response为返回体,err为错误 axios.get("https://autumnfish.cn/api/joke/list?num=6") .then(function (response) { console.log(response); },function(err){ console.log(err); }) } /* 接口2:用户注册 请求地址:https://autumnfish.cn/api/user/reg 请求方法:post 请求参数:username(用户名,字符串) 响应内容:注册成功或失败 */ // 事件绑定 document.querySelector(".post").onclick = function () { // axios的post格式:post后跟url和请求体,response为返回体,err为错误 axios.post("https://autumnfish.cn/api/user/reg",{username:"盐焗西兰花"}) .then(function(response){ console.log(response); console.log(this.skill); },function (err) { console.log(err); }) } </script> </body> </html>
Axios+Vue技术
我们常常用Vue作为页面的设计框架,同时采用Axios作为前后端交互的技术
两者的结合其实并没有互相掺杂,大致上还保留原本的形式,最大的改变只有数据来源发生变化
<!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>axios+vue</title> </head> <body> <div id="app"> <input type="button" value="获取笑话" @click="getJoke"> <p> {{ joke }}</p> </div> <!-- 官网提供的 axios 在线地址 --> <script src="https://unpkg.com/axios/dist/axios.min.js"></script> <!-- 开发环境版本,包含了有帮助的命令行警告 --> <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script> <script> /* 接口:随机获取一条笑话 请求地址:https://autumnfish.cn/api/joke 请求方法:get 请求参数:无 响应内容:随机笑话 */ // 采用Vue开启框架页面 var app = new Vue({ el:"#app", data:{ // 页面数据展示 joke:"很好笑的笑话" }, methods: { // 获得笑话的方法,采用axios技术进行数据请求 getJoke:function(){ var that = this; axios.get("https://autumnfish.cn/api/joke").then(function(response){ console.log(response.data); that.joke = response.data; },function (err) { }) } }, }) </script> </body> </html>
案例:天气预报
我们同样采用一个简单的案例来巩固Vue网络应用
案例需求:
- 我们可以手动查找输入框内的城市的天气情况
- 我们可以点击页面内含有的城市的天气情况
代码展示:
<!--主页面展示--> <!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>天知道</title> <!--CSS链接--> <link rel="stylesheet" href="css/index.css" /> </head> <body> <!--Vue绑定--> <div class="wrap" id="app"> <div class="search_form"> <div class="logo"><img src="img/logo.png" alt="一篇文章带你了解网页框架——Vue简单入门" alt="logo" /></div> <div class="form_group"> <!--双向绑定city,添加事件@keyup.enter="queryWeather"--> <input type="text" class="input_txt" placeholder="请输入查询的天气" v-model="city" @keyup.enter="queryWeather" /> <!--添加事件@keyup.enter="queryWeather"--> <button class="input_sub" @click="queryWeather"> 搜 索 </button> </div> <!--展示列出的城市,点击触发事件--> <div class="hotkey"> <a href="javascript:;" v-for="city in hotCitys" @click="clickSearch(city)">{{ city }}</a> </div> <!--展示返回的天气数据--> </div> <ul class="weather_list"> <!----> <li v-for="(item,index) in forecastList" :key="item.date" :style="{transitionDelay:index*100+'ms'}"> <div class="info_type"> <span class="iconfont">{{ item.type }}</span> </div> <div class="info_temp"> <b>{{ item.low}}</b> ~ <b>{{ item.high}}</b> </div> <div class="info_date"> <span>{{ item.date }}</span> </div> </li> </ul> </div> <!-- 开发环境版本,包含了有帮助的命令行警告 --> <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script> <!-- 官网提供的 axios 在线地址 --> <script src="https://unpkg.com/axios/dist/axios.min.js"></script> <script> new Vue({ el: "#app", data: { // 输入框城市,双向绑定 city: "武汉", // 天气情况 forecastList: [], // 城市展示 hotCitys: ["北京", "上海", "广州", "深圳"] }, methods: { queryWeather() { // 将天气情况清零 this.forecastList = []; // axios获得天气状况 axios .get(`http://wthrcdn.etouch.cn/weather_mini?city=${this.city}`) .then(res => { console.log(res); this.forecastList = res.data.data.forecast; }) .catch(err => { console.log(err); }) .finally(() => { }); }, // 点击城市触发queryWeather方法,获得天气情况 clickSearch(city) { this.city = city; this.queryWeather(); } } }); </script> </body> </html>
/* css展示 页面前置css修改 */ body,ul,h1,h2,h3,h4,h5,h6{ margin: 0; padding: 0; } h1,h2,h3,h4,h5,h6{ font-size:100%; font-weight:normal; } a{ text-decoration:none; } ul{ list-style:none; } img{ border:0px; } /* 清除浮动,解决margin-top塌陷 */ .clearfix:before,.clearfix:after{ content:''; display:table; } .clearfix:after{ clear:both; } .clearfix{ zoom:1; } .fl{ float:left; } .fr{ float:right; } /* css展示 页面内部css修改 */ body{ font-family:'Microsoft YaHei'; } .wrap{ position: fixed; left:0; top:0; width:100%; height:100%; /* background: radial-gradient(#f3fbfe, #e4f5fd, #8fd5f4); */ /* background:#8fd5f4; */ /* background: linear-gradient(#6bc6ee, #fff); */ background:#fff; } .search_form{ width:640px; margin:100px auto 0; } .logo img{ display:block; margin:0 auto; } .form_group{ width:640px; height:40px; margin-top:45px; } .input_txt{ width:538px; height:38px; padding:0px; float:left; border:1px solid #41a1cb; outline:none; text-indent:10px; } .input_sub{ width:100px; height:40px; border:0px; float: left; background-color: #41a1cb; color:#fff; font-size:16px; outline:none; cursor: pointer; position: relative; } .input_sub.loading::before{ content:''; position: absolute; left: 0; top: 0; width: 100%; height: 100%; background: url('../img/loading.gif'); } .hotkey{ margin:3px 0 0 2px; } .hotkey a{ font-size:14px; color:#666; padding-right:15px; } .weather_list{ height:200px; text-align:center; margin-top:50px; font-size:0px; } .weather_list li{ display:inline-block; width:140px; height:200px; padding:0 10px; overflow: hidden; position: relative; background:url('../img/line.png') right center no-repeat; background-size: 1px 130px; } .weather_list li:last-child{ background:none; } /* .weather_list .col02{ background-color: rgba(65, 165, 158, 0.8); } .weather_list .col03{ background-color: rgba(94, 194, 237, 0.8); } .weather_list .col04{ background-color: rgba(69, 137, 176, 0.8); } .weather_list .col05{ background-color: rgba(118, 113, 223, 0.8); } */ .info_date{ width:100%; height:40px; line-height:40px; color:#999; font-size:14px; left:0px; bottom:0px; margin-top: 15px; } .info_date b{ float: left; margin-left:15px; } .info_type span{ color:#fda252; font-size:30px; line-height:80px; } .info_temp{ font-size:14px; color:#fda252; } .info_temp b{ font-size:13px; } .tem .iconfont { font-size: 50px; }
结束语
好的,关于Vue入门案例的内容就介绍到这里,希望能为你带来帮助!
附录
该文章属于学习内容,具体参考B站黑马程序员vue前端基本教程
这里附上链接:01.课程介绍_哔哩哔哩_bilibili