zoukankan      html  css  js  c++  java
  • Vue 项目 购物车 模块

    购物车 ajax 接口请求拆分到 service 文件夹中

    // goods.js
    import axios from 'axios'
    
    export default {
        getGoodsInfo () {
            return axios.get('/api/goods')
            .then(res => {
                // 处理数据格式,并返回
                const {code, data: goodsInfo, slider, keys} = res.data;
                if (code) {
                    return {goodsInfo, slider, keys};
                } else {
                    return null;
                }
            });
        }
    }
    

    路由切换动态

    // 1. 使用 transition 组件 嵌套 router-view 组件
    <transition name="route-move">
    	<router-view class="child-view" />
    </transition>
    
    // 2. 通过 CSS 定义路由切换动画
    .route-move-enter {
        // 入场前状态
        transform: translate3d(-100%, 0, 0);
    }
    .route-move-leave-to{
        // 离场后状态
        transform: translate3d(100%, 0, 0);
    }
    .route-move-enter-active,
    .route-move-leave-active{
        // 激活状态
        transition: transform 0.3s;
    }
    

    购物车动画,使用 Vue 的 JS 方式的半场动画

    // CartAnim.vue
    <template>
    <div class="ball-wrap">
    	<transition
    		@before-enter="beforeEnter"
    		@enter="enter"
    		@after-enter="afterEnter"
    	>
    		<div class="ball" v-show="show">
    			<div class="inner">
    				<div class="cubeic-add"></div>
    			</div>
    		</div>
    	</transition>
    </div>
    </template>
    
    <script>
    export default {
        name: "cartAnim",
        data () {
            return {
                show: false
            }
        },
        methods: {
            start(el) {
                // 启动动画接口,传递点击按钮元素
                this.el = el;
                // 适应.ball显示,激活动画钩子
                this.show = true;
            },
            beforeEnter(el) {
                // 把小球移动到点击的DOM元素所在位置
                const rect = this.el.getBoundingClientRect();
                // 转换为用于绝对定位的坐标
                const x = rect.left - window.innerWidth /2;
                const y = -(window.innerHeight - rect.top - 10 - 20);
                // ball 只移动 y 轴
                el.style.transfrom = `translate3d(0, ${y}px, 0)`;
                // inner 只移动 x 轴
                const inner = el.querySelector(".inner");
                inner.style.transform = `translate3d(${x}px, 0, 0)`;
            },
            enter(el, done) {
                // 获取offsetHeight就会重绘
                document.body.offsetHeight;
                //指定动画结束位置
                el.style.transform = `translate3d(0, 0, 0)`;
                const inner = el.querySelector(".inner");
                inner.style.transform = `translate3d(0, 0, 0)`;
                el.addEventListener("transitionend", done);
            },
            afterEnter(el) {
                // 动画结束, 开始清理工作
                this.show = false;
                el.style.display = "none";
                this.$emit("transitionend");
            }
        }
    }
    </script>
    
    <style scoped>
    .ball-wrap .ball{
        position: fixed;
        left: 50%;
        bottom: 10px;
        z-index: 100000;
        color: red;
        transition: all .5s cubic-bezier(0.49, -0.29, 0.75, 0.41);
    }
    .ball-wrap .ball .inner{
    	 16px;
        height: 16px;
        transition: all 0.5s linear;
        background: #f00;
        border-radius: 50%;
    }
    .ball-wrap .ball .inner .cubeic-add {
        font-size: 22px;
    }
    </style>
    
    // CartAnim 組件的使用
    // 1. 引入组件
    import CartAnim from '@/components/CartAnim.vue';
    // 2. 挂载到组件选项中
    components: {
        CartAnim
    }
    // 3. 在组件模板中 使用组件,并在商品列表组件上监听启动事件
    <cart-anim ref="ca"></cart-anim>
    <good-list @cartanim="$refs.ca.start($event)" />
    
    // 4. 在 good-list 组件中通过 $emit 派发自定义事件
    this.$emit('cartanim', event.target);
    

    全局创建组件实例函数

    import Vue from 'vue';
    
    export default function(Component, props) {
        // 创建vue实例
        const instance = new Vue({
            render: h => h(Component, { props });
        }).$mount();
        
        // 把生成的dom追加至body中
        document.body.appendChild(instance.$el);
        
        // 添加一个销毁方法
        const comp = instance.$children[0];
        comp.remove = function () {
            document.body.removeChild(instance.$el);
            instance.$destroy();
        }
        return comp;
    }
    
    // 在入口 main.js 中注入方法
    import create from './utils/create'
    Vue.prototype.$create = create;
    
    // 在组件中使用 $create 方法
    const anim = this.$create(CartAnim);
    anim.start(el);
    anim.$on("transitionend", anim.remove);
    
  • 相关阅读:
    ls 按大小排序 按时间排序
    【u035】奶牛的电信
    【record】#10
    【record】10.30..11.6
    【33.33%】【codeforces 608C】Chain Reaction
    【44.19%】【codeforces 608D】Zuma
    【22.73%】【codeforces 606D】Lazy Student
    【27.40%】【codeforces 599D】Spongebob and Squares
    【26.67%】【codeforces 596C】Wilbur and Points
    【13.91%】【codeforces 593D】Happy Tree Party
  • 原文地址:https://www.cnblogs.com/yuxi2018/p/11967313.html
Copyright © 2011-2022 走看看