Vue路由
一. 作业案例
1. 单文件组件实现选项卡
代码:
子组件OptionCard.vue文件:
<template> <div id="OptionCard"> <div class="title_box"> <span v-for="item, key in select_list" :class="index==key?'active':''" @click="index=key">{{item.title}}</span> </div> <div class="content_box"> <div v-for="item, key in option_list" class="item1" :class="index==key?'current':''">{{item.content}}</div> </div> </div> </template> <script> export default { name: "OptionCard", data(){ return { index: 0, select_list: [ {"title":"欧美专区"}, {"title":"日韩专区"}, {"title":"大陆专区"}, {"title":"图片专区"}, ], option_list: [ {"content":"欧美专区的内容!"}, {"content":"日韩专区的内容!"}, {"content":"大陆专区的内容!"}, {"content":"图片专区的内容!"}, ] } } } </script> <style scoped> #OptionCard { width: 400px; height: 300px; background: #eeeeee; } .title_box { height: 50px; background: #ff6700; } .active { background: #eeeeee; } span { line-height: 50px; text-align: center; display: inline-block; width: 80px; } .item1 { height: 250px; border-bottom: 1px solid black; display: none; } .current { display: block; } </style>
在App.vue文件中注册:
<template> <div id="app"> <OptionCard></OptionCard> </div> </template> <script> import OptionCard from "./components/OptionCard" export default { name: 'App', components: { OptionCard } } </script> <style> </style>
效果:
2. 实现图书的管理(增删改查)
代码:
<!DOCTYPE html> <html> <head> <title>表格数据的增删查改</title> <script src="js/vue.js"></script> <style> table{ border-collapse: collapse; border: 1px solid blue; } table td,th{ width: 130px; height: 30px; text-align: center; } .form{ background: rgba(0, 0, 0, 0.3); height: 100%; width: 100%; position: fixed; top:0; } .form_content{ background: white; width: 400px; height: 250px; margin: 80px auto 0; padding: 30px 0 0 60px; } </style> </head> <body> <div id="app"> <a href="" @click.stop.prevent="show_form=true"><button>新增书籍</button></a> <table border="1"> <tr> <th>ID</th> <th>书名</th> <th>价格</th> <th>操作</th> </tr> <tr v-for="book,key in book_list"> <td>{{book.id}}</td> <td>{{book.title}}</td> <td>{{book.price}}</td> <td><button @click.stop="edit_book(key)">编辑</button> | <button @click.stop="del_book(key)">删除</button></td> </tr> </table> <div class="form" v-show="show_form"> <div class="form_content"> <h3>新增书籍</h3> <p>书名:<input type="text" v-model="title"></p> <p>价格:<input type="text" v-model="price"></p> <button @click.stop="add_book">保存</button> <button @click.stop="show_form=false">取消</button> </div> </div> </div> <script> var vm = new Vue({ el: "#app", data: { key: "", title: "", price: "", show_form: false, id_increment: 7, book_list: [ {"id": 1, "title": "python入门", "price": 150}, {"id": 3, "title": "python进阶", "price": 100}, {"id": 4, "title": "python高级", "price": 75}, {"id": 5, "title": "python研究", "price": 60}, {"id": 7, "title": "python大神", "price": 180}, ] }, methods: { // 保存书籍 add_book(){ this.show_form = false; if (this.key === ""){ // 保存新增书籍 this.id_increment++; let new_book = { id: this.id_increment, title: this.title, price: this.price }; this.book_list.push(new_book) }else{ // 编辑书籍保存 this.book_list[this.key].title = this.title; this.book_list[this.key].price = this.price; this.title = ""; this.price = ""; } }, // 删除书籍 del_book(index){ this.book_list.splice(index, 1); }, // 编辑书籍 edit_book(index){ this.show_form=true; this.key = index; this.title = this.book_list[index].title; this.price = this.book_list[index].price; } } }) </script> </body> </html>
效果:
扩展知识(本地存储):
html5提供给开发者保存数据到客户端的两个新对象.
window.localStorage # 本地存储
window.sessionStorage # 会话存储
这两个对象都是保存数据的,只是保存数据的周期不一样而已。
这两个对象的用法也是一样的。
localStorage.setItem("变量名","变量值"); # 存储数据
localStorage.getItem("变量名"); # 获取数据
localStorage.removeItem("变量名"); # 删除数据
localStorage.clear(); # 清空本地存储中的所有数据
二. 在组件中使用axios获取数据
1. 安装和配置axios
默认情况下,我们的项目中并没有对axios包的支持,所以我们需要下载安装。
在项目根目录中使用 npm安装包
npm install axios
接着在main.js文件中,导入axios并把axios对象 挂载到vue属性中作为一个子对象,这样我们才能在组件中使用。
// The Vue build version to load with the `import` command // (runtime-only or standalone) has been set in webpack.base.conf with an alias. import Vue from 'vue' import App from './App' import axios from 'axios' // 从node_modules目录中导包 Vue.config.productionTip = false; Vue.prototype.$axios = axios; // 把对象挂载到Vue中 /* eslint-disable no-new */ new Vue({ el: '#app', components: { App }, template: '<App/>' });
2. 在组件中使用axios获取数据
新建子组件GetWeather.vue文件
<template> <div> <input type="text" v-model="city" placeholder="请输入要查询的城市"> <button @click="get_weather">获取天气</button> <p>{{weather_info}}</p> </div> </template> <script> export default { name: "GetWeather", data(){ return { city: "", weather_info: "", } }, methods: { get_weather(){ this.$axios.get("http://wthrcdn.etouch.cn/weather_mini", { params: { "city": this.city } }).then(response=>{ this.weather_info = response.data; }).catch(error=>{ consolo.log(error.response) }) } } } </script> <style scoped> </style>
记得要在App.vue文件进行注册,注册完后,效果如下:
注意:使用的时候,因为本质上来说,我们还是原来的axios,所以也还会受到同源策略的影响。
三. 项目分析
首页
导航、登录注册栏、轮播图、底部导航
登录注册
选项卡
免费课
课程分类、筛选、课程列表
免费课详情
课程封面视频、优惠活动倒计时、选项卡
我的购物车
全选、商品价格统计
购买结算
购买成功
我的订单
课时播放页面
四. 项目搭建
1. 新建一个vue项目
vue init webpack luffycity
根据需要在生成项目时,我们选择对应的选项。
根据上面的提示,我们已经把vue项目构建好了,接下来我们可以在pycharm编辑器中把项目打开并根据上面黄色提示,运行测试服务器。
2. 初始化项目
清除默认的Helloworld.vue组件和App.vue中的默认模板代码和默认样式。
修改后的效果:
接下来,我们可以查看效果了,一张白纸。
3. 安装路由vue-router
3.1 下载路由组件
npm i vue-router -S
执行效果:
3.2 配置路由
在src目录下创建router路由目录,在router目录下创建index.js路由文件
router/index.js路由文件中,编写初始化路由对象的代码
// 引入路由类和Vue类 import Vue from 'vue' import Router from 'vue-router' // 注册路由类 Vue.use(Router); // 初始化路由对象 export default new Router({ // 设置路由模式为‘history’,去掉默认的# model: "history", routes: [ // 路由列表 { // 一个字典,代表一条url // name: "路由别名", // path: "路由地址", // component: 组件类名, } ] })
打开main.js文件,把router路由规则对象注册到vue中。
代码:
// The Vue build version to load with the `import` command // (runtime-only or standalone) has been set in webpack.base.conf with an alias. import Vue from 'vue' import App from './App' import router from './router/index' Vue.config.productionTip = false; /* eslint-disable no-new */ new Vue({ el: '#app', router, // 注册路由规则对象 components: { App }, template: '<App/>' });
3.3 在视图中显示路由对应的内容
在App.vue组件中,添加显示路由对应的内容。
代码:
<template> <div id="app"> <router-view /> </div> </template> <script> export default { name: 'App', components: { } } </script> <style> </style>
注意:如果在vue创建项目的时候,设置安装vue-router,则项目会自动帮我们生成上面的router目录和index.js里面的代码,以及自动到main.js里面注册路由对象。
4. 引入ElementUI
对于前端页面布局,我们可以使用一些开源的UI框架来配合开发,Vue开发前端项目中,比较常用的就是ElementUI了。
ElementUI是饿了么团队开发的一个UI组件框架,这个框架提前帮我们提供了很多已经写好的通用模块,我们可以在Vue项目中引入来使用,这个框架的使用类似于我们前面学习的bootstrap框架,也就是说,我们完全可以把官方文档中的组件代码拿来就用,有定制性的内容,可以直接通过样式进行覆盖修改就可以了。
中文官网:http://element-cn.eleme.io/#/zh-CN
文档快速入门:http://element-cn.eleme.io/#/zh-CN/component/quickstart
4.1 快速安装ElementUI
在项目的根目录下执行下面的命令。
npm i element-ui -S
上面的代码等同于:npm install element-ui --save
执行命令效果:
4.2 配置ElementUI到项目中
在main.js中导入ElementUI,并调用。代码:
// elementUI 导入 import ElementUI from 'element-ui'; import 'element-ui/lib/theme-chalk/index.css'; // 调用插件 Vue.use(ElementUI);
效果:
成功引入了ElementUI以后,接下来我们就可以开始进入前端页面开发,首先是首页。
五. 首页的开发
首页采用了上下页面布局,首页是导航栏、轮播图。。。脚部等几个小模块。所以我们可以把首页作为一个组件进行开发,然后把首页的这些小模块作为单独的组件来进行开发。
1. 创建首页组件
在src/components目录下创建文件 Home.vue
<template> <div class="home"> <Header></Header> <Banner></Banner> <Footer></Footer> </div> </template> <script> import Header from "./common/Header" import Banner from "./common/Banner" import Footer from "./common/Footer" export default { name: "Home", data(){ return {} }, methods:{ }, components:{ Header, Footer, Banner, } } </script> <style scoped> </style>
2. 编写首页的头部导航栏
<template> <div class="header"> <div class="content_box"> <div class="content"> <div class="logo full-left"> <img src="/static/image/logo.svg" alt=""> </div> <ul class="nav full-left"> <li><span>免费课</span></li> <li><span>轻课</span></li> <li><span>学位课</span></li> <li><span>题库</span></li> <li><span>老男孩教育</span></li> </ul> <div class="login-bar full-right"> <div class="shop-cart full-left"> <img src="/static/image/cart.svg" alt=""> <span>购物车</span> </div> <div class="login-box full-left"> <span>登录</span> | <span>注册</span> </div> </div> </div> </div> </div> </template> <script> export default { name: "Header" } </script> <style scoped> .header{ height: 80px; } .content_box{ width: 100%; height: 80px; position: fixed; z-index:3; background-color: #fff; box-shadow: 0 0.5px 0.5px 0 #c9c9c9; } .header .content{ max-width: 1200px; width: 100%; margin: 0 auto; } .header .content .logo{ height: 80px; line-height: 80px; margin-right: 50px; cursor: pointer; /* 设置光标的形状为爪子 */ } .header .content .logo img{ vertical-align: middle; } .header .nav li{ float: left; height: 80px; line-height: 80px; margin-right: 30px; font-size: 16px; color: #4a4a4a; cursor: pointer; } .header .nav li span{ padding-bottom: 16px; padding-left: 5px; padding-right: 5px; } .header .nav li:hover span{ color: #000; } .header .login-bar{ height: 80px; } .header .login-bar .shop-cart{ margin-right: 20px; border-radius: 17px; background: #f7f7f7; cursor: pointer; font-size: 14px; height: 28px; width: 88px; margin-top: 30px; line-height: 32px; text-align: center; } .header .login-bar .shop-cart:hover{ background: #f0f0f0; } .header .login-bar .shop-cart img{ width: 15px; margin-right: 4px; margin-left: 6px; } .header .login-bar .shop-cart span{ margin-right: 6px; } .header .login-bar .login-box{ margin-top: 33px; } .header .login-bar .login-box span{ color: #4a4a4a; cursor: pointer; } .header .login-bar .login-box span:hover{ color: #000000; } </style>
3. 编写首页的中间banner页面(轮播图)
<template> <div class="banner"> <el-carousel height="640px"> <el-carousel-item> <img src="/static/image/banner1.png" alt=""> </el-carousel-item> <el-carousel-item> <img src="/static/image/banner2.jpeg" alt=""> </el-carousel-item> <el-carousel-item> <img src="/static/image/banner3.png" alt=""> </el-carousel-item> </el-carousel> </div> </template> <script> export default { name: "Banner" } </script> <style scoped> .el-carousel__item h3 { color: #475669; font-size: 14px; opacity: 0.75; line-height: 150px; margin: 0; } .el-carousel__item:nth-child(2n) { background-color: #99a9bf; } .el-carousel__item:nth-child(2n+1) { background-color: #d3dce6; } img { width: 100%; } </style>
我们可以在App.vue 中设置一些公共样式的代码:
<template> <div id="app"> <router-view /> </div> </template> <script> export default { name: 'App', components: { } } </script> <style> /* 声明全局样式和项目的初始化样式 */ body,h1,h2,h3,h4,p,table,tr,td,ul,li,a,form,input,select,option,textarea{ margin:0; padding: 0; font-size: 15px; } a{ text-decoration: none; color: #333; } ul,li{ list-style: none; } table{ border-collapse: collapse; /* 合并边框 */ } /* 工具的全局样式 */ .full-left{ float: left!important; } .full-right{ float: right!important; } </style>
首页效果: