vue 项目要点总结(二)

静态logo图片怎么引入

<div class="logo">
  <img src="../assets/logo.png"/>
</div>

clipboard.png

对重复元素的遍历

 productList:{
    pc:{
            title:"PC产品",
            list:[
              {title:"数据统计",url:"#",hot:false},
              {title:"数据预测",url:"#",hot:true},
              {title:"流量分析",url:"#",hot:false},
              {title:"广告发布",url:"#",hot:true}
            ]
        }
},

<dl class="first">
  <dt>{{productList.pc.title}}</dt>
  <dd v-for="item in productList.pc.list">
    <a :href="item.url">{{item.title}}</a>
    <span v-if="item.hot" class="hot">HOT</span>
  </dd>
</dl>
//在重复的部分用v-for

如果某个重复的部分比较分散;可用 <template v-for> </template> 循环,循环是从标签本身就开始的

<li v-for="item in news" :title="item.title"><a :href="item.url">{{item.title}}</a></li>

//li 既是 v-for 的载体, 也是item ;:title="item.title" 与v-for 同一个标签;

:class 的灵活使用

遍历的时候 class 可以接受 几种赋值方式;

//直接绑定item的属性
<li v-for="(item,index) in board" class="bot-item clearfix" :class="item.class">


//通过对象的方式配置
<li v-for="(item,index) in board" class="bot-item clearfix" :class="'red':index==0?true:false}">

//class 是 一个数组;第一项通过对象配置,第二项,利用item.id 拼成特有的字符串类
<li v-for="(item,index) in board" class="bot-item clearfix" 
:class="[{'red':index==0?true:false},'red'+item.id]">

img src属性 路径问题

静态src可以直接写成相对路径

<img src="../assets/icon/1.png"/>

动态src 推荐使用背景图代替;

<div :style="{backgroundImage: 'url(' + img + ')'}"></div>

如果动态src 要写成模板变量,要通过require 函数请求;这样webpack才能打包出正确的路径

<img :src="item.icon"/>

board:[
                {
                  "title":"开放产品",
                  "description":"开放产品是一款开放产品",
                  url:"#",
                  icon:require('../assets/icon/1.png'),
                  class:"mr15 mb15"
                }
    ]

icon:require('../assets/icon/1.png') //webpack 可以打包的路径

如果要通过ajax请求mock的的img 目前只找到此方法,把img 放在 static 文件下;写json的时候用绝对路径

slides=[{
  "src":"/static/slideShow/pic4.jpg",  //static 文件 与index.html 同级
  "title":"勇攀高峰",
  "href":"#"
}]


 <img v-if="isShow" :src="slides[nowIndex].src">

使用 vue-resource ajax 数据

安装

cnpm install vue-resource --save

引入

import resource from 'vue-resource'
Vue.use(resource)

使用

created(){ //创建应用开始的时候;
  this.$http.get('productList').then(function (data) {
    console.log(data);
  },function (err) {
    console.log(err)
  })
}

本地模拟数据 express

早期的vue-lic下面有dev-server.js和dev-client.js两文件,请求本地数据在dev-server.js里配置,在vue 2.0 中 最新的vue-webpack-template 中已经去掉了dev-server.js和dev-client.js 改用webpack.dev.conf.js代替

具体的配置代码参考这个文章

http://blog.csdn.net/u0122073...

ajax 数据回来后怎么处理

export default {
        data: function () {
            return {
               //json数据申请回来之前,模板中其实已经用到了数据结构,
               //所以,在还没有数据的时候,你就需要先写出数据结构;否则会报错 typeErr
              productList:{
                    pc:{
                        title:"",  //先定好的数据结构;
                        list:[]     //因为数据中是重复的部分,可以不定义
                    },
                    app:{
                      title:"",
                      list:[]
                    }
                },
              news:[],
              board:[]
            }
        },
      created (){
          //通过 => 函数,延续this的引入;否者 then() 中的this 并不是指向 实例的this;
          this.$http.get('/api/productList').then((res)=> {
          //模拟回来的数据,要看准res的结构;确保读到数据,并复制给this.data;
            this.productList = res.data.data;      
          },(err)=> {
            console.log(err)
          })
          this.$http.get('/api/news').then( (res)=> {
            this.news = res.data.data;
          }, (err) => {
            console.log(err)
          })
          this.$http.get('/api/board').then((res)=> {
            this.board = res.data.data;
          },(err)=> {
            console.log(err)
          })
        },
    }

写一个幻灯片组件

完整的代码是:

父组件

<div class="slide">
    //传入参数 ,绑定自定义事件
   <slide :slides="slides" :time="2000" @onchange="slideChange"></slide>
</div>

//把资源申请回来

 methods:{
        slideChange(index){
            console.log(index)
        }
      },
 created (){
    this.$http.get('/api/slides').then((res)=> {
        this.slides = res.data.data;
      },(err)=> {
        console.log(err)
      })
}

幻灯片组件完整代码

<template>
    <div @mouseover="stopEvnet" @mouseout="runEvent">
      <div class="slide-box">
         <div class="img-list clearfix">
            <a :href="slides[imgIndex].href">
              <transition name="slide-trans">
                <img v-if="isShow" :src="slides[imgIndex].src">
              </transition>
              <transition name="slide-trans-old">
                <img v-if="!isShow" :src="slides[imgIndex].src">
              </transition>
            </a>
         </div>
        <div class="tools">
          <div class="li-tools">
            <div class="left" @click="goto(toLeft)"> < </div>
            <ul>
              <li v-for="(item,index) in slides" :class="{'on':index==imgIndex}" @click="goto(index)">{{index+1}}</li>
            </ul>
            <div class="right" @click="goto(toRight)"> > </div>
          </div>
        </div>
        <p class="img-title">{{slides[imgIndex].title}}</p>
      </div>
    </div>
</template>
<script>
    export default {
        data: function () {
            return {
              imgIndex:2,
              timeEv:null,
              isShow:false
            }
        },
        props:{
          slides:{
            type:Array,
            default:[]
          },
          time:{
            type:Number,
            default:1000
          }
        },
        computed:{
          toRight(){
            let a = this.imgIndex+1;
            if(a>3){
              a = 0
            }
            return a
          },
          toLeft(){
            let b = this.imgIndex-1;
            if(b<0){
              b = 3
            }
            return b
          }
        },
        methods:{
          goto (index) {
            this.isShow = false
            setTimeout(() => {
              this.isShow = true
              this.imgIndex = index
              this.$emit('onchange',index)
            }, 10)
          },
          stopEvnet(){
              clearInterval(this.timeEv)
          },
          runEvent(){
            this.timeEv = setInterval(()=> {
              this.goto(this.toRight)
            },this.time);
          }
        },
        mounted(){
          this.runEvent();
        }
    }
</script>
<style scoped>

.slide-trans-enter-active {
  transition: all .5s;
}
.slide-trans-enter {
  transform: translateX(730px);
}
.slide-trans-old-leave-active {
  transition: all .5s;
}
.slide-trans-old-leave-to{
  transform: translateX(-730px);
}

  .slide-box{
    width: 730px;
    height: 436px;
    position: relative;
    overflow: hidden;
  }
  .img-list{
    min-height: 436px;
  }
  .img-list a{
    height: 100%;
  }
  .img-list img{
    width: 730px;
    height: 436px;
    position: absolute;
  }
  .tools{
    width: 100%;
    height: 50px;
    background-color: #000;
    opacity: 0.5;
    position: absolute;
    bottom:0px;
    left: 0;
  }
  .img-title{
    position: absolute;
    bottom:15px;
    left: 10px;
    z-index: 10;
    color: #fff;
  }
  .li-tools{
    position: absolute;
    bottom:12px;
    right: 10px;
  }
  .left,.right,li,ul{
    display: inline-block;
    padding:2px 5px;
    color: #fff;
    cursor: pointer;
    margin:0 5px;
    border-radius: 5px;
  }
  li.on{
    background-color: #12b7f5;
  }
</style>

需要注意的地方有几个
  • 确保ajax 数据回来后才做渲染

console 出现这种报错,但是模板渲染正常,一切正常

clipboard.png

原因就是,ajax 请求的数据还没回到,模板已经开始渲染,所以读不到这个href属性;
处理办法 是加个判断;等数据存在后,再去读值

clipboard.png

  • 清楚触发定时器的 vue钩子;
//鼠标进入时
@mouseover="stopEvnet" 

//鼠标出去时
@mouseout="runEvent"
  • 只用了一次for 循环;区别于与 jq幻灯片的写法

jq的幻灯片 可能我们习惯把 所有图片都先遍历出来,然后 写js 让img-box 滚动;

看vue代码,发现只用了在li 的一次for循环;全部数据 全部依赖于一个变量 imgIndex 读取;改变imgIndex的值,其它数据自动转换;

这是利用了vue的双向绑定机制;只需要更换 index 就会自动 读取出对应的src,达到换图片的目的;

注意for循环以为,读取数据的写法

<a :href="slides[imgIndex].href">

<img :src="slides[imgIndex].src">

<p class="img-title">{{slides[imgIndex].title}}</p>
  • 只写了一个goto 方法实现 点击切换,左右切换

goto 的功能功能,就是点击哪个li,切换到哪个数据;

利用 vue的 计算属性功能:监听一个值,返回一个处理后的值; 监听left 的click 事件;goto到一个 toLeft 的计算值; 实现优雅的切换;

因为 计算属性toRight 可以当做一个数值来使用;所以,计时器切换的时候,模拟点击 right 可以写成

this.timeEv = setInterval(()=> {
  this.goto(this.toRight) //    this.toRight 得到当前img的下一个数据的index
},this.time);
  • 切换动画的实现(有点抽象)

让两个相同的图片互斥显示;

slide-trans 负责进入的动画; slide-trans-old 负责移出的动画

 <transition name="slide-trans">
    <img v-if="isShow" :src="slides[imgIndex].src">
  </transition>
  <transition name="slide-trans-old">
    <img v-if="!isShow" :src="slides[imgIndex].src">
  </transition>

初始化的时候,让 isShow = false;就是说,让负责移出的动画的img 先渲染;

goto 的时候,先让 isShow = false 移出动画会被执行,这时的index是当前的图片index;意思是,让当前显示的img执行 移出动画

然后延迟 500毫秒,让isShow = true,移入动画会被执行,这时的index已经改变为 goto 参数的index,意思就是将要跳转到的图片的index,所以,其实就是让 要显示的图片 执行移入动画;

goto (index) {
    this.isShow = false
    setTimeout(() => {
      this.isShow = true
      this.imgIndex = index
    }, 500)
  },
  • 切换动画的写法

动画的过程有几个阶段:

v-enter(进入动作初始状态),
v-enter-active(进入动作到完成进入动作的中间过程)
v-enter-to(进入动作结束的状态)
v-leave(离开动作初始状态),
v-leave-active(离开动作到完成离开动作的中间过程)
v-leave-to(离开动作结束的状态)

参考:https://vuefe.cn/v2/guide/tra...

//slide-trans 动画的 进入动作 到 完成进入动作 的 中间过程,所有动画时间为0.5秒
.slide-trans-enter-active {
  transition: all .5s;
}
// 进入动作初始状态 translateX(730px)
.slide-trans-enter {
  transform: translateX(730px);
}

//slide-trans-old动画 离开动作 到 完成离开动作 的中间过程,所有动画时间为0.5秒,
// transform: translateX(-730px)为什么写在这里?待了解
.slide-trans-old-leave-active {
  transition: all .5s;
  transform: translateX(-730px);
}

直观上 enter动画 和 leave 动画是一个相反的过程,所以也可以写成;效果一样;

.slide-trans-old-leave-active {
  transition: all .5s;
}
.slide-trans-old-leave-to{
  transform: translateX(-730px);
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值