Vue项目小应用

Vue—ref链在项目中的应用(1)

在移动端app项目当中,我们经常遇到的一个场景是:点击每一个不同的模块,进入到一个大致相同的详情页,然后里面会有不同的一大堆折叠起来的文字描述,我们可以点击一个向下的箭头,就可以进行将折叠文字显示出来,下面来介绍一下如何通过vue的ref链以及css3来完成我们的上述场景

  • 我们在这里拿两段数据来作比较
    • "1937年淞沪会战末期,国民革命军第88师524团留守上海四行仓库,与租界一河之隔,孤军奋战4昼夜,造就了罕见的被围观的战争;为壮声势,四百人对外号称八百人。 电影《八佰》由管虎导演,是亚洲首部全片使用IMAX摄影机拍摄的商业影片,将于2019年7月5日全国上映。"
    • "哈利波特是一个孤儿,从小寄养在姨妈家,受尽欺凌。但就在哈利11岁生日的时候,他意外收到了霍格沃茨学院的入学通知书。哈利从该学院派来接他的巨人海格口中得知,这是一间魔法学院,并得知了自己的身世,原来哈利的父母都是伟大的魔法师,在对付伏地魔的战斗中双双献身,唯有哈利幸免于难。哈利进入霍格沃茨后,表现出了超乎想象的飞行天赋,得到麦格教授的推荐进入了格兰芬多的魁地奇球队。另一方面,哈利发现霍格沃茨学院内有一股黑暗势力似乎在暗暗滋长,揭开谜团的关键就在有凶恶的三头犬守护的房间内。哈利、罗恩和赫敏三个好朋友决定探个究竟。"

以上是我们场景当中遇到的需要折叠的数据

由场景所知,我们可以通过包裹一个div标签,然后动态的更改div标签中的内容,来完成一个点击不同的模块显示对应的内容的操作

首先进行new实例

new Vue({
  el:'#app',
  data: {
    //用来存放待会获取到的值
    filmInfo: null,
    //控制高度类名是否显示
    mark1: true,
    mark2: true
  }
})

vue实例创建完成后,可以在生命周期树的created钩子函数中进行一个异步请求数据,在这里我们通过axios的方式来进行

created () {
    axios.get(`接口`, {
      headers: {
				//处理请求头,防止跨域
      }
    }).then(res => {、
    	//假设res上有个放有我们一开始所描述数据的对象film
      this.filmInfo = res.film
    })

此时进行对div标签的内容填写

<!--假设a,b是对象的键-->
<div>{{filmInfo.a}}</div>
<div>{{filmInfo.b}}</div>

此时,一个页面结构我们就写好了

下面我们就可以通过css3来实现动态展开的效果了

可以给div增加内联样式

<div @click="mark1=!mark1" style="height:1rem; transition: height .5s ease; overflow: hidden;" :class="mark1 ? 'introduce' : ''">{{filmInfo.a}}</div>
<div @click="mark2=!mark2" style="height:1rem; transition: height .5s ease; overflow: hidden;" :class="mark2 ? 'introduce' : ''">{{filmInfo.b}}</div>

通过vue加一个动态类名

.introduce {
  height: .38rem !important;
}

原理就是通过div标签上的click事件,来更改mark的值为true还是false,再通过v-bind绑定在class上来进行我们的introduce类名是否添加在标签上,这样就可以通过!important权重最高的属性来更改内联的高度,最后通过transition来完成我们的一个动态展开的结果。

此时呢,我们就发现了一个很大的bug,就是文本内容是可能不一样长的,这也就导致,我们把高度写死的话,内容多的会显示不全,直接影响了用户的体验。

有多种方法,我在这里分享的是通过ref链来解决这个问题。

直接绑顶一个p标签来包裹我们要写入的内容,然后填入div中,这时,即便我们给外盒子div添加一个overflow:hidden的属性,它里面p标签被内容撑开的高度是不会变的,所以我们可以通过这一特性,来获取到p标签的高度后,再进行一个高度回填,来完成动态展开折叠的这样一个操作。

并且给p标签设置一个ref = 'text',下面只展示第二段比较长的数据来进行演示

<div @click="mark2=!mark2" style="height:1rem; transition: height .5s ease; overflow: hidden;" :class="mark2 ? 'introduce' : ''"><p ref='text'>{{filmInfo.b}}</p></div>

此时便可以在updated钩子函数中来进行ref链操作获取p标签的一个高度值,也可以在请求数据的后面通过this.$nextTick来实现

updated () {
  this.textHeight = this.$refs.text.offsetHeight + 'px'
}

然后我们把数据进行一个回填,更改行内的固定写死的height值

<div class="text" @click="mark2=!mark2" :style="{height:textHeight}" :class="mark2 ? 'introduce' : ''"><p ref='text'>{{filmInfo.b}}</p></div>

另外我们在项目中写到的css样式是非常多的,所以将部分拿到外部

.text{
  transition: height .5s ease; overflow: hidden;
}

此时,我们一个通过vue的ref链和css3属性完成的动态展开数据就完成了。

<!DOCTYPE html>
<html lang="en" style="font-size:100px">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
    <!--引入vue.js 渐进式js框架-->
    <script src="./base/vue.js"></script>
    <style>
      body{
        font-size:14px; 
        font-family:"微软雅黑"; 
        color:#666; 
      }
      *{margin: 0;padding: 0;}
      .introduce {
        height: .38rem !important;
      }
      .text{
        transition: height .5s ease; overflow: hidden;
      }
    </style>
</head>
<body>
    
    <div id="app">
      <!-- <div @click="mark1=!mark1" style="height:1rem; transition: height .5s ease; overflow: hidden;" :class="mark1 ? 'introduce' : ''">{{filmInfo.a}}</div>
      <div @click="mark2=!mark2" style="height:1rem; transition: height .5s ease; overflow: hidden;" :class="mark2 ? 'introduce' : ''">{{filmInfo.b}}</div> -->
      <div @click="mark1=!mark1" style="height:1rem; transition: height .5s ease; overflow: hidden;" :class="mark1 ? 'introduce' : ''"><p>{{filmInfo.a}}</p></div>
      <div class="text" @click="mark2=!mark2" :style="{height:textHeight}" :class="mark2 ? 'introduce' : ''"><p ref='text'>{{filmInfo.b}}</p></div>
    </div>
    <script>
        new Vue({
          el: "#app",
          data: {
            textHeight: 0,
            mark1: true,
            mark2: true,
            filmInfo: {
              a:"1937年淞沪会战末期,国民革命军第88师524团留守上海四行仓库,与租界一河之隔,孤军奋战4昼夜,造就了罕见的被围观的战争;为壮声势,四百人对外号称八百人。 电影《八佰》由管虎导演,是亚洲首部全片使用IMAX摄影机拍摄的商业影片,将于2019年7月5日全国上映。",
              b:"哈利波特是一个孤儿,从小寄养在姨妈家,受尽欺凌。但就在哈利11岁生日的时候,他意外收到了霍格沃茨学院的入学通知书。哈利从该学院派来接他的巨人海格口中得知,这是一间魔法学院,并得知了自己的身世,原来哈利的父母都是伟大的魔法师,在对付伏地魔的战斗中双双献身,唯有哈利幸免于难。哈利进入霍格沃茨后,表现出了超乎想象的飞行天赋,得到麦格教授的推荐进入了格兰芬多的魁地奇球队。另一方面,哈利发现霍格沃茨学院内有一股黑暗势力似乎在暗暗滋长,揭开谜团的关键就在有凶恶的三头犬守护的房间内。哈利、罗恩和赫敏三个好朋友决定探个究竟。"
            }
          },
          updated () {
            this.textHeight = this.$refs.text.offsetHeight + 'px'
          }
        })

    </script>
</body>
</html>

以上就是对vue——ref链在项目中的一个小应用,若有出入,欢迎指出,立刻改正。

posted on 2020-08-22 16:07  Huskie!  阅读(178)  评论(0编辑  收藏  举报