vue08----Singer.vue跳转至Detail.vue、阿里巴巴矢量图标、base64、songList中的ul向上滚动时特效、过渡标签transition、animate.css、vuex、vuex的使用流程、修改vuex中的值、actions处理异步。getters派生属性

### Singer.vue跳转至Detail.vue

    将Fsinger_mid参数(002J4UUk29y8BY)传过去:
    @click="goDetail(info.Fsinger_mid)"

### 使用阿里巴巴矢量图标库,返回箭头(Detail.vue)

    1、先登录iconfont官网,下载需要的字体图标
    2、将font文件夹中的所有文件拷贝,在项目src文件夹下新建font文件夹,粘贴。其中,如果要使用Unicode方式,只需要拷贝 iconfont.eot、iconfont.svg、iconfont.ttf、iconfont.woff、iconfont.woff2这5个文件,如果要使用Font class方式,只需要将 iconfont.css文件拷贝。
    3、两种引用方式:Unicode和Font class
        (1)Unicode方式(IE6+):
            ①在reset.less中声明样式:
                @font-face {
                    font-family: 'iconfont';
                    src: url('../font/iconfont.eot');
                    src: url('../font/iconfont.eot?#iefix') format('embedded-opentype'),
                    url('../font/iconfont.woff2') format('woff2'),
                    url('../font/iconfont.woff') format('woff'),
                    url('../font/iconfont.ttf') format('truetype'),
                    url('../font/iconfont.svg#iconfont') format('svg');
                }


                .iconfont {
                    font-family: "iconfont" !important;
                    font-size: 36px;
                    font-style: normal;
                    -webkit-font-smoothing: antialiased;
                    -moz-osx-font-smoothing: grayscale;
                }
            注意:font文件夹的路径注意不要写错了
            ②Detail.vue中,声明 class="iconfont" ,并在标签内部写入  编码:
         <span @click="back" class="iconfont"> &#xe61b; </span>
        
  (2)Font class方式(IE8+、语义化):
            ①Detail.vue中引入css文件:
        @import "../font/iconfont.css";
            ②Detail.vue中,声明 class="iconfont" ,并添加该字体图标的类名:
        <span @click="back" class="iconfont icon-back"></span>
    4、优化:起别名
        ①vue.config.js中:
.set("font",resolve("./src/font"))
            注意:修改完要重启
        ②此时, ../font 可以写成 ~font
    5、如果要替换该字体图标
        先将选好的字体图标购物车下载,再将其中的font文件夹中所有内容替换掉src下font中的所有内容,再写对应的类名或图标编码。

### base64压缩图片(Detail.vue)

    (1)引入public中的图片(绝对路径)
     <img src="/arrow.png">
    (2)引入asset中的图片(相对路径)
    <img src="../assets/arrow.png">
        此时图片的路径就变成base64
    vue中引入图片的两种方式:
        1、路径引入,绝对路径和相对路径都可以
        2、变量引入,绝对路径可以,相对路径需要用import引入才能使用:
            import img from "../assets/arrow.png";// vue脚手架中可以用import引入任何模块
            data(){
                return{
                    img:img
                }
            }


            <img :src="img">
    场景:20-30K的图片打成base64的,可以减少http的请求,但是会增大包的体积。base将图片打成一段字符串,浏览器可以根据字符串解析成图片。



### Detail.vue背景图片显示

    <div class="img" :style="bgStyle">


    </div>
    computed: {
        bgStyle(){
            let id=this.$route.params.id;
            return `background-image: url("https://y.gtimg.cn/music/photo_new/T001R300x300M000${id}.jpg?max_age=2592000");`;
        }
    },

### songList中的ul向上滚动时特效(Detail.vue)

    效果:songList向上滚动时,可以一直向上到超出header隐藏。
    思路:给songList实例化,它下面的容器ul设置背景色,这样就可以向上滚动了,在滚动的同时,让 .img 的高度随之减小。边界判断:到 .img 剩余40px时,让 .img 的高度恒等于40,并提高 .header 的层级。
    代码:
        initBS(){
            this.BS = new BS(this.$refs.songWrapper,{
                probeType:3,// 在屏幕滑动和momentum 滚动动画运行过程中实时的派发 scroll 事件
                click:true
            });
            let img=this.$refs.img;
            let imgHeight=img.clientHeight;
            this.BS.on("scroll",(obj)=>{
                img.style.height=(imgHeight+obj.y)+"px";
                // 判断到达距离顶部40px
                if(img.clientHeight<=40){
                    img.style.height=40+"px";
                    img.style.zIndex=3;
                    this.$refs.songWrapper.style.zIndex=2;
                    this.$refs.play.style.opacity=0;
                }else{
                    img.style.zIndex=2;
                    this.$refs.songWrapper.style.zIndex=3;
                    this.$refs.play.style.opacity=1;
                }
                if(img.clientHeight>=262){
                    this.$refs.songWrapper.style.zIndex=10;
                }
            });
        },
    效果:songList向下滚动时,放大 .img 的背景图和播放按钮
    思路:y轴向下是正方向,大于0时,给 .img 的尺寸进行放大,比例为percentage。scale的缩放中心默认是center,这里以top方向为中心点放大。
    代码:
        if(obj.y>0){
            let percentage=1+(obj.y/imgHeight);
            img.style.transform=`scale(${percentage})`;
            img.style.transformOrigin="top";
        }

### 过渡标签 transition(transitionBox.vue)

    场景:使一个标签淡入淡出
    步骤:
        ①用transition标签将需要动画的标签包裹起来,设置name属性,比如 name="fade"
            <transition name="fade">
                <div class="div" v-if="state">


                </div>
            </transition>
        ②用fade相关的6个类名设置动画
            .fade-enter{
                opacity: 0;
            }
            .fade-enter-active{
                transition: opacity 2s;
            }
            .fade-enter-to{
                opacity: 1;
            }
            .fade-leave{
                opacity: 1;
            }
            .fade-leave-active{
                transition: opacity 2s;
            }
            .fade-leave-to{
                opacity: 0;
            }
        注意:如果transition标签中不是一个元素,要使用transition-group标签,并且给该标签中的元素设置key属性,设置不同的值:
            <transition-group name="fade">
                <div key="1" class="div" v-if="state">


                </div>
                <p key="2" v-if="state">P元素</p>
            </transition-group>

### 过渡标签 transition结合Animate.css使用(transitionBox.vue)

    ①在asset文件夹中放入animate.min.css文件
    ②引入animate.min.css:@import "../../assets/animate.min.css";
    ③使用:在transition标签中添加enter-active-class和leave-active-class属性
        <transition enter-active-class="animated lightSpeedIn" leave-active-class="animated lightSpeedOut">
            <div class="div" v-if="state">


            </div>
        </transition>
    注意:
        1、enter-active-class和leave-active-class属性的第一个值是固定的animated,第二个值是需要的动画名称(淡入淡出用fadeIn和fadeOut,右边划入划出用slideInRight和slideOutRight)
        2、此时可以不写name属性,name属性是需要自定义动画的时候用的

### Singer组件进入Detail组件的右滑动画(Singer.vue)

    ①引入animate.min.css:
      @import "../assets/animate.min.css";
    ②用transition标签将Detail组件(<router-view></router-view>)包裹:
        <transition enter-active-class="animated slideInRight" leave-active-class="animated slideOutRight">
            <router-view></router-view>
        </transition>
    如果想要设置动画时间,在animate.min.css中搜索animated,设置动画时间。
    如果不想引入animate.min.css文件:(节约空间)
        ①transition标签中设置name属性:
            <transition name="slide">
                <router-view></router-view>
            </transition>
        ②样式:
            .slide-enter{
                transform: translate(100vw);
            }
            .slide-enter-active{
                transition: transform 0.5s;
            }
            .slide-enter-to{
                transform: translate(0);
            }
            .slide-leave{
                transform: translate(0);
            }
            .slide-leave-active{
                transition: transform 0.5s;
            }
            .slide-leave-to{
                transform: translate(100vw);
            }

### vuex

    特点:
        1、多组件共享状态(有一个变量,在所有组件都可以使用)
        2、一个组件发生改变,其他组件自动变
    核心:
        1、state:全局状态(全局变量,state中的数据在所有的组件都可以使用)
        2、mutations(突变):一个对象,有一堆方法,vuex规定修改state中的值必须使用mutations中的方法
        3、commit(犯罪):触发mutations中的值必须使用commit方法(this.$store.commit("addAge");)
            例:
    commit("changeName",{name:"二狗子"});
                  changeName----需要触发的mutations中的函数名
                  {name:"二狗子"}----传递过去的参数对象
        4、actions(行动):在这里执行commit()
            changeNameAction(obj,params){
                setTimeout(()=>{
                    let name=params.name;
                    let {commit}=obj;
                    commit("changeName",{name:name});
                },500);
            }
            通过dispatch()触发actions中的方法:
            this.$store.dispatch("changeNameAction",{name:"二狗子"});
        5、getters:派生属性,vuex中的计算属性,相当于data的computed
    流程:在state中定义数据,修改时先在mutations中定义修改的方法,这个方法通过commit()触发,如果是同步改,直接用this.$store.commit();如果是异步,则将commit()放在actions中执行,actions通过this.$store.dispatch()触发。
    场景:
        数据有其他组件复用
        需要跨多级组件传递数据
        需要持续化的数据

### vuex的使用流程(demo/vuex)

    ①下载vuex插件:npm run vuex
    ②在vuex文件夹下新建store/store.js:
        import Vue from "vue";
        import Vuex from "vuex";
        Vue.use(Vuex);

        const store=new Vuex.Store({
            state:{
                name:"孙艺珍",
                age:30
            }
        });

        export default store;
    ③入口文件(main.js)中引入vuex:
        import store from "./demo/vuex/store/store.js";

        new Vue({
            store,
            ...
        })
    ④在vue组件中打印:
        mounted(){
            console.log(this.$store)
        }

### 修改vuex中的值(demo/vuex)

    ①如果要修改vuex中的值,必须要通过mutations(突变)中的方法:(store.js中vuex的配置项)
        mutations:{
            changeName(state){
                state.name="吴启浪";
            }
        },
    ②mutations中的方法由commit(犯罪)触发:(组件中)
        methods: {
            changeName(){
                this.$store.commit("changeName");
            }
        },

###### 如果要给mutations中方法传参:

    在调用commit方法时,第一个参数是触发的函数名称,第二个参数是一个对象:
        this.$store.commit("changeName",{name:"二狗子"});
    在mutations中方法中接收这个参数,第一个参数是state,第二个参数是params(commit传来的第二个参数):
        changeName(state,params){
            state.name=params.name;
        },

### actions中处理异步的方法,通过dispatch()触发

    场景:如果有异步请求,这个异步请求放在组件中处理,那么每个组件都要写一次,最好是放在actions中处理
    store.js:
        actions:{
            changeNameAction(obj,params){
                setTimeout(()=>{
                    let name=params.name;
                    let {commit}=obj;
                    commit("changeName",{name:name});
                },500);
            }
        }
    demo3.vue:
        this.$store.dispatch("changeNameAction",{name:"二狗子"});

### getters 派生属性,vuex中的计算属性,相当于data的computed

    声明:
        getters: {
            doubleAge(state){
                return state.age*2;
            }
        },
    调用:
        {{this.$store.getters.doubleAge}}
    注意:
        getters中函数和computed中函数特点一样:声明的函数必须要用return返回出去,在调用的时候不加(),当state中的值发生改变时调用。
 

猜你喜欢

转载自www.cnblogs.com/wuqilang/p/12290858.html