版权声明:本文为博主原创文章,未经博主允许不得转载 https://blog.csdn.net/AiHuanhuan110/article/details/89421279
vue工程化第二节
提高代码可复用性
相同代码单独作为一个组件,提高代码可复用性。
下面两个界面的红色框框,样式和内容都差不多,可以单独作为一个组件来写。
步骤:
-
首先在 components 下新建文件 movieList.vue ,然后写入以下代码
<template> <div> <div @click="$router.push({name:'movieDetail'})" class="movie-list"> <div class="movie-img"> <img :src="mitem.img.replace('w.h','128.180')" alt> </div> <div class="right-info"> <ul class="movie-info"> <li class="name">{{mitem.nm}}</li> <li v-if="mitem.globalReleased && mitem.sc!==0" class="score"> 观众评 <span>{{mitem.sc}}</span> </li> <li style="font-size: 14px;color: #888" v-if="mitem.globalReleased && mitem.sc==0">暂无评分</li> <li v-if="!mitem.globalReleased" class="score"> <span>{{mitem.wish}}</span> 想看 </li> <li class="actor">{{mitem.star}}</li> <li class="showinfo">{{mitem.showInfo}}</li> </ul> <div class="btn"> <button v-if="mitem.globalReleased" class="buy-btn">购票</button> <button v-if="!mitem.globalReleased" class="pre-btn">预售</button> </div> </div> </div> </div> </template> <script> export default { name: "movieList", props: ["mitem"], //通过mitem属性接收父组件的传值 data() { return {}; } }; </script> <style scoped> @import "../assets/css/movie-list.css"; </style>
-
然后在需要使用组件的页面,引入、注册组件,即可使用
// hoting.vue 路径:src/components <template> <div> <div class="hoting"> <!-- 使用组件:HTML 中的特性名是大小写不敏感的,所以浏览器会把所有大写字符解释为小写字符。这意味着当你使用 DOM 中的模板时,camelCase (驼峰命名法) 的 prop 名需要在使用时要转换为其等价的 kebab-case (短横线分隔命名) 命名。 :mitem="h_item" ==> 通过属性绑定向子组件动态传值 --> <movie-list v-for="(h_item,index) in hotList" :key="index" :mitem="h_item"></movie-list> </div> </div> </template> <script> import axios from "axios"; import movieList from "./movieList"; //引入组件 export default { name: "hoting", data() { return { hotList: [] }; }, created() { axios .get("http://www.softeem.xin/maoyanApi/ajax/movieOnInfoList") .then(res => { this.hotList = res.data.movieList; }); }, components: { movieList //注册组件 } }; </script> <style scoped> </style>
-
作为一个页面的一部分
// coming.vue 路径:src/components <template> <div> <!-- 本页面自有的部分 --> <div class="hopeful"> <p>近期最受期待</p> <div class=" img-list" ref='imglist' @touchmove='throttleRun($event)'> <div class="hopeful-list" v-for='(item,index) in hopefulList' :key='index'> <div class="hope-img"> <img :src="item.img.replace('w.h','128.180')" alt=""> <p class="wish">{{item.wish}}想看</p> </div> <div class="hopeful-info"> <p class="name">{{item.nm}}</p> <p class="showTime">{{item.comingTitle}}</p> </div> </div> </div> </div> <div class="comming"> <!-- 使用组件 --> <movie-list v-for="(c_item,index) in comingList" :key="index" :mitem='c_item'></movie-list> </div> </div> </template> <script> import axios from 'axios' import movieList from './movieList' //引入组件 export default { name: 'coming', components: { movieList //注册组件 } // ... 其他代码,可参考本节的demo </script> <style scoped> @import "../assets/css/movie-list.css"; // ... 其它样式,参考本节demo </style>
跳转电影详情页
通过路由传值,在点击进入详情页时,将电影的id传入到详情页面,然后通过电影id去请求相应数据,参考路由传值
<!-- movieList.vue 路径:src/components -->
<template>
<div>
<div @click="$router.push({name:'movieDetail',query:{id:mitem.id}})" class="movie-list">
</div>
// ...其它代码
</div>
</template>
电影详情页
代码如下:
<template>
<div>
<div class="movie-header">
<div class="movie-img">
<img :src="movieDetail.img.replace('w.h','128.180')" alt>
</div>
<ul class="movie-info">
<li>{{movieDetail.nm}}</li>
<li>{{movieDetail.enm}}</li>
<li v-if="movieDetail.globalReleased && movieDetail.sc!==0" class="score">
观众评
<span>{{movieDetail.sc}}</span>
</li>
<li
style="font-size: 14px;color: #888"
v-if="movieDetail.globalReleased && movieDetail.sc==0"
>暂无评分</li>
<li v-if="!movieDetail.globalReleased" class="score">
<span>{{movieDetail.wish}}</span> 想看
</li>
<li>{{movieDetail.cat}}</li>
<li>{{movieDetail.src}}</li>
<li>{{movieDetail.pubDesc}}</li>
</ul>
</div>
<button class="buy-btn">特惠购票</button>
<div class="movie-intro">
<p :class="btnType?'overflow':''">{{movieDetail.dra}}</p>
<img @click="btnType=!btnType" class="btn" :src="btnType?downBtnSrc:upBtnSrc" alt>
</div>
</div>
</template>
<script>
import axios from "axios";
/**
* img里面的src非常特殊 不能使用表达式动态绑定
* 如果非要使用动态表达式绑定,一定是先把图片导入进来,然后再使用
*/
import downBtnSrc from "../assets/img/down.png";
import upBtnSrc from "../assets/img/up.png";
export default {
data() {
return {
movieDetail: null,
btnType: true,
downBtnSrc,
upBtnSrc
};
},
// 这里会在实例创建完成后被立即调用。created 是vue生命周期钩子,参考 https://cn.vuejs.org/v2/api/#created
created() {
// 这里获取 从路由传值传过来的电影id,然后进行数据请求
let id = this.$route.query.id;
axios
.get("http://www.softeem.xin/maoyanApi/ajax/detailmovie?movieId=" + id)
.then(res => {
this.movieDetail = res.data.detailMovie;
});
}
};
</script>
<style lang="scss" scoped>
@import "../assets/scss/main.scss";
@import "../assets/css/movie-list.css";
// ... 其它样式请参考第二节demo
</style>
看代码注释。
本节结尾
- 项目思想大概就是这样,路由之间的跳转,组件化开发,划分模块,路由传值。
- demo 会持续更新。
- 数据和内容再细节化
- 添加播放宣传片功能
- 懒加载
- 底部菜单
- vuex、登陆验证等等。
- 博客也会有相应的更新
欢迎大家讨论和发表意见,未完。。。