• 【vue】vue-znly


    老规矩,放下博主的项目地址:https://github.com/wohaiwo/vue-znly
    我一直在想给那些开源者取什么名字比较好,怎样才对得起他们开源项目的精神,后来想想,还是叫博主吧。有的人用语言表达技术,有的人用代码表达技术。
    接下来我们还是来看项目效果吧

    我们可以看到这个项目内容还是挺多的,里面缺少一些内容,但是不影响我们研究这个项目
    我们看index.html可以发现,这个项目用到了vue和jquery结合做的。

    <!DOCTYPE html>
    <html>
      <head>
        <meta charset="utf-8">
        <meta name="viewport" content="width=device-width, height=device-height, user-scalable=no, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0">
        <meta name="keywords" content="今世缘 景区">
        <meta name="apple-mobile-web-app-capable" content="yes" />
        <meta name="apple-touch-fullscreen" content="yes">
        <meta name="renderer" content="webkit">
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <meta name="apple-mobile-web-app-capable" content="yes" />
        <title>今世缘景区欢迎您</title>
        <link rel="shortcut icon" href="/static/logo/favicon.ico" type="image/x-icon" />
        <meta name="apple-mobile-web-app-status-bar-style" content="black" />
        <meta name="format-detection"content="telephone=no, email=no" />
        <meta http-equiv="refresh" content="2000;url=http://www.baidu.com" />
      </head>
      <body>
        <div id="app">
            <router-view></router-view>
        </div>
        <script type="text/javascript" src="http://api.map.baidu.com/api?v=1.4"></script>
        <script type="text/javascript" src="../static/lib/js/jquery-3.2.1.slim.min.js"></script>
      </body>
    </html>
    

    main.js中引入入口文件App.vue

    //main.js
    // 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 VueRouter from 'vue-router';
    import routes from './router/router.js';
    import axios from 'axios';
    // 解决30秒延迟问题
    import FastClick from 'FastClick';
    
    Vue.use(VueRouter);		// 加载vue-router插件
    Vue.prototype.$http = axios;
    
    FastClick.attach(document.body);
    
    
    // 创建 router 实例,然后传 `routes` 配置
    const router = new VueRouter({ 
    	mode: 'hash',
    	routes
    });
    
    // 创建和挂载根实例	
    var vm =  new Vue({
    	router,
    	components: { App }
    }).$mount('#app')
    
    //app.vue中还加入了动画
    <template>
    	<div>
    		<transition name="router-fade" mode="out-in">
        		<router-view></router-view>
        	</transition>
        </div> 
    </template>
    
    <script> 
    	import './static/lib/css/main.css'
    	import './static/lib/css/reset.css'
      	export default {
      	}
    
    </script>
    
    <style lang="scss">
    	.router-fade-enter-active, .router-fade-leave-active {
    	  	transition: opacity .3s;
    	}
    	.router-fade-enter, .router-fade-leave-active {
    	  	opacity: 0;
    	}
    
    	.router-slid-enter-active, .router-slid-leave-active {
            transition: all .4s;
        }
        .router-slid-enter, .router-slid-leave-to {
            transform: translate3d(-100px, 0, 0);
            opacity: 0;
        }
    </style>
    

    router中也是使用懒加载的模式,可以看到首先加载定向的是我们的home组件在app.vue中渲染出来

    //router.js
    import App from '../App.vue';
    
    // Webpack 会将任何一个异步模块与相同的块名称组合到相同的异步块中。
    const home = resolve => require(['../page/home.vue'], resolve);		// 首页
    const introduction = resolve => require(['../page/scenicIntroduction.vue'], resolve);
    const listDetail = resolve => require(['../components/listDetail.vue'], resolve);
    const travelBox = resolve => require(['../page/travelBox.vue'], resolve);
    const externalMap = resolve => require(['../page/externalMap.vue'], resolve);
    const service = resolve => require(['../page/service.vue'], resolve);
    const dropBox = resolve => require(['../components/dropBox.vue'], resolve);
    
    // 定义路由
    const routes = [
    	{
    		path: '/',
    		component: App,
    		children: [
    			{
    				path: '/',
    				redirect: { name: 'home' }
    			},
    			{
    				path: '/home',
    				name: 'home',
    				component: home
    			}, {
    				path: '/scenic/introduction', 
    				name: 'introduction', 
    				component: introduction
    			}, {
    				path: '/scenic/detail/:id/:type/:identifier',
    				name: 'listDetail', 
    				component: listDetail
    			}, {
    				path: '/travelBox',
    				name: 'travelBox', 
    				component: travelBox
    			}, {
    				path: '/externalMap',
    				name: 'externalMap',
    				component: externalMap
    			}, {
    				path: '/service/:type',
    				name: 'service',
    				component: service
    			}, {
    				path: '/dropBox/:url/:title',
    				name: 'dropBox',
    				component: dropBox
    			}
    		]
    	}
    ]
    
    
    export default routes;
    

    我们来看home组件,里面的代码挺有意思的,
    先看header组件

    //header.vue
    <template>
    	<header>
    		<slot name="logo"></slot>
    		<span class="left-icon" v-if="goBack" @click="$router.go(-1)">
    			<i title="返回" class="iconfont">&#xe679;</i>
            </span>
    		<span class="left-icon side-bar" v-if="sideBar" @click="showSideBar">
    			<i title="主菜单" class="iconfont">&#xe602;</i>
            </span>
            <span class="title-text" v-if="headTitle">{{headTitle}}</span>
            <transition name="slide-fade">
            <nav v-show="isShowSideBar">
    	    	<router-link to="/scenic/introduction"><i class="iconfont">&#xe641;</i>景区介绍</router-link>
    			<router-link :to="{name: 'service', params: {type: 3}}"><i class="iconfont">&#xe64c;</i>景区公告</router-link>
    			<router-link :to="{name: 'service', params: {type: 15}}"><i class="iconfont">&#xe69b;</i>景区服务</router-link>
    		    <router-link :to="{name: 'service', params: {type: 13}}"><i class="iconfont">&#xe6b2;</i>预订门票</router-link>
    	        <router-link :to="{name: 'service', params: {type: 14}}"><i class="iconfont">&#xe6af;</i>特色购物</router-link>
    	    	<router-link to="/travelBox"><i class="iconfont">&#xe603;</i>旅行百宝箱</router-link>
        		<router-link :to="{name: 'dropBox', params: {url: vrUrl, title: vrTitle}}"><i class="iconfont">&#xe73d;</i>虚拟旅游</router-link>
        		 <router-link :to="{name: 'service', params: {type: 6}}"><i class="iconfont">&#xe7f1;</i>餐饮住宿</router-link>
            </nav>
            </transition>
    	</header>
    </template>
    <script>
    	export default {
    		data() {
    			return {
    			}
    		},
    		props: ['goBack', 'headTitle', 'sideBar', 'isShowSideBar', 'vrUrl', 'vrTitle'],
    		methods: {
    			// 子组件通过emit向父组件传递事件的函数名
    			showSideBar() {
    				this.$emit('breadcrumb');
    			}
    		}
    	}
    </script>
    <style scoped lang="scss">
    	$nav-color: #e60012;
    	header {
    		position: fixed;
    		left: 0;
    		top: 0;
    		z-index: 100;
    		 100%;
    		height: 40px;
    		line-height: 40px;
    		color: $nav-color;
    		background: #fff ;
    		text-align: center;
    		border-bottom: 2px solid #ededed;
    		box-sizing: border-box;
    		span {
    			font-size: 18px;
    			font-weight: bold;	
    		}		
    		.left-icon {
    			position: absolute;
    			left: 0;
    			top: 50%;
    			 50px;
    			transform: translateY(-50%);
    			i {
    				color: $nav-color;
    			}
    		}
    		.side-bar {
    			left: 0;
    			 10%;
    			background: $nav-color;
    			i {
    				color: #fff;
    			}
    		}
    		nav {
    			position: fixed;
    			left: 0;
    			right: 0;
    			top: 40px;
    			bottom: 50px;
    			z-index: 20;
    			 140px;
    			background: #fff;
    			a {
    				display: block;
    				height: 50px;
    				line-height: 50px;
    				text-align: left;
    				padding-left: 8%;
    				box-sizing: border-box;
    				color: #000;
    				&:not(:last-child) {
    					border-bottom: 1px solid #e6e6e6;
    				}
    				i {
    					color: $nav-color;
    					margin-right: 20px;
    				}
    			}
    		}
    	}
    	.slide-fade-enter-active, .slide-fade-leave-active  {
    		transition: all 0.3s ease-in;
    	}
    	.slide-fade-enter, .slide-fade-leave-to{
    		opacity: 0;
    		transform: translate3d(-150px, 0, 0);
    	}
    	// 适配一体机样式
    	@media screen and  (min- 1000px) {
    		$header-height: 100px;
    	 	i {
    	 		font-size: 36px;
    	 	}
    	  	header {
    			font-size: 32px;
    		  	height: $header-height;
    		  	line-height: $header-height;
    		  	border-bottom: 4px solid #ededed;
    			span {
    				font-size: 45px;
    				font-weight: bold;	
    			}
    			.left-icon {
    				 $header-height;
    			}
    		  	nav {
    				top: $header-height;
    				bottom: $header-height;
    				 300px;
    		  		a {
    					height: $header-height;
    					line-height: $header-height;
    					border-bottom: 3px solid #e6e6e6;
    				}
    		  	}
    	  }
    
    	}
    </style>
    

    userCount.vue不知道表达什么意思?

    //userCount.vue
    //srccomponentsuserCount.vue
     <template>
    	<div>
    		<p>{{ msg }}</p>
    		 
    	</div>
    </template>
    
    <script>
    	export default {
    		data() {
    			return {
    				msg: ''
    			}
    		},
    		created() {
    			let url = '/JSY_H5/h5/statistics';
    			this.$http.get(url).then((response) => {
    				this.$data.msg = response.data.data.msg;
    			}, (response) => {
    				console.log('oops, data is error');
    			});
    		}
    	}
    </script>
    
    <style scoped lang="scss">
    	div {
    		position: relative;
    		 100%;
    		height:  20px;
    		padding: 0 4%;
    		margin-top: 40px;
    		font-size: 14px;
    		color: #ddd;
    		background: rgba(0, 0, 0, .4);
    		overflow: hidden;
    		z-index: 40;
    		user-select: none;
    		box-sizing: border-box;
    		p {
    			left: 100%;
    			position: absolute;
    			z-index: 40;
    			white-space: nowrap;
    			animation-delay: 1s;
    			animation-name: slide;
    			animation-duration: 45s;
    			animation-iteration-count: infinite;
    		}
    	}
    	@media screen and (min- 1000px) {
    		div{
    			height:  60px;
    			margin-top: 100px;
    			font-size: 32px;
    			p {
    				line-height: 60px;
    			}
    		}
    	}
    	@keyframes slide {
    		0% { left: 100%; }
    		100% { left: -120%; }
    	}
    </style>
    
    //footer.vue
    <template>
    	<footer>
    	    <ul>
    	    	<li>
    		    	<router-link :to="{name: 'service', params: {type: 15}}" :class=" pathName == navUrl[0] ? 'active' : ''">
    		    		<i class="iconfont">&#xe69b;</i><span>景区服务</span>
    		    	</router-link>
    	    	</li>
    	    	<li>
    	    		<router-link to="/home" :class=" pathName == navUrl[1] ? 'active' : ''">
    	    			<i class="iconfont">&#xe6b8;</i><span>主页</span>
    	    		</router-link>
    	    	</li>
    	    	<li>
    	    		<router-link :to="{name: 'service', params: {type: 6}}" :class=" pathName == navUrl[2] ? 'active' : ''">
    	    			<i class="iconfont">&#xe7f1;</i><span>餐饮住宿</span>
    	    		</router-link>
    	    	</li>
    	    </ul>
    	</footer>
    </template>
    
    <script>
    	export default {
    		data() {
    			return {
    				isShow: false,
    				navUrl : [0, 1, 2]
    			}
    		},
    		props: ['pathName'],
    		created() {
    		},
    		methods: {
    			showNav(state) {
    				this.$data.isShow = state ? false : true;
    			}
    		}
    	}
    </script>
    
    <style scoped lang="scss">
    	footer {
    		display: block;
    		 100%;
    		height: 50px;
    		position: fixed;
    		left: 0;
    		bottom: 0;
    		z-index: 100;
    		color: #000;
    		background: #fff;			
    		ul {
    			height: 100%;
    			overflow: hidden;
    			li {
    				display: inline-block;
    				position: relative;
    				float: left;
    				 33.33%;
    				height: 100%;
    				box-sizing: border-box;
    				.iconfont {
    					display: block;
    					margin-top: 4px;
    					font-size: 20px;
    				}
    			}
    		}
    		// 菜单栏选中点击样式
    		.active {
    			i, span {
    				color: #e60012;
    			}
    		}
    		a {
    			display: block;
    			 100%;
    			height: 100%;
    			font-size: 14px;
    			color: #5D656B;
    			text-align: center;
    		}
    	}
    
    	.slide-fade-enter-active {
    	  transition: all .3s ease;
    	}
    	.slide-fade-leave-active {
    	  transition: all .8s cubic-bezier(1.0, 0.5, 0.8, 1.0);
    	}
    	.slide-fade-enter, .slide-fade-leave-to {
    	  transform: translate3d(0, 100%, 0);
    	  opacity: 0;
    	}
    
    	@media screen and  (min- 1000px) {
    		footer {
    			height: 100px;
    			ul {
    				li {
    					.iconfont {
    						font-size: 48px;
    					}
    				}
    			}
    			a {
    				font-size: 24px;
    			}
    		}
    	}
    </style>
    

    home.vue引入了这几个组件

    //home.vue
    <template>
        <div id="main">
            <v-header sideBar="true" :isShowSideBar="isShowSideBar" :vrUrl="vRinfo.jumpUrl" :vrTitle="vRinfo.title" @breadcrumb="showSideBar">
                <span class="header-logo" slot="logo"><img class="logo" :src="logoImgUrl" alt="logo-title"></span>
            </v-header>
            <user-count></user-count>
            <!-- 首页滚动banner -->
            <div class="banner">
                <div class="swiper-container" @click="closeSideBar">
                    <div class="swiper-wrapper">
                        <!-- 从后端取数据进行渲染的 -->
                        <div class="swiper-slide" v-for="item in imageDataArr">
                           <img :src="item.INFO_IMAGE_URL" :alt="item.INFO_TITLE">
                        </div>
                    </div>
                    <!-- 如果需要分页器 -->
                    <div class="swiper-pagination swiper-pagination-white"></div>
                </div>
                <nav class="right-side">
                    <router-link :to="{name: 'service', params: {type: 13}}"><span>预订</span><span>门票</span></router-link>
                    <router-link v-if="isApp" :to="{name: 'dropBox', params: {url: vRinfo.jumpUrl, title: vRinfo.title}}"><span>虚拟</span><span>旅游</span></router-link>
                    <a v-if="!isApp" target="_blank" :href = "vRinfo.jumpUrl"><span>虚拟</span><span>旅游</span></a>
                    <a @click="showSideBar"><span>更多</span><span>功能</span></a>
                </nav>
            </div>
            <v-footer :pathName="1"></v-footer>
        </div>
    </template>
    
    <script>
    import Vue from 'vue';
    import vHeader from '../components/header'
    import userCount from '../components/userCount'
    import vFooter from '../components/footer.vue'
    import '../static/lib/js/swiper.min.js'
    import '../static/lib/css/swiper.min.css'
    
    export default {
        data() {
            return {
                isApp: false,           // 是否是园区一体机
                isShowSideBar: false,
                imageDataArr: [],       // 首页轮播图
                vRinfo: {               // 虚拟旅游
                    title: '',
                    jumpUrl: ''
                },
                logoImgUrl: ''
            }
        },
        components: {
            vHeader, userCount,  vFooter
        },
        created() {
    
        },
        mounted() {
            let isApp = window.localStorage ? localStorage.getItem('isApp') : Cookie.read('isApp');
            // 浏览器本地存储是否是一体机
            // 判断本地缓存里面是否已经存在isApp
            if(isApp == 'true') {
                this.logoImgUrl = '../static/logo/logo-red-pc.png';
                this.isApp = true;
            } else {
                // 判断是否是第一次进来首页,如果是,则获取params的参数
                this.isApp = this.$route.query && this.$route.query.app;
                if(this.isApp == 'true') {
                    // 保存到全局变量中
                    if(window.localStorage) {
                        localStorage.setItem('isApp', this.isApp);
                    } else {
                        Cookie.wirte('isApp', this.isApp);
                    }
                    this.logoImgUrl = '../static/logo/logo-red-pc.png';
                } else {
                    this.logoImgUrl = '../static/logo/logo-red-h5.png';
                }
            }
            this.initPage();
            this.getVRTravel();
        },
        methods: {
            initPage() {
                  let url = `/JSY_H5/h5/queryServiceList?type=1`;
                this.$http.get(url).then((response) => {
                    this.imageDataArr = response.data.rows;
                    // vue.nextTick在页面初始挂载就要渲染好轮播
                    Vue.nextTick(function() {
                        new Swiper('.swiper-container', {
                            autoplay: 10000, 
                            pagination: '.swiper-pagination',
                            loop: true
                        });
                    });
                }, (response) => {
                    console.log('oops, data is not found');                
                });
            },
            getVRTravel() {
                let url = '/JSY_H5/h5/queryServiceList?type=16';
                this.$http.get(url).then((response) => {
                    // 遍历数据,改变数据结构,套用同一天模板listTpl
                    this.$data.vRinfo['title'] = response.data.rows[0]['INFO_TITLE'];
                    this.$data.vRinfo['jumpUrl'] = response.data.rows[0]['JUMP_URL'];
                });
            },  
            showSideBar() {
                this.isShowSideBar = !this.isShowSideBar;
                console.log("this.isShowBar",this.isShowSideBar)
            },
            closeSideBar() {
                this.isShowSideBar = false;
            }
        }
    }
    </script>
    
    <style scoped lang="scss">
        #main {
            font-family: "Microsoft Yahei", 'Avenir', Helvetica, Arial, sans-serif;
            -webkit-font-smoothing: antialiased;
            -moz-osx-font-smoothing: grayscale;
            text-align: center;
            color: #2c3e50;
        }
        .header-logo {
            display: inline-block;
             100%;
            height: 40px;
            box-sizing: border-box;
            .logo {
                height: 100%;
            }
        }
        .banner {
            $right-side-size: 50px;
            .swiper-container {
                position: fixed;
                left: 0;
                right: 0;
                top: 40px;
                bottom: 50px;
                z-index: 10;
                overflow: hidden;
                .swiper-slide img {
                     100%;
                    height: 100%;
                }
            }
            .right-side {
                position: fixed;
                right: 4%;
                bottom: 70px;
                z-index: 10;
                 $right-side-size;
                a {
                    display: inline-block;
                     $right-side-size;
                    height: $right-side-size;
                    color: #fff;
                    background: #e60012;
                    border: 2px solid #fff;
                    padding: 5px;
                    border-radius: 50%;
                    box-shadow: 0 0 10px 0 rgba(0, 0, 0, .5);
                    box-sizing: border-box;
                    span {
                        display: block;
                        font-size: 14px;
                        height: 18px;
                        line-height: 18px;
                    }
                    &:not(:last-child) {
                        margin-bottom: 10px;
                    }
                }
            }
        }
    
        // 适配一体机样式
        @media screen and  (min- 1000px) {
            $right-side-size: 150px;
            .header-logo {
                height: 100px;
            }
            .banner {
                .swiper-container {
                    top: 100px;
                    bottom: 100px;
                }
                 .right-side {
                    right: 4%;
                    bottom: 50%;
                     $right-side-size;
                    transform: translate3d(0, 50%, 0);
                    a {
                         $right-side-size;
                        height: $right-side-size;
                        padding: 12px;
                        border: 5px solid #fff;
                        span {
                            font-size: 45px;
                            height: 55px;
                            line-height: 55px;
                        }
                    }
                }
            }
    
        }
    </style>
    

    在景区页面中引入了listTpl.vue

    //listTpl.vue
    <template>
    	<div>
    		<div class="list-tpl" >
    			<ul v-if="!isType" class="list-item">
    				<li v-for="item in items">
    			    	<router-link :to="{name: 'listDetail', params: {id: item.id, type: type, identifier: identifier}}">
    						<div class="list-image">
    							<img :src="item.imageUrl">
    						</div>
    						<aside >
    							<h3>{{ item.title }}</h3>
    							<article>{{ item.description }}</article>
    						</aside>
    	                </router-link>
    				</li>
    			</ul>
    
    			<ul v-if="isType" class="list-item">
    				<li v-for="item in items">
    					<div class="list-image">
    						<img :src="item.imageUrl">
    					</div>
    					<aside >
    						<h3>{{ item.title }}</h3>
    						<article v-html= "item.description"></article>
    						<a class="jump-url" v-if="!isApp" :href="item.jumpUrl" target="_blank">去预订</a>
    						<a class="jump-url" v-if="isApp" @click="showQRCode(item.qrCode)">去预订</a>
    					</aside>
    				</li>
    			</ul>
    	    </div>
    	    <div v-if="isShowQrBox" id="qrcode" @click="closeQrcodeBox">
    	    	<div class="mask"></div>
    	    	<div id="qrcode-content"></div>
    	    </div>
    	</div>
    </template>
    
    <script>
    	import Vue from 'vue';
    	import '../static/lib/js/jquery.qrcode.min.js';
    	export default {
    		data() {
    			return {
    				isApp: false,				// 判断是否使用不同的遍历模块, true => 调出二维码模板
    				isType: false, 				// 当type = 13 || 14时,显示去预定的模板
    				isShowQrBox: false
    			}
    		},
    		props: ['identifier', 'items', 'type'],
    		created() {
    			// 在listTpl页面中 只在预订门票和特色购物里面调出而二维码
    	        if(this.type == 13 || this.type == 14){
    	        	this.isType = true;
    	        	// 判断是否是园区一体机
    	        	let isApp = window.localStorage ? localStorage.getItem('isApp') : Cookie.read('isApp');
    				if(isApp == 'true') {
    					this.isApp = true;
    				}
    	        }
    		},
    		methods: {
    			showQRCode(url) {
    				this.isShowQrBox = true;
    				jQuery('#qrcode #qrcode-content').empty();
    				Vue.nextTick(function() {
    					jQuery('#qrcode #qrcode-content').qrcode(url);
    				});
    			},
    			// 关闭二维码框
    			closeQrcodeBox() {
    				this.isShowQrBox = false;
    			}
    		}
    	}
    </script>
    <style scoped lang="scss">
    	.list-tpl {
    		margin-top: 45px;
    		.list-item {
    			margin: 10px auto;
    			list-style: none;
    			height: 100vh;
    			overflow: auto;
    			background: #EDEDED;	
    			li {
    				display: inline-block;
    				 100%;
    				padding: 2%;
    				margin-bottom: 10px;
    				overflow: hidden;
    				box-sizing: border-box;
    				background: #fff;
    				a {
    					display:inline-block;
    				}
    				.list-image {
    					float: left;
    					 30vw;
    					height: 30vw;
    					margin-right: 3vw;
    					box-sizing: border-box;
    					img {
    						 100%;
    						height: 100%;	
    					}
    				}
    				aside {
    					position: relative;
    					min-height: 30vw;
    					font-size: 14px;
    					text-align: left;
    					overflow: hidden;
    					text-overflow: ellipsis;
    					box-sizing: border-box;
    					h3 {
    						color: #CD1940;
    						padding: 2px 0 5px 0;
    						font-size: 16px;
    						font-weight: bold;
    					}
    					article {
    						font-size: 14px;
    						color: #000;
    						line-height: 1.4;
    						text-align: justify;
    					}
    			        .jump-url {
    				        position: absolute;
    				        right: 0;
    				        bottom: 0;
    			             60px;
    			            height: 30px;
    			            line-height: 30px;
    			            text-align: center;
    			            color: #FFF;
    			            background: #e60012;
    			            box-sizing: border-box;
    			        }
    				}
    			}
    		}
    	}
    	#qrcode {
    		position: relative;
    		.mask {
    			position: fixed;
    			display: block;
    			left: 0;
    			right: 0;
    			top: 0;
    			bottom: 0;
    			background: rgba(0, 0, 0, 0.4);
    			z-index: 10;
    		}
    		#qrcode-content {
    			position: fixed;
    			left: 50%;
    			top: 50%;
    			padding: 15px;
    			text-align: center;
    			background: #fff;
    			z-index: 100;
    			transform: translate3d(-50%, -50%, 0);
    			&:after {
    				content: '扫一扫上面的二维码图案';
    				display: block;
    				padding-top: 10px;
    			}
    		}
    	}
    
    	@media screen and (min- 1000px) {
    		.list-tpl {
    			margin-top: 100px;
    			.list-item {
    				li {
    					aside {
    						h3 {
    							font-size: 38px;
    						}
    						article {
    							font-size: 32px;
    						}
    						.jump-url {
    					        position: absolute;
    					        right: 0;
    					        bottom: 0;
    				             120px;
    				            height: 60px;
    				            line-height: 60px;
    				            text-align: center;
    				            color: #FFF;
    				            font-size: 24px;
    				            background: #e60012;
    				            box-sizing: border-box;
    				        }
    					}
    				}
    			}
    		}
    	}
    </style>
    
    /#/?app=true
    

    我们其实可以猜测这个组件里面主要是展示景区相关图片,并且还有二维码扫码的功能,用jQuery做的
    完整的景区介绍的代码

    <template>
        <div>
            <v-header goBack="true" headTitle="景区介绍"></v-header>
            <list-tpl :items="scenicInfo" :type="type"  identifier="1"></list-tpl>
            <loading :show="done"></loading>
        </div>
    </template>
    
    <script>
        import vHeader from '../components/header.vue';
        import listTpl from '../components/listTpl.vue';
        import loading from '../components/loading.vue'; 
          
        export default {
          data() {
            return {
                done: false,
                type: '0',      // 这个类型应该是字符串,需要跟路由匹配到
                scenicInfo: []
            }
          },
          components: {
            vHeader, listTpl, loading
          },
          mounted() {
            // 页面初始化时加载数据
            this.initPage();
          },
          methods: {
            initPage() {
                this.done = true;
                let url = '/JSY_H5/h5/querySSSList';
                this.$http.get(url).then((response) => {
                    // 遍历数据,改变数据结构,套用同一套模板listTpl
                    response.data.rows.forEach((item, index) => {
                        let tmp = {};
                        tmp['description'] = item['SS_DESCRIPTION'];
                        tmp['id'] = item['SS_NO'];
                        tmp['imageUrl'] = item['SS_IMAGE_URL'];
                        tmp['title'] = item['SS_TITLE'];
                        this.$data.scenicInfo.push(tmp);
                    });
                    this.$data.done = false;
                }, (response) => {
                    this.$data.done = false;
                });
            }
          }
        }
      </script>
    
    //loading.vue
    <template>
      <transition>
        <svg class="spinner" :class="{ show: show }" v-show="show" width="68px" height="68px" viewBox="0 0 44 44">
          <circle class="path" fill="none" stroke-width="4" stroke-linecap="round" cx="22" cy="22" r="20"></circle>
        </svg>
      </transition>
    </template>
    
    <script>
      export default {
        props: ['show']
      }
    </script>
    
    <style lang="scss">
      $offset: 126;
      $duration: 1.4s;
      .spinner {
        position: fixed;
        z-index: 999;
        transition: opacity .15s ease;
        animation: rotator $duration linear infinite;
        animation-play-state: paused;
        right: 50%;
        top: 20%;
        margin-right: -34px;
        &.show {
          animation-play-state: running
        }
    
        &.v-enter, &.v-leave-active {
          opacity: 0;
        }
    
        &.v-enter-active, &.v-leave {
          opacity: 1;
        }
      }
    
      @keyframes rotator {
        0% {
          transform: scale(0.5) rotate(0deg);
        }
        100% {
          transform: scale(0.5) rotate(270deg);
        }
      }
    
      .spinner .path {
        stroke: #42b983;
        stroke-dasharray: $offset;
        stroke-dashoffset: 0;
        transform-origin: center;
        animation: dash $duration ease-in-out infinite;
      }
    
      @keyframes dash {
        0% {
          stroke-dashoffset: $offset;
        }
        50% {
          stroke-dashoffset: ($offset/2) transform rotate(135deg);
        }
        100% {
          stroke-dashoffset: $offset transform rotate(450deg);
        }
      }
    
    </style>
    

    //srcpageservice.vue
    <template>
        <div>
            <v-header goBack="true" :headTitle="headTitle"></v-header>
            <list-tpl :items="serviceInfo" :type="type"  identifier="2"></list-tpl>
            <v-footer :pathName="index" v-show=" type == 6 || type == 15"></v-footer>
            <loading :show="done"></loading>
        </div>
    </template>
    
    <script>
        import vHeader from '../components/header.vue';
        import listTpl from '../components/listTpl.vue';
        import loading from '../components/loading.vue';
        import vFooter from '../components/footer.vue';
        export default {
            data() {
                return {
                    type: null,
                    done: false,
                    index: 0,          // 动态显示footer导航栏显示位置
                    serviceInfo: []
                }
            },
            computed: {
                headTitle: function() {
                    let type = `${this.type}`;
                    switch(type) {
                        case '3':
                            type = '景区公告';
                            break;
                        case '6':
                            type = '餐饮住宿';
                            break;
                        case '7':
                            type = '周边景点';
                            break;
                        case '13':
                            type = '预订门票';
                            break;
                        case '14':
                            type = '特色购物';
                            break;
                        case '15':
                            type = '景区服务';
                            break;
                    }
                    return type;
                },
            },
            components: {
                vHeader, listTpl, loading, vFooter
            },
            created() {
          	    this.type = this.$route.params.type;
           },
            mounted() {
                // 页面初始化时加载数据
                this.initPage();
            },
            // 只在当前路由改变,但是该组件被复用时调用
            // to 表示 route即将要进去的路由
            // from 表示 route正要离开的路由
            beforeRouteUpdate(to, from, next) {
                this.type = to.params.type;
                next(this.initPage());          
            },
            methods: {
                initPage() {
                    // 判断footer底部导航栏的显示位置
                    if(this.type == 6) {
                        this.index = 2;  
                    } else if (this.type == 15) {
                        this.index = 0;
                    }
                    this.$data.serviceInfo = [];   // 初始化数据,防止footer底部导航栏切换数据没有清空
                    this.done = true;
                    let url = `/JSY_H5/h5/queryServiceList?type=${this.type}`;
                    this.$http.get(url).then((response) => {
                    	// 遍历数据,改变数据结构,套用同一天模板listTpl
                        response.data.rows.forEach((item, index) => {
                        	let tmp = {};
                        	tmp['description'] = item['INFO_DESCRIPTION'];
                        	tmp['id'] = item['INFO_NO'];
                        	tmp['imageUrl'] = item['INFO_IMAGE_URL'];
                        	tmp['title'] = item['INFO_TITLE'];
                            tmp['qrCode'] = item['QR_CORE_URL'];
                            tmp['jumpUrl'] = item['JUMP_URL'];
                        	this.$data.serviceInfo.push(tmp);
                        });
                        this.$data.done = false;
                    }, (response) => {
                        this.$data.done = false;
                    });
                }
            }
        }
      </script>
    

    //srcpage	ravelBox.vue
    <template>
    	<div>
            <v-header goBack="true" headTitle="旅行百宝箱"></v-header>
            <div class="travel-box">
    			<section class="item-box">
    				<router-link :to="{name: 'listDetail', params: {id: 5, type: 20, identifier: 0}}">
    					<i class="iconfont">&#xe656;</i>
    					<span>旅游线路</span>
    				</router-link>
    				<router-link :to="{name: 'externalMap'}">
    					<i class="iconfont">&#xe621;</i>
    					<span>外部交通</span>
    				</router-link>
    				<router-link :to="{name: 'listDetail', params: {id: 4, type: 21, identifier: 0}}">
    					<i class="iconfont">&#xe638;</i>
    					<span>景区地图</span>
    				</router-link>
    				<router-link :to="{name: 'service', params: {type: 7}}">
    					<i class="iconfont">&#xe600;</i>
    					<span>周边景点</span>
    				</router-link>
    				<router-link :to="{name: 'service', params: {type: 6}}">
    					<i class="iconfont">&#xe7f1;</i>
    					<span>餐饮,住宿</span>
    				</router-link>
    			</section>			
            </div>
    	 </div>
    </template>
    
    	<script>
    		import vHeader from '../components/header'
    		export default {
    			data() {
    				return {
    				}
    			},
    			components: {
    				vHeader
    			},
    			mounted() {
    
    			}
    		}
    	</script>
    
    	<style scoped lang="scss">
    		.travel-box {
    			margin-top: 42px;
    				height: 100vh;
    				background: #F5F5F5;
    				a {
    					display: inline-block;
    					 32%;
    					height: 100px;
    					margin: 0 2% 2% 0;
    					color: #5D656B;
    					background: #fff;
    					text-align: center;
    					box-sizing: border-box;
    					&:nth-child(3n + 0) {
    						margin-right: 0;
    					}
    					i {
    						display: block;
    						font-size: 48px;
    						line-height: 60px;
    						margin-top: 10px;
    					}
    					span {
    						font-size: 16px;
    					}
    				}
    		}
    		@media screen and (min- 1000px) {
    			.travel-box {
    				margin-top: 100px;
    				a {
    					height: 200px;
    					i {
    						font-size: 64px;
    						line-height: 100px;
    					}
    					span {
    						font-size: 24px;
    					}
    				}
    			}
    		}
    </style>
    
    //listDetail
    <template>
        <div class="detail">
            <v-header goBack="true" :headTitle="listDetail.title"></v-header>
            <div class="audio-play" v-if="this.identifier == 1 && listDetail.audio">
                <i v-on:click="playAudio" class="iconfont">&#xe66b;&nbsp;音频播放</i>
                <audio  id="audio" :src="listDetail.audio" loop="true">
                    你的浏览器不支持 <code>audio</code> 音频播放功能.
                </audio>
            </div>
            <div class="detail-body" v-show="isShow">
                <section v-html="listDetail.content"></section>
                <review :id="detailId" :qrCodeUrl="qrCodeUrl" v-if="needReview"></review>
            </div>
            <loading :show="done"></loading>
        </div>
    </template>
    
    <script>
        import loading from '../components/loading.vue';
        import vHeader from '../components/header.vue';
        import review from '../components/review.vue';
        export default {
            data() {
              return {
                done: false,
                isShow: false,     // 只有当数据加载完成之后才能够实现出来
                needReview: false,  //是否需要显示评论(只有景点才需要,其他的地方都是不需要的,默认关闭)
                detailId: '',
                type: '',          // 判断当前的模块信息
                identifier: '',    // 标识符 景点介绍模块为1 旅行百宝箱模块为0
                shopUrl: '',
                qrCodeUrl: '',      // 二维码的生成地址
                listDetail: {      // 详情列表信息
                    title: '',
                    content: '',
                    audio: null
                }
              }
            },
            components: {
                loading, vHeader, review
            },
            created() {
                this.detailId = this.$route.params.id;
                this.identifier =  this.$route.params.identifier || 0;
                this.type = this.$route.params.type;
            },
            mounted() {
               this.initPage();
            },
            methods: {
                initPage() {
                    let listDetailUrl = '';
                    this.$data.done = true;
                    if(this.identifier == 1) {  
                        listDetailUrl = `/JSY_H5/h5/querySSSOne?id=${this.detailId}`;   // 景点介绍调用的接口
                    } else if(this.identifier == 2) {
                        listDetailUrl = `/JSY_H5/h5/queryServiceOne?id=${this.detailId}`;   // service.vue下面过来调用接口
                    } else {
                        listDetailUrl = `/JSY_H5/h5/queryServiceList?type=${this.detailId}`;     // 旅游线路,景区地图调用的接口
                    }
    
                    this.$http.get(listDetailUrl).then((response) => {
                        this.done = false;
                        this.isShow = true;
                        let data = response.data.rows;
                        // 景点介绍
                        if(this.identifier == 1) {
                            this.listDetail.title = data[0].SS_TITLE;
                            this.listDetail.content = data[0].SS_CONTENT;
                            this.listDetail.audio = data[0].SS_VIDEO_URL;
                            this.qrCodeUrl = data[0].QR_CORE_URL;
                            this.needReview = true;
                        } else {
                            // 资讯
                            this.listDetail.title = data[0].INFO_TITLE;
                            this.listDetail.content = data[0].INFO_CONTENT;
                            this.needReview = false;
                        }
                        // 由于后台传过来是一段字符串 需要使用正则来适配一体机文字大小
                        let isApp = window.localStorage ? localStorage.getItem('isApp') : Cookie.read('isApp');
                        if(isApp == 'true') {
                            this.listDetail.content = this.listDetail.content.replace(/font-size:s*d+px;/g, 'font-size: 32px;');
                        }
                    }, (response) => {
                        console.log('opps Is Error: ' + response);
                        this.done = false;
                    })
                },
                playAudio() {
                    let audio = document.getElementById('audio');
                    var isPlaying = audio.currentTime > 0 && !audio.paused && !audio.ended 
                        && audio.readyState > 2;
    
                    if (!isPlaying) {
                      audio.load(); 
                      audio.play();
                    }
                }
            }
        }
    </script>
    
    <style lang="scss">
      .detail {
        padding-top: 40px;  // 移除头部header的高度
        .audio-play {
             100%;
            color: #fff;
            padding: 1% 4%;
            text-align: right;
            background: #000;
            opacity: .4;
            box-sizing: border-box;
            i {
                display: inline-block;
                 100px;
                height: 30px;
                line-height: 30px;
            }
        }
        .detail-body {
            padding: 10px 10px 40px 10px ;
            section {
                100%;
                img {
                    100%;
                }
            }
        }
        footer {
            position: absolute;
            right: 0;
            bottom: 0;
             100%;
            height: 40px;
            background: #f6f6f6;
            text-align: right;
            a {
                display: inline-block;
                 80px;
                height: 40px;
                line-height: 40px;
                padding: 2px;
                color: #FFF;
                text-align: center;
                background: #e60012;
                box-sizing: border-box;
            }
        }
      }
      @media screen and (min- 1000px) {
        .detail {
            padding-top: 100px;
            .audio-play {
                i {
                    font-size: 32px;
                     200px;
                    height: 50px;
                    line-height: 50px;
                }
            }
            footer {
                height: 100px;
            }
        }
    }
    </style>
    

    这个组件中引用了review组件

    <template>
    	<div>
    		<div class="reviews" v-show="isShow">
    			<ul>
    				<li><i class="iconfont">&#xe73d;</i>{{ visitCount }}</li>
    				<li @click.once="upVote" :class="{active: isActive }"><i class="iconfont">&#xe644;</i>{{ goodCount }}</li>
    				<li @click="showReviewBox"><i class="iconfont">&#xe761;</i>写评论</li>
    				<li @click="showCommentBox"><i class="iconfont">&#xe649;</i>{{ reviewCount }}</li>
    			</ul>
    		</div>
    		<transition name="slide-fade-down">
    			<div v-show="isShowReviewBox" class="reviews-box">
    				<div class="header">
    					<span @click="closeReviewBox">取消</span>
    					<span>评论</span>
    					<span @click="addReview" :class="isSend">发送</span>
    				</div>
    				<div class="body">
    					<textarea v-model="reviewContent" autofocus maxlength="120" required></textarea>
    				</div>
    			</div>
    		</transition>
    		<transition name="slide-fade-right">
    		<div v-show="isShowCommentBox" class="comment-box">
    			<div @click.stop.prevent="closeCommentBox" class="mask"></div>
    			<div class="comment-main">
    				<section v-for="(item, index) in reviewData">
    					<div class="reviews-author"><span>游客</span></div>
    					<div class="reviews-body">
    						<p class="reviews-content">{{ item.SSR_CONTENT }}</p>
    						<p>{{ item.ENTRY_DATE_TIME  | time}}</p>
    					</div>
    				</section>
    			</div>
    		</div>
    		</transition>
    	    <div v-if="isShowQrBox" id="qrcode" @click="closeQrcodeBox">
    	    	<div class="mask"></div>
    	    	<div id="qrcode-content"></div>
    	    </div>
    	    <div v-if="isShowTipBox" class="tip-box">
    	    	您的评论已经提交,请等待审核通过...
    	    </div>
    	</div>
    </template>
    
    <script>
    	import Vue from 'vue';
    	import '../static/lib/js/jquery.qrcode.min.js'
    	export default {
    		data() {
    			return {
    				isShow: true,				
    				SS_NO: this.id,				// 当前的景点id
    				isActive: false,
    				reviewData: [],   			// 评论数
    				visitCount: 0,    			// 访问数
    				goodCount: 0,	  			// 点赞数
    				reviewCount: 0,   			// 评论数
    				reviewContent: '', 			// 评论内容
    				isShowReviewBox: false,		// 是否显示评论框
    				isShowCommentBox: false,     // 是否显示评论列表
    				isShowQrBox: false,          // 是否显示二维码
    				isShowTipBox: false			  // 是否显示评论成功提示框
    			}
    		},
    		props: ['id', 'qrCodeUrl'],
    		mounted() {
    			this.initPage();
    		},
    		computed: {
    			isSend: function () {
    				return {
    					active:	!!this.$data.reviewContent.length
    				}   
    			}
    		},
    		filters: {
    			// 格式化时间
    			time: function(date) {
    				if(!date) return '';
    			    var date = new Date(date);
    			    var Y = date.getFullYear() + '-';
    			    var M = (date.getMonth()+1 < 10 ? '0'+(date.getMonth()+1) : date.getMonth()+1) + '-';
    			    var D = (date.getDate() < 10 ? '0' + (date.getDate()) : date.getDate()) + ' ';
    			    	return Y + M + D;
    			}
    		},
    		methods: {
    			// 评分
    			showRate(rate) {
    				if(!rate) rate = 5;
    				return "★★★★★☆☆☆☆☆".slice(5 - rate, 10 - rate);
    			},
    			// 判断是否显示评论界面
    			showReviewBox() {
    				let isApp = window.localStorage ? localStorage.getItem('isApp') : Cookie.read('isApp');
    				if(isApp == 'true') {			// 如果当前是一体机访问 则无法添加评论 调出二维码
    					let url = this.qrCodeUrl;
    					this.$data.isShowReviewBox = false;
    					this.isShowQrBox = true;
    					jQuery('#qrcode #qrcode-content').empty();
    					Vue.nextTick(function() {
    						jQuery('#qrcode #qrcode-content').qrcode(url);			// 使用ES6来进行字符串转义
    					});
    				} else {
    					this.$data.isShowReviewBox = !this.$data.isShowReviewBox;
    				}
    			},
    			showCommentBox() {
    				if(this.reviewCount == 0) return false;     // 如果当前的评论数为0 则不显示评论列表
    				this.$data.isShowCommentBox = !this.$data.isShowCommentBox;
    			},
    			// 关闭评论界面
    			closeReviewBox() {
    				this.$data.isShowReviewBox = false;
    			},
    			closeCommentBox() {
    				this.$data.isShowCommentBox = false;
    			},
    			// 添加评论
    			addReview() {
    				let url = `/JSY_H5/h5/saveSSR`;
    				this.$http.post(url, {
    					SS_NO: this.$data.SS_NO,
    					SSR_CONTENT: this.$data.reviewContent
    				}).then( (response) => {
    					this.closeReviewBox();
    					this.reviewContent = '';
    					this.isShowTipBox = true;
    					// 需要使用箭头函数来邦定this的值
    					setTimeout(() => {
    						this.isShowTipBox = false;
    					}, 1000);
    				}, (response) => {
    					console.log('opps Is Error: ' + response);
    				})
    			},
    			initPage() {
    				let url = `/JSY_H5/h5/querySSRList?id=${this.$data.SS_NO}`;
    				this.$http.get(url).then((response) => {
    					this.$data.reviewData = response.data.rows;
    				}, (response) => {
    					console.log('opps Is Error: ' + response);
    				});
    				this.getUserVisit();	// 获取评论接口中 访问量和点赞数
    			},
    			// 获取当前景点的页面访问量点赞数以及评论数
    			getUserVisit() {
    				let url = `/JSY_H5/h5/addInteractive?id=${this.$data.SS_NO}`;  // 游客访问量
    				this.$http.get(url).then((response) => {
    					this.$data.goodCount = response.data.GOODED_COUNT;
    					this.$data.visitCount = response.data.LOOKED_COUNT;
    					this.$data.isActive = response.data.IS_GOODED;
    					this.$data.reviewCount = response.data.REVIEW_COUNT;
    				}, (response) => {
    					console.log('opps Is Error: ' + response);
    				});
    			},
    			// 添加点赞
    			upVote() {
    				let url = `/JSY_H5/h5/addInteractive?id=${this.$data.SS_NO}&ACTION="good"`;  // 当前景点-点赞数
    				this.$http.get(url).then((response) => {
    					this.$data.goodCount = response.data.GOODED_COUNT;
    					this.$data.isActive = true;
    				}, (response) => {
    					console.log('opps Is Error: ' + response);
    				});
    			},
    			// 关闭二维码框
    			closeQrcodeBox() {
    				this.isShowQrBox = false;
    			}
    		}
    	}	
    </script>
    
    
    <style scoped lang="scss">
    	/* 底部详情操作框 */
    	.reviews {
    		position: fixed;
    		bottom: 0;
    		left: 0;
    		right: 0;
    		height: 60px;
    		z-index: 100;
    		background: #F6F6F6;
    		ul  {
    			padding: 0 5%;
    			li {
    				display: inline-block;
    				 25%;
    				height: 30px;
    				line-height: 30px;
    				margin: 15px 4% 0 0;
    				text-align: center;
    				border-radius: 10%;
    				background: #fff;
    				box-sizing: border-box;
    				i {
    					margin-right: 5px;
    				}
    				&:last-child {
    					color: #e60012;
    					 13%;
    					margin-right: 0;
    				}
    			}
    		}
    		/* 选中样式 */
    		.active {
    			color: #e60012;
    			pointer-events: none;
    		}
    	}
    	/* 评论框基本样式 */
    	.reviews-box {
    		position: fixed;
    		left: 0;
    		right: 0;
    		bottom: 0;
    		z-index: 200;
    		 100%;
    		height: 100px;
    		padding: 2% 8% 5%; 
    		background: #F6F6F6;
    		box-sizing: border-box;
    		.header {
    			 100%;
    			padding-bottom: 5px;
    			text-align: center;
    			span {
    				color: #000;
    				&:first-child {
    					float: left;
    				}
    				&:last-child {
    					float: right;
    					color: #333;
    					pointer-events: none;
    					&.active {
    						pointer-events: auto;
    						color: #e60012;
    					}
    				}
    			}
    		}
    		/* 用户编辑框 */
    		.body {
    			textarea {
    				min-height: 40px;
    				 100%;
    				padding: 2%;
    				font-size: 14px;
    				border-radius: 5%;
    				border: 2px solid #F6F6F6;
    				background: #fff;
    				box-sizing: border-box;
    				resize: none;
    				box-shadow: none;
    			}
    		}
    	}
    	/* 动画效果 */
    	.slide-fade-down-enter-active, .slide-fade-down-leave-active  {
    		transition: all 1s ease-in;
    	}
    	.slide-fade-down-enter, .slide-fade-down-leave-to{
    		transform: translate3d(0, 100px, 0);
    	}
    
    	.slide-fade-right-enter-active, .slide-fade-right-leave-active  {
    		transition: all 1s ease-in;
    	}
    	.slide-fade-right-enter, .slide-fade-right-leave-to{
    		transform: translate3d(100%, 0, 0);
    	}
    	.tip-box {
    		position: absolute;
    		left: 50%;
    		top: 50%;
    		transform: translate3d(-50%, -50%, 0);
    		 200px;
    		height: 100px;
    		font-size: 18px;
    		text-align: justify;
    		padding: 10px 20px;
    		background: #fff;
    		box-shadow: 1px 1px 10px rgba(0, 0, 0, .5);
    		box-sizing: border-box;
    	}
    	/* 右侧评论列表 */
    	.comment-box {
    		position: fixed;
    		top: 40px;
    		bottom: 50px;
    		right: 0;
    		 80%;
    		overflow-y: auto;
    		background: #F6F6F6;
    		.mask {
    			position: fixed;
    			display: block;
    			left: 0;
    			right: 0;
    			top: 0;
    			bottom: 0;
    			background: rgba(0, 0, 0, .5);
    			z-index: 100;
    		}
    		.comment-main {
    			position: relative;
    			z-index: 100;
    			section {
    				min-height: 80px;
    				padding: 2%;
    				background: #fff;
    				overflow: hidden;
    				text-align: left;
    				font-size: 14px;
    				border-bottom: 2px solid #F6F6F6;
    				box-sizing: border-box;
    				.reviews-author {
    					float: left;
    					 25%;
    					height: 80px;
    					padding-left: 4%;
    					margin-right: 2%;
    					color: #333;
    					box-sizing: border-box;
    				}
    				.reviews-body {
    					min-height: 80px;
    					overflow: hidden;
    					.reviews-content {
    						min-height: 40px;
    					}
    					p {
    						&:first-child span {
    							color: #e60012;
    						}
    						&:last-child {
    							font-size: 12px;
    						}
    					}
    				}
    			}
    		}
    	}
    	@media screen and  (min- 1000px) {
    		.comment-box {
    			top: 100px;
    			bottom: 60px;
    			.comment-main {
    				section {
    					font-size: 32px;
    					.reviews-body {
    						p {
    							&:last-child {
    								font-size: 24px;
    							}
    						}
    					}
    				}
    			}
    		}
    	}
    	#qrcode {
    		position: relative;
    		.mask {
    			position: fixed;
    			display: block;
    			left: 0;
    			right: 0;
    			top: 0;
    			bottom: 0;
    			background: rgba(0, 0, 0, 0.4);
    			z-index: 10;
    		}
    		#qrcode-content {
    			position: fixed;
    			left: 50%;
    			top: 50%;
    			padding: 15px;
    			text-align: center;
    			background: #fff;
    			z-index: 100;
    			transform: translate3d(-50%, -50%, 0);
    			&:after {
    				content: '扫一扫上面的二维码图案';
    				display: block;
    				padding-top: 10px;
    
    			}
    		}
    	}
    </style>
    
    //srcpageexternalMap.vue
    <template>
    	<div>
            <v-header goBack="true" headTitle="外部地图"></v-header>
            <div class="travel-box">
    			<div id="allmap"></div>
            </div>
    
        </div>
    </template>
    
    <script>
    	import vHeader from '../components/header'
    	export default {
    		data() {
    			return {
    			}
    		},
    		components: {
    			vHeader
    		},
    		mounted() {
    
    			//百度地图API功能
    			var map = new BMap.Map("allmap");    // 创建Map实例
    			map.centerAndZoom(new BMap.Point(119.199201,34.019519), 18);  // 初始化地图,设置中心点坐标和地图级别
    			map.addControl(new BMap.MapTypeControl());   //添加地图类型控件
    			map.setCurrentCity("淮安国缘宾馆");          // 设置地图显示的城市 此项是必须设置的
    			map.enableScrollWheelZoom(true);     //开启鼠标滚轮缩放
    			// 编写自定义函数,创建标注
    			function addMarker(point){
    			  var marker = new BMap.Marker(point);
    			  map.addOverlay(marker);
    			}
    			// 向指定地图里面添加标注
    			addMarker(new BMap.Point(119.199201,34.019519));
    		}
    	}
    </script>
    
    <style scoped lang="scss">
    	.travel-box {
    		margin-top: 60px;
    	}
    	#allmap {
    		 100%;
    		height: 400px;
    	}
    	@media screen and (min- 1000px) {
    		.travel-box {
    			margin-top: 100px;
    		}
    		#allmap {
    			height: 600px;
    		}
    	}
    </style>
    

    后记:我挺喜欢这个项目的代码的,哈哈哈,因为都看得懂,还能够猜到作者的意图。

  • 相关阅读:
    sql 主键 标识 默认值
    SQL Server跨服务器查询
    C# 取整数
    RegisterClientScriptBlock、RegisterStartupScript
    UpdatePanel
    C#创建(从数据库中导出)Excel文件(含Interop.Excel.Dll)
    基类、接口的应用——表单控件:一次添加、修改一条记录,一次修改多条记录。(上)
    利用JS获取IE客户端IP及MAC的实现
    Net用DataTable导出Excel通用函数(修正了Excel进程删除不掉问题)
    感人至深的文章
  • 原文地址:https://www.cnblogs.com/smart-girl/p/11166096.html
Copyright © 2020-2023  润新知