谈论一下vue的ref是个什么东西,然后再做一个让图片跟着鼠标动的玩具。

海星吧 2019-9-19 4139


我吉良吉影只想过平静的生活。


ok,今天突然想起了一个很奇妙的东西,以前一直没搞明白的,vue的ref和$refs。

话说年初的时候我对js,vue这一类的东西完全没有概念,当时就是死学硬背,铁着头皮敲代码。

连原生js都没怎么学,就直接学vue框架了。

成效低的很。。

在那个时候看过这个ref和$refs。之前那个先辈还在这个公司的时候他就告诉我这个是操作dom的,也就是操作对象的。

当时没这个概念,所以没搞懂,然后就没管这个东西了。


今天我在做一个图片跟随鼠标移动的demo的时候,发现我无论怎么样给放大图片的div设置值,

他都会报错,但是按道理应该是行得通的。或许是因为我dom操作有问题?


于是我就想起以前一直没搞懂的ref这个操作dom的api。

现在再来看,发现其实就跟原生js的document.getElementById 这一类选择器是一样一样的。

推荐讲解的博客:

https://www.cnblogs.com/xumqfaith/p/7743387.html

https://www.cnblogs.com/xuqp/p/9524342.html

这个讲的很详细。


下面是我的demo


1.jpg

2.png

我给这个‘点击偶’的button添加了一个点击事件。让他输出this.$refs

 clickedButton: function () {

            console.log(this.$refs)

     },

然后他就打印出我在组件中注册的  ref。

可以看到他其实是把ref注册到了一个对象里,上面还有他的标签类型,ID和Class。

不过我在button上写上style,在input上写上了value这样的属性,但是他没有显示出来,或许是只会给出id和class

3.png


以上,给标签加上个ref 这样的属性,然后设置一个名字,这个名字是自己决定的,你可以给他设置为标签的id。

然后  在这个组件里 this.$refs.myButton就相当于 document.getElementById('myButton')这样子的感觉。

而且不用每个函数都写上声明,只需要使用$refs 就可以了(其实感觉也差不多,不过说是可以减少dom的消耗)



好了,接下来看怎么使用ref来写这个demo玩具了

其实很简单。


<template>

  <div>

    <ul>

    <!-- 在列表中的img里设置 移入移出的事件 -->

      <li v-for="(it,index) in imgarray"

      ><img :src="it.img" alt=""

        @mousemove="showBigPic(it.img)" @mouseout="closeimg()"

      ></li>

      <li ref='bigpicview' v-show="imgBigis">

        <!-- v-show="imgBigis" 显示或隐藏 -->

        <img src="" id="bigPic" alt="" ref="bigPic">

        <!-- bigPic 这个是放大图 -->

      </li>

    </ul>

 <h1>{{ message }}</h1>

    <button ref="myButton" style="width: 150px;" @click="clickedButton">点击偶</button>

    <input type="text" value="123456789" ref='input'>

    <div class="bbg a b c " @click="bbgClick()" id="bbg" ref="bbg"

    >点我一下</div>


  </div>

</template>


<script>

export default{

  data(){

    return{

      imgarray:[

        {img:require("../../../assets/img/6.jpg")},

        {img:require("../../../assets/img/5.jpg")},

        {img:require("../../../assets/img/12.jpg")},

      ],

      imgBigis:false,//通过控制器,让bigpicview这个标签显示或隐藏

      message: '嘞洛嘞洛嘞洛,樱桃真好吃',

    }

  },

  mounted(){

    // this.showBigPic()

  },

  methods: {

     clickedButton: function () {

            console.log(this.$refs)

     },

    bbgClick(){

      this.$refs.bbg.style.left = 20+'px'

      console.log(this.$refs.bbg.style.left)

      console.log(this.$refs.bigPic)

    },

    showBigPic(file ,e) {//通过参数把图片路径存入    file,第二个参数  e 是window对象

      this.imgBigis = true    //让图片显示出来

      var e = e || window.event // console.log(e,'这个是window对象,event')

//       document.getElementById("bigPic").src=file;

//  var div = document.getElementsByClassName('bigpicview')

      var bigPic = this.$refs.bigPic

      bigPic.src=file  //鼠标移入那个图片,就会把图片的路径设置到这个放大图片标签的路径里

      var bigpicview = this.$refs.bigpicview

       var intX = e.clientX;  //获得window的鼠标的坐标

       var intY = e.clientY;

       bigpicview.style.left = intX+ 5 + 'px';  

       bigpicview.style.top = intY + 5 + 'px';

//让绝对定位的图片的坐标变成鼠标的坐标,不过由于会卡住,不能往下走,

//所以我让它的坐标加了5px,这样就不会卡死了。如果不信可以自己试试去掉这个5px,看看会怎么样。


//     document.getElementsByClassName('bigpicview').style.left = intX+'px'

//     document.getElementsByClassName('bigpicview').style.top = intY+'px'

    },

    closeimg(){  //鼠标移出时关闭大图。

      this.imgBigis=false

    },

  },

}

</script>


<style scoped="scoped">

.follow_img_body{

  .imgUl{

    display: flex;

    .imgLi{

      .img{

        width: 200px;

      }

    }

    .bigpicview{

      position: absolute;/*这个一定要设置*/

      left: 800px;

      #bigPic{

        width: 400px;

      }

    }

  }

}

</style>


5.jpg


我们通过获取到window.event的clientX和clientY这两个鼠标在窗口的坐标,然后通过ref操作图片的dom,

用函数的参数showBigPic(it.img)把当前图片的路径设置到bigPic,这个时候,鼠标移入到那个图片里,bigPic的图片就是哪一张。

然后把坐标设置给已经绝对定位了的bigpicview,他就可以跟着鼠标动了。



好了 ,我在鼠标移入事件里加了一个↓ ,用来输出,让你们看到放大图的坐标

console.log(bigpicview.style.left,bigpicview.style.top)


可以看到他的坐标是跟着我的鼠标变化的(截图的时候鼠标不会出来。)

而且由于我留了个心眼,给他的坐标加了5px,所以就不会卡住了。


敲代码就像玩mc一样,慢慢堆出建筑的感觉挺不错的。

你说mc 是什么? 就是那个让牛顿气的跳出来把棺材板都扔到太空中某位停止思考的完美生物大人的脑门上的游戏。


Welcome to  Starfish bar,If you have better suggestions or better ideas,

Thank you forleave a message below, see you again.



弱鸡程序员年底还在加班
最新回复 (2)
  • 欧派兽 2019-9-19
    0 2
    奖励三级精华
    1:管理员给你移区后会显示移到了你之前发帖的区。 2:点击我作为楼主发帖时一楼下的图片签名,可以跳转到站规教程贴。 3:多次水贴水回复会封号哦? 4:不知道回什么的时候就点“里世界专属”,一键随机生成几种回复内容。 5:祝你在里世界玩得愉快!
  • 海星吧 2019-9-19
    0 3
    欧派兽 奖励三级精华
    阿麗亞朵undefined,阿勒,這個表情標籤沒有誒。。
    弱鸡程序员年底还在加班
    • ACG里世界
      4
          
返回
发新帖