前端vue 的老师飞快的讲了如何使用Vue完成前端页面数据的渲染,听的懵懵懂懂,回头细心琢磨了一下,写了笔记加深一下印象,有兴趣的小伙伴也可以看一下学习一下; 文章最后附带项目源代码。
废话不多说,先上效果图。
主页面分为三个板块, 分别为顶部文章管理、文章列表,中部的文章列表数据渲染页面,还有底部固定的footer导航。
最后还有点击返回跳转到主页面的主功能。
代码如下(示例):
这里需要注意的是二级路由children ,因为jinengHome这个组件是主页面,jinnegDetail.vue 是二级页面 ,jinnegList.vue与主页面是同级的组件。
import jinengDetail from '@/components/jinengDetail.vue' import jinengList from '@/components/jinengList.vue' import jinengHome from '@/components/jinengHome.vue' // 路由配置代码:这里需要注意的是二级路由children ,因为jinengHome这个组件是主页面,jinnegDetail.vue 是二级页面 ,jinnegList.vue与主页面是同级的组件。 routes: [{ path: '/jinengHome', name: 'jinengHome', component: jinengHome, children: [ { path: '/jinengDetail', name: 'jinengDetail', component: jinengDetail }, { path: '/', name: 'jinengList', component: jinengList }, ] }, ]:
需要注意的是每一个组件里面必须要有<template /template> 而且模板里面必须包裹一个 div
<template> // 模板 <div class="container"> <div class="page-title" :style="{ 'justify-content': currentPath === '/jinengList' ? 'center' : 'space-between', }"> // :style 动态绑定样式, 冒号代表 v-bind 绑定样式。 <router-link id="goBack" v-show="currentPath === '/jinengDetail'" to="/">返回</router-link> // 给返回按钮添加一个v-show 指令,让他停留在主页面的时候隐藏,到详情页的时候显示。 <span>文章管理</span> // 为保存按钮添加跳转时显示隐藏的效果 <router-link id="save" v-show="currentPath === '/jinengDetail'" to="/jinengList">保存</router-link> </div> // 头部的文章标签栏切换的效果,为li 绑定类名并同时添加 @click 点击事件,选中状态变红色,未选中为默认状态。 <ul class="page-tab"> <li :class="{ active: currentItem === item }" @click="changeItem(item)" v-for="(item, index) in arr" :key="index" > // 与此同时,台为li 添加了 v-for 指令来遍历 arr 这个数组,数组里面存放-文章列表, 文章编写, 文章分类,三个条目。对应js 的 return 下的arr:[]代码。 {{ item }} // 为数组item编写模板语法,让其显示到页面上面 </li> </ul> // 最后配置路由容器 <router-view></router-view> //底部文章管理的模块 <ul class="footer"> <li> <div class="icon"></div> <div>文章管理</div> </li> <li> <div class="icon"></div> <div>文章管理</div> </li> <li> <div class="icon"></div> <div>文章管理</div> </li> </ul> </div> </template>接下来为元素和标签配置样式 编写css代码
<style scoped> .container { display: flex; flex-direction: column; position: absolute; top: 0; left: 0; right: 20px; bottom: 0; padding-top: 100px; padding-bottom: 60px; } .container .page-title { /* display: flex; */ justify-content: space-between; align-items: center; position: fixed; top: 0; left: 0; background: rgb(100, 108, 252); color: #ffffff; width: 100%; height: 40px; line-height: 40px; text-align: center; z-index: 1; padding: 0 10px; box-sizing: border-box; } .container .page-title #goBack { color: #ffffff; border: 2px solid #aaa; border-top-left-radius: 20px; border-top-right-radius: 20px; border-bottom-left-radius: 20px; border-bottom-right-radius: 20px; height: 30px; line-height: 30px; padding: 0 10px; } .container .page-title #save { color: #ffffff; border: 2px solid #aaa; border-top-left-radius: 20px; border-top-right-radius: 20px; border-bottom-left-radius: 20px; border-bottom-right-radius: 20px; height: 30px; line-height: 30px; padding: 0 10px; } .container .page-title { position: fixed; top: 0; left: 0; background: rgb(100, 108, 252); color: #ffffff; width: 100%; height: 40px; line-height: 40px; text-align: center; z-index: 1; } .container .page-tab { position: fixed; top: 40px; left: 20px; width: 80%; padding: 0 10px; display: flex; /* justify-content: space-between; */ /* align-items: center; */ background: #ffffff; border-bottom: 1px solid blue; z-index: 1; } .container .page-tab li { flex: 1; height: 40px; line-height: 40px; text-align: center; font-size: 14px; } .container .page-tab li.active { color: #ffffff; background: red; } .container .page-tab li:nth-child(2) { border-left: 1px solid #ddd; border-right: 1px solid #ddd; } .container .footer { position: fixed; bottom: 0; left: 0; display: flex; width: 100%; height: 60px; background: rgb(100, 108, 252); color: #ffffff; font-size: 12px; font-weight: bold; } .container .footer li { flex: 1; display: flex; margin-right: 80px; flex-direction: column; justify-content: space-around; align-items: center; } .container .footer li .icon { width: 25px; height: 25px; background: #aaaaaa; border-radius: 50%; } .container .footer li:first-child .icon { width: 25px; height: 25px; border-radius: 50%; background-image: url(../assets/icons-36-black.png); background-position: -867px -5px; } .container .footer li:nth-child(2) .icon { width: 25px; height: 25px; border-radius: 50%; background-image: url(../assets/icons-36-black.png); background-position: -939px -5px; } .container .footer li:last-child .icon { width: 25px; height: 25px; border-radius: 50%; background-image: url(../assets/icons-36-white.png); background-position: -580.5px -5px; } </style>紧接着编写js 为他执行动作- 代码
<script> export default { data() { return { arr: ["文章列表", "文章编写", "文章分类"], // 这里对应上述的 <li v-for = "(item,index) in arr" :key=index > currentItem: "文章列表", btnVisible: false, }; }, mounted() { console.log(this.$route); // 在这里用控制台输入当前路由路径。 }, computed: { currentPath() { return this.$route.path; },// 计算属性,对应上述的v-show="currentPath === '/jinengDetail'" ,判断当前的路由路径。 }, methods: { changeItem(item) { this.currentItem = item; }, // methods对应上述的 @click="changeItem(item)" 点击条目的事件,更换item颜色与选中状态。 toList() { this.$router.push({ path: "/jinenglist" }); }, }, watch: { // $route (value) { // console.log('监听router', value) // if (value.path === '/jinengList') { // this.btnVisible = false // } else { // this.btnVisible = true // } // } }, }; </script>到此页面的显示效果为:
css代码:
<style scoped> .list-container { position: relative; flex: 1; } .list-container .search-box { position: relative; display: flex; justify-content: center; align-items: center; width: 100%; margin-left: 10px; height: 40px; background: #aaaaaa; } .list-container .search-box .input-icon { position: absolute; top: 50%; left: 20px; width: 25px; height: 25px; margin-top: -12.5px; background: #ddd; border-radius: 50%; background-image: url("../assets/icons-36-white.png"); /* 这里的 background-image 语句后面的路径 需要注意的是 ../ 表示 上一级的目录。*/ background-position: -1225px -5px; } .list-container .search-box input { box-sizing: border-box; width: 100%; height: 35px; border-top-left-radius: 20px; border-top-right-radius: 20px; border-bottom-left-radius: 20px; border-bottom-right-radius: 20px; outline: none; border: 2px solid #333333; padding-left: 40px; } .list-container .content-box { width: 100%; flex: 1; overflow: auto; } .list-container .content-box li { position: relative; width: 90%; height: 80px; border-bottom: 1px solid #ddd; padding: 0 0px; box-sizing: border-box; } .list-container .content-box li .item-icon { position: absolute; top: 50%; right: 0px; width: 25px; height: 25px; margin-top: -12.5px; background: #aaaaaa; border-radius: 50%; background-image: url("../assets/icons-36-white.png"); background-position: -220px -5px; } .list-container .content-box li .title { font-weight: bold; height: 40px; line-height: 40px; } </style>js代码: 这里需要注意的是 引入jQuery文件需要在项目中配置, 配置语句 跳出控制台输入:npm install jquery --save 即可引入 jQuery,然后在页面中的script下输入 import $ from “jquery” 即可使用jQuery的一些语法和代码。
npm install jquery --save <script> import $ from "jquery";// 这里需要注意的是 引入jQuery文件需要在项目中配置, //配置语句 跳出控制台输入:npm install jquery --save 即可引入 jQuery。 //然后在页面中的script下输入 即可使用jQuery的一些语法和代码。 import $ from "jquery" export default { data() { return { arr: [], // 这里用于显示调用接口成功后传回来的数据。 }; }, mounted() { // 在vue中写jQuery代码需要在 mounted中编写。 $.ajax({ url: "http://192.168.3.77:3000/api/demo/getList", //请求地址,这里是老师给的服务器默认地址,这个接口已经有数据了。 method: "get",// 请求方式 为get请求 data: {}, // 这里的data是用来显示请求成功后取回来的数据用于显示。 dataType: "json", // 请求的数据类型为 json,json解析。 success: (res) => { // 请求成功后,把请求的数据 res 作为参数传入 。 console.log(res);// 在控制台中输出调取成功后的数据。 this.arr = res;// 把请求成功后的数据获取到后,显示到 data(){} 中 return下的arr数组当中。 }, }); }, methods: { toDetail(data) { console.log(data); this.$router.push({ path: "/jinengDetail", query: data }); }, }, }; </script>至此,列表文章的模块就有数据了。运行效果图:
html
<template> <div class="wrapper"> <ul class="content-box"> <li> <div>作者:</div> <input id="auther" v-model="detailObj.userName" type="text" /> </li> <!-- v-model 表示双向绑定,用于在输入框中显示主页面点击后传回来的数据显示。 --> <li> <div>标题:</div> <input id="detailTitle" v-model="detailObj.title" type="text" /> </li> <li> <div>内容:</div> <textarea v-model="detailObj.detailInfo" id="remark" name="" cols="30" rows="10" ></textarea> </li> </ul> <router-view /> </div> </template>国际惯例,配置css代码,只要有html代码 要设置样式的话就要写 css代码:
<style scoped> .content-box { padding: 10px; } .content-box li { display: flex; flex-direction: column; } .content-box li > div { height: 40px; line-height: 40px; color: #333333; } .content-box li input { flex: 1; height: 40px; border-top-left-radius: 10px; border-top-right-radius: 10px; border-bottom-left-radius: 10px; border-bottom-right-radius: 10px; } .content-box li textarea { border-top-left-radius: 10px; border-top-right-radius: 10px; border-bottom-left-radius: 10px; border-bottom-right-radius: 10px; outline: none; /* box-shadow: blue 5px; */ } </style>配置完css代码后的效果为: 最后是js代码: 这里需要注意的是 url 地址的老师提供的默认地址,需要自己去找接口数据调用。
<script> import $ from "jquery"; export default { data() { return { detailObj: {}, // 此处用于input框中显示获取到的数据。 }; }, mounted() { console.log(window.location.href);// 显示当前浏览器的访问路径 window.location.href。 console.log(this.$route.query); // 控制台输出并获取到当前的路由传过来的数据。 $.ajax({ url: "http://192.168.3.77:3000/api/demo/detail", method: "get", data: { id: this.$route.query.id }, // data属性: 获取到id 当前的路由数据的id。 dataType: "json", success: (res) => { console.log("detailData", res); this.detailObj = res;// 把数据传给detailObj,返回数据。 }, }); }, }; </script>在App.vue 根组件 中写 路由容器代码 <router-view //> 否则页面没有任何数据!
1.二级路由children ,因为jinengHome这个组件是主页面,jinnegDetail.vue 是二级页面 ,jinnegList.vue与主页面是同级的组件。
2.引入jQuery文件需要在项目中配置,配置语句 跳出控制台输入:npm install jquery --save 即可引入 jQuery,然后在页面中的script下输入 import $ from “jquery” 即可使用jQuery的一些语法和代码。
3 url: “http://192.168.3.77:3000/api/demo/getList”, 的请求地址,这里是老师给的服务器默认地址,这个接口已经有数据了。method: 请求方式要为get请求。
4: success: (res) => { 是使用的箭头函数来获取数据,请求成功后,把请求的数据 res 作为参数传入 this.arr = res;代码是把请求成功后的数据获取到后,显示到 data(){} 中 return下的arr数组当中。
5:路由配置文件path 为路径 ,将其设置为 “/” 的话为跳转到当前主页面。
项目源代码:链接:https://pan.baidu.com/s/1Jfz7DmgH9di1uua-bUl_qw 提取码:pykn
最困难之时,就是我们离成功不远之日。——凯撒