手机扫描二维码
# 全局安装 vue-cli
$ npm install --global vue-cli
# 创建一个基于 webpack 模板的新项目
$ vue init webpack my-project(sell)
# 安装依赖,走你
$ cd my-project(sell)
$ npm install
$ npm run dev
├── build // 构建服务和webpack配置 ├── config // 项目不同环境的配置 ├── index.html // 项目入口文件 ├── package.json // 项目配置文件 ├── src // 生产目录 │ ├── common // 公共的css js 资源 │ ├── components // 各种组件 │ ├── router // 路由 │ ├── App.vue // 主页面 │ └── main.js // Webpack 预编译入口
import Vue from 'vue';
import App from './App';
import router from './router';
// index.js会自动寻找到,也可以写全(import router from './router/index.js')
import VueResource from 'vue-resource';
import './common/styles/index.scss';/* 设置为 false 以阻止 vue 在启动时生成生产提示 */
fig.productionTip = false;Vue.use(VueResource); // 全局注册/* eslint-disable no-new */
new Vue({el: '#app',router,components: { App },template: '<App/>'
});
<template><div id="app"><v-header v-bind:seller="seller"></v-header><div class='tab border-b-1px'><div class='item-tab'><router-link to="/goods">商品</router-link></div><div class='item-tab'><router-link to="/ratings">评论</router-link></div><div class='item-tab'><router-link to="/seller">商家</router-link></div></div><!--主要用于保留组件状态或避免重新渲染--><keep-alive><router-view v-bind:seller="seller"></router-view></keep-alive></div>
</template><script>
import header from './components/header/header.vue';
import {urlParse} from './common/js/util.js';
// import data from './common/json/data.json';
const ERR_OK=0;
export default {name:'App',data () {return {seller:{id: (() => {let queryParam=urlParse();return queryParam.id;})()}};},created (){this.$('/api/seller?id=' + this.seller.id).then(response => {if(===ERR_OK){// 用于对象的合并 , Object.assign方法的第一个参数是目标对象,后面的参数都是源对象。this.seller=Object.assign({},this.seller,response.data.data);}else{console.log('no data');}});// this.seller=Object.assign({},this.seller,data.seller);},components:{'v-header':header}
};
</script><style lang="scss" scoped>@import "./common/styles/mixin.scss";#app{.tab{display:flex;width:100%;height:40px;line-height:40px;font-size:14px;color:rgb(240,20,20);@include border-b-1px(rgba(7,17,27,0.1));.item-tab{flex:1;text-align:center;.active{color:rgb(240,20,20);}}}}
</style>
import VueResource from 'vue-resource';Vue.use(VueResource); // 全局注册
data () {return {seller:{id: (() => {let queryParam=urlParse();return queryParam.id;})()}};},
created (){this.$('/api/seller?id=' + this.seller.id).then(response => {if(===ERR_OK){// 用于对象的合并 , Object.assign方法的第一个参数是目标对象,后面的参数都是源对象。this.seller=Object.assign({},this.seller,response.data.data);}else{console.log('no data');}});// this.seller=Object.assign({},this.seller,data.seller);},
当一个组件被定义,data 必须声明为返回一个初始数据对象的函数,因为组件可能被用来创建多个实例。如果 data 仍然是一个纯粹的对象,则所有的实例将共享引用同一个数据对象!通过提供 data 函数,每次创建一个新实例后,我们能够调用 data 函数,从而返回初始数据的一个全新副本数据对象。
import header from './components/header/header.vue';
components:{'v-header':header
}
<v-header v-bind:seller="seller"></v-header>
<template>
...
</template><script>
export default{
...props: {seller:{type:Object,required:true}}
...
};
</script><style lang="scss" scoped>
...
</style>
import Vue from 'vue';
import Router from 'vue-router';
import goods from '@/components/goods/goods.vue';
import ratings from '@/components/ratings/ratings.vue';
import seller from '@/components/seller/seller.vue';Vue.use(Router);const routes=[{path: '/',redirect: 'goods', // 重定向},{path: '/goods',component: goods},{path: '/ratings',component: ratings},{path: '/seller',component: seller}
];
export default new Router({// 激活class类名linkActiveClass:'active',routes
});
new Vue({el: '#app',router,components: { App },template: '<App/>'
});
在 App.vue 中通过 router-link 组件实现
<router-link to="/goods">商品</router-link>
注意:不支持target=”_blank”属性,如果你想打开一个新标签页,你必须用标签。
最后通过 router-view 组件渲染
<keep-alive><router-view v-bind:seller="seller"></router-view>
</keep-alive>
// keep-alive 主要用于保留组件状态或避免重新渲染
<template><div class="header"><!--内容区--><div class="content-wrapper"><div class="avatar"><img v-bind:src="seller.avatar" width="64" height='64'/></div><div class="content"><div class="title"><span class="brand"></span><span class="name">{{seller.name}}</span></div><div class="description">{{seller.description}}/{{seller.deliveryTime}}分钟送达</div><div v-if="seller.supports" class="support"><!--判断是否存在--><span class="icon" v-bind:class="classMap[seller.supports[0].type]"></span><span class="text">{{seller.supports[0].description}}</span></div></div><div v-if="seller.supports" class="support-count" @click="showDetail"><span class="count">{{seller.supports.length}}个</span><i class="icon-keyboard_arrow_right"></i></div></div><!--公告区--><div class="bulletin-wrapper" @click="showDetail"><span class="bulletin-title"></span><span class="bulletin-text">{{seller.bulletin}}</span><i class="icon-keyboard_arrow_right"></i></div><!--背景--><div class="background"><img v-bind:src="seller.avatar" width="100%" height="100%" /></div><!--遮罩层 ,详情页--><transition name="fade"><div class="detail" v-show="detailShow"><div class="detail-wrapper clearfix"><div class="detail-main"><h1 class="name">{{seller.name}}</h1><div class="star-wrapper"><star :size="48" :score="seller.score"></star></div><div class="title"><div class="line"></div><div class="text">优惠信息</div><div class="line"></div></div><ul v-if="seller.supports" class="supports"><li class="support-item" v-for="(item ,index) in seller.supports"><span class="icon" :class="classMap[seller.supports[index].type]"></span><span class="text">{{seller.supports[index].description}}</span></li></ul><div class="title"><div class="line"></div><div class="text">商家公告</div><div class="line"></div></div><div class="bulletin"><p class="content">{{seller.bulletin}}</p></div></div></div><div class="detail-close" @click="hideDetail"><i class="icon-close"></i></div></div></transition></div>
</template><script>
import star from "../star/star.vue";
export default{data(){return{classMap:[],detailShow:false}},methods:{showDetail(){this.detailShow=true;},hideDetail(){this.detailShow=false;}},props: {seller:{type:Object,required:true}},created (){this.classMap=['decrease','discount','guarantee','invoice','special'];},components:{star}
};
</script><style lang="scss" scoped>
@import "../../common/styles/mixin.scss";.header {position:relative;overflow:hidden;color:#fff;background:rgba(7,17,27,0.5);.content-wrapper { position:relative;padding:24px 12px 18px 24px;font-size:0;.avatar { display:inline-block;vertical-align:top;img{ border-radius:2px;}}.content {display:inline-block;margin-left:16px;font-size:14px;.title { margin:2px 0 8px 0;.brand { display:inline-block;vertical-align:top;width:30px;height:18px;@include bg-image("img/brand"); background-size:30px 18px;background-repeat: no-repeat;}.name {margin-left:6px;font-size:16px;line-height:18px;font-weight: bold;}}.description {margin-bottom: 10px;line-height:12px;font-size:12px;}.support {.icon { display:inline-block;vertical-align:top;width:12px;height:12px;margin-right: 4px;background-size: 12px 12px;background-repeat: no-repeat;&.decrease { @include bg-image("img/decrease_1"); } &.discount { @include bg-image("img/discount_1"); } &.guarantee { @include bg-image("img/guarantee_1"); } &.invoice { @include bg-image("img/invoice_1"); } &.special { @include bg-image("img/special_1"); } } .text{ line-height:12px;font-size:10px;}}}.support-count {position:absolute;right:12px;bottom:14px;padding:0 8px;height:24px;line-height: 24px;border-radius:14px;background-color:rgba(0,0,0,0.2);.count{ vertical-align:top;font-size: 10px;}.icon-keyboard_arrow_right{margin-left: 2px;line-height:24px;font-size: 10px;}}}.bulletin-wrapper{position:relative;height:28px;line-height: 28px;padding:0 22px 0 12px;white-space: nowrap;overflow:hidden;text-overflow:ellipsis;background:rgba(7,17,27,0.2);.bulletin-title{ display:inline-block;vertical-align:top;margin-top:8px;width:22px;height:12px;@include bg-image("img/bulletin"); background-size:22px 12px;background-repeat:no-repeat;}.bulletin-text{vertical-align:top;margin:0 4px;font-size:10px;}.icon-keyboard_arrow_right{position:absolute;font-size:10px;right:12px;top:8px;}}.background{position:absolute;top:0;left:0;width:100%;height:100%;background:red;z-index:-1;filter:blur(10px);}.detail{position:fixed;z-index:100;top:0;left:0;width:100%;height:100%;overflow:auto;background:rgba(7,17,27,0.8);backdrop-filter:blur(10px);transition: all 0.5s;&.fade-enter,&.fade-leave-to{ opacity:0;}.detail-wrapper{width:100%;min-height: 100%;.detail-main{ margin-top:64px;padding-bottom:64px;.name{ line-height:16px;text-align:center;font-size:16px;font-weight: 700;}.star-wrapper{margin-top:16px;padding:2px 0;text-align:center;}.title{display:flex;width:80%;margin:28px auto 24px auto;.line{ flex:1;position:relative;top:-6px;border-bottom:1px solid rgba(255,255,255,0.2);}.text{padding:0 12px;font-size:15px;font-weight:700;}}.supports{width:80%;margin:0 auto;.support-item{ padding:0 12px;margin-bottom:12px;font-size:0px;&:last-child{ margin-bottom:0;}.icon{display:inline-block;vertical-align: top;width:16px;height:16px;margin-right:6px;background-size:16px 16px;background-repeat: no-repeat;&.decrease { @include bg-image("img/decrease_2"); } &.discount { @include bg-image("img/discount_2"); } &.guarantee { @include bg-image("img/guarantee_2"); } &.invoice { @include bg-image("img/invoice_2"); } &.special { @include bg-image("img/special_2"); } } .text{ line-height:16px;font-size:12px;}}}.bulletin{width:80%;margin:0 auto;.content{ padding:0 12px;line-height:24px;font-size:12px;}}}}.detail-close{position:relative;width:32px;height:32px;margin:-64px auto 0 auto;font-size:32px;}}
}
</style>
指令
v-on:click.stop="doThis"
过渡动画 :transition 组件
<transition name="fade">
...
</transition>
transition: all 0.5s;
&.fade-enter,&.fade-leave-to{opacity:0;
}
本文发布于:2024-02-02 22:31:54,感谢您对本站的认可!
本文链接:https://www.4u4v.net/it/170688431446872.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
留言与评论(共有 0 条评论) |