2.2Vue2的模板语法

2.1.1、插值语法

1、代码示例
  <body>
    <!-- 准备容器 -->
    <div id="app">
      <!-- 在data中声明的 -->
      <!--1、 data中声明的变量 -->
      <h1>{{msg}}</h1>
      <h1>{{sayHello()}}</h1>
      <!-- 不在data中的变量不可以 -->
      <!-- <h1>{{i}}</h1> -->
      <!-- <h1>{{sum()}}</h1> -->

      <!-- 2、常量 -->
      <h1>{{100}}</h1>
      <h1>{{'hello vue!'}}</h1>
      <h1>{{3.14}}</h1>

      <!--3、 javascript表达式 -->
      <h1>{{1 + 1}}</h1>
      <h1>{{msg + 1}}</h1>
      <h1>{{'msg' + 1}}</h1>
      <h1>{{gender ? '男' : '女'}}</h1>
      <h1>{{number + 1}}</h1>
      <h1>{{msg.split('').reverse().join('')}}</h1>

      <!-- 错误的:不是表达式,这是语句。 -->
      <!-- <h1>{{var i = 100}}</h1> -->

      <!-- 4、在白名单里面的 -->
      <h1>{{Date}}</h1>
      <h1>{{Date.now()}}</h1>
      <h1>{{Math}}</h1>
      <h1>{{Math.ceil(3.14)}}</h1>
    </div>

    <!-- vue程序 -->
    <script>
      // 用户自定义的一个全局变量
      var i = 100;
      // 用户自定义的一个全局函数
      function sum() {
        console.log("sum.....");
      }

      new Vue({
        el: "#app",
        data: {
          number: 1,
          gender: true,
          msg: "abcdef", // msg是在data中声明的变量
          sayHello: function () {
            console.log("hello vue!");
          },
        },
      });
    </script>
  </body>
2、代码总结

      {{可以写什么}}

  1. data中声明的变量,函数,数组,等都可以
  2. 常量
  3. 只要是合法的javascript表达式都可以,注意js语句不行,赋值语句,if,for等
  4. 模版表达式都被放在沙盒中,只能访问全局变量的一个白名单

         如:Math和Date

        'Infinity,undefined,NaN,isFinite,isNaN,'

        'parseFloat,parseInt,decodeURI,decodeURIComponent,encodeURI,encodeURIComponent,'

        'Math,Number,Date,Array,Object,Boolean,String,RegExp,Map,Set,JSON,Intl,'

        'require'

2.1.2、指令语法

1. 什么是指令?有什么作用?

    指令的职责是,当表达式的值改变时,将其产生的连带影响,响应式地作用于 DOM

2. Vue框架中的所有指令的名字都以“v-”开始。

3. 插值是写在标签体当中的,那么指令写在哪里呢?

Vue框架中所有的指令都是以HTML标签的属性形式存在的,

例如:<span 指令是写在这里的>{{这里是插值语法的位置}}</span>

注意:虽然指令是写在标签的属性位置上,但是这个指令浏览器是无法直接看懂的。是需要先让Vue框架进行编译的,编译之后的内容浏览器是可以看懂的。

4. 指令的语法规则:

完整的语法格式:

<HTML标签 v-指令名:参数="javascript表达式"></HTML标签>

javascript表达式:

之前在插值语法中{{这里可以写什么}},那么指令中的表达式就可以写什么,当然{{}}不需要写

不是所有的指令都有参数和表达式:

有的指令,不需要参数,也不需要表达式,例如:v-once

有的指令,不需要参数,但是需要表达式,例如:v-if="表达式"

有的指令,既需要参数,又需要表达式,例如:v-bind:参数="表达式"

5. v-once 指令

作用:只渲染元素一次。随后的重新渲染,元素及其所有的子节点将被视为静态内容并跳过。这可以用于优化更新性能。

6. v-if="表达式" 指令

作用:表达式的执行结果需要是一个布尔类型的数据:true或者false

true:这个指令所在的标签,会被渲染到浏览器当中。

false:这个指令所在的标签,不会被渲染到浏览器当中。

 <body>
    <!-- 准备一个容器 -->
    <div id="app">
      <h1>{{msg}}</h1>
      <!-- 只会渲染一次,msg更改数据,也不会再次渲染 -->
      <h1 v-once>{{msg}}</h1>
      <h1 v-if="a > b">v-if测试:你看我出不出现</h1>
    </div>
    <!-- vue程序 -->
    <script>
      new Vue({
        el: "#app",
        data: {
          msg: "Hello Vue!",
          a: 10,
          b: 11,
        },
      });
    </script>
  </body>

2.1.3、v-bind指令详解

1. 这个指令是干啥的?

它可以让HTML标签的某个属性的值产生动态的效果。

2. v-bind指令的语法格式:

<HTML标签 v-bind:参数="表达式"></HTML标签>

3. v-bind指令的编译原理?

编译前:

<HTML标签 v-bind:参数="表达式"></HTML标签>

编译后:

<HTML标签 参数="表达式的执行结果"></HTML标签>

注意两项:

第一:在编译的时候v-bind后面的“参数名”会被编译为HTML标签的“属性名”

第二:表达式会关联data,当data发生改变之后,表达式的执行结果就会发生变化。所以,连带的就会产生动态效果。

4. v-bind因为很常用,所以Vue框架对该指令提供了一种简写方式:

只是针对v-bind提供了以下简写方式:

<img :src="imgPath">

5. 什么时候使用插值语法?什么时候使用指令?

凡是标签体当中的内容要想动态,需要使用插值语法。

只要向让HTML标签的属性动态,需要使用指令语法。

  <body>
    <!-- 准备一个容器 -->
    <div id="app">
      <!-- 注意:以下代码中 msg 是变量名。 -->
      <!-- 注意:原则上v-bind指令后面的这个参数名可以随便写。 -->
      <!-- 虽然可以随便写,但大部分情况下,这个参数名还是需要写成该HTML标签支持的属性名。这样才会有意义。 -->
      <span v-bind:xyz="msg"></span>

      <!-- 这个表达式带有单引号,这个'msg'就不是变量了,是常量。 -->
      <span v-bind:xyz="'msg'"></span>

      <!-- v-bind实战 -->
      <img src="../img/1.jpg" /> <br />
      <img v-bind:src="imgPath" /> <br />

      <!-- v-bind简写形式 -->
      <img :src="imgPath" /> <br />

      <!-- 这是一个普通的文本框 -->
      <input type="text" name="username" value="zhangsan" /> <br />
      <!-- 以下文本框可以让value这个数据变成动态的:这个就是典型的动态数据绑定。 -->
      <input type="text" name="username" :value="username" /> <br />

      <!-- 使用v-bind也可以让超链接的地址动态 -->
      <a href="https://www.baidu.com">百度1</a> <br />
      <a :href="url">百度2</a> <br />

      <!-- 不能采用以下写法,会报错-->
      <!-- <a href="{{url}}">百度3</a>  -->
    </div>
    <!-- vue程序 -->
    <script>
      new Vue({
        el: "#app",
        data: {
          msg: "Hello Vue!",
          imgPath: "../img/1.jpg",
          username: "章三",
          url: "https://www.baidu.com",
        },
      });
    </script>
  </body>

2.1.4、 v-model详解

1. v-bind和v-model这两个指令都可以完成数据绑定。

2. v-bind是单向数据绑定。

data ===> 视图

3. v-model是双向数据绑定。

data <===> 视图

4. v-bind可以使用在任何HTML标签当中。

v-model只能使用在表单类元素上,例如:input标签、select标签、textarea标签。

为什么v-model的使用会有这个限制呢?

因为表单类的元素才能给用户提供交互输入的界面。v-model指令通常也是用在value属性上面的。

5. v-bind和v-model都有简写方式:

v-bind简写方式:

v-bind:参数="表达式" 简写为 :参数="表达式"

v-model简写方式:

v-model:value="表达式" 简写为 v-model="表达式"

<body>
    <!-- 准备一个容器 -->
    <div id="app">
      <!-- 完整写法 -->
      v-bind指令:<input type="text" v-bind:value="name1" /><br />
      v-model指令:<input type="text" v-model:value="name2" /><br />

      <!-- 报错了,v-model不能使用在这种元素上。 -->
      <!-- <a v-model:href="url">百度</a> -->

      <!-- 简写 -->
      v-bind指令:<input type="text" :value="name1" /><br />
      v-model指令:<input type="text" v-model="name2" /><br />

       <!-- 联动改变 -->
      v-bind消息1:<input type="text" :value="msg" /><br />
      v-model消息2:<input type="text" v-model="msg" /><br />
    </div>

    <!-- vue程序 -->
    <script>
      new Vue({
        el: "#app",
        data: {
          name1: "zhangsan",
          name2: "wangwu",
          url: "https://www.baidu.com",
          msg: "Hello Vue!",
        },
      });
    </script>
  </body>

2.15、用户片段

安装插件:JavaScript (ES6) code snippets

为JavaScript、TypeScript、HTML、React和Vue提供了ES6的语法支持。

第一步:

第二步:

第三步:配置片段

html.json中设置html环境下的代码片段

// 配置信息
"Print to console": {
  // 给片段设置的简写
  "prefix": "log",
  // 配置片段
  "body": [
    // ,分割开每行代码  $1 鼠标聚焦的地方 
  "console.log('$1');",
  "$2"
  ],
  // 片段描述信息(可删除)
  "description": "Log output to console"
}

具体配置如下:

{
    "h5 template": {
        "prefix": "vv", // 对应的是使用这个模板的快捷键
        "body": [
            "<!DOCTYPE html>",
            "<html lang=\"en\">",
            "<head>",
            "\t<meta charset=\"UTF-8\">",
            "\t<meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">",
            "\t<meta http-equiv=\"X-UA-Compatible\" content=\"ie=edge\">",
            "\t<title>Document</title>",
            "\t<script src='https://cdn.jsdelivr.net/npm/vue@2.6.10/dist/vue.js'></script>",
            "</head>\n",
            "<body>",
            "\t<div id =\"root\"> </div>\n",
            "\t<script>",
            "\tVue.config.productionTip = false//阻止vue 在启动时生成生产提示",
            "\t var vm = new Vue({",
            "\t\tel: '#root',",
            "\t\tdata() {return{}},",
            "\t\tmethods: {}",
            "\t });",
            "\t</script>",
            "</body>\n",
            "</html>"
        ],
        "description": "vue学习模版" // 模板的描述
    }
}

在javascript.json 中配置js的片段

    // 配置信息
    "create vue instance": {
        // 给片段设置的简写
        "prefix": "v1",
        // 配置片段
        "body": [
            "\t var vm = new Vue({",
            "\t\tel: '#root',",
            "\t\tdata: {'$1'},",
            "\t });",
        ],
        // 片段描述信息(可删除)
        "description": "vm"
    },
<think>我们使用Vue2来实现一个图片叠放(类似楼层叠放)的效果。根据之前的设计,我们将创建多个图片层,每层有轻微的旋转和垂直偏移,形成堆叠效果。同时,当鼠标悬停时,图片会展开并显示完整内容。我们将创建一个Vue组件,名为`ImageStack`,它接收一个图片列表作为数据源,然后循环渲染这些图片,并应用CSS样式来实现堆叠效果。实现步骤:1.创建Vue组件,定义props(例如:images,用于接收图片数组)2.模板中循环遍历images,使用动态样式绑定每张图片的位置、旋转角度和z-index3.使用CSS样式设置绝对定位,并设置每张图片的默认偏移和旋转4.添加鼠标悬停事件,当悬停时,将当前图片置顶并应用放大的样式,同时移除旋转(可选,也可以保留部分旋转)注意:为了确保堆叠效果,我们需要设置一个容器(relative定位),内部图片都是absolute定位,通过top和left进行微调。我们将使用数组的索引来动态计算每张图片的旋转角度和位置偏移,以及z-index(越后面的图片z-index越低,并且位置稍微向下向右偏移)。具体实现如下:我们将为每个图片元素绑定动态样式(内联样式或类名),根据索引设置不同的旋转和位置。同时,通过数据属性(例如currentHoverIndex)来跟踪当前悬停的图片索引,从而改变其样式。但注意,我们不需要为每张图片都设置不同的样式,而是通过索引和悬停状态来动态计算。我们也可以使用CSS类来控制基本样式,然后通过动态绑定类来处理悬停状态。考虑到Vue2语法,我们使用`v-for`循环,并利用索引。设计思路:1.未悬停状态:每张图片根据索引有轻微旋转(正负交替或随机)和垂直偏移(越往后的图片偏移越大,形成堆叠)2.悬停状态:该图片放大,旋转归零(或接近零),提升z-index,并增加阴影。我们将使用两种方式结合:-使用计算属性为每个图片生成样式对象(基于索引和悬停状态)-或者,在方法中定义一个计算样式的函数这里,我们选择在模板中直接使用对象语法。此外,为了过渡效果,我们为图片元素添加`transition`属性。示例数据:images:[{title:'山间风光',desc:'自然风光下的壮丽山脉与森林覆盖',url:'https://picsum.photos/600/400?random=1'},{title:'海滨日落',desc:'夕阳余晖洒在金色沙滩上的美景',url:'https://picsum.photos/600/400?random=2'},{title:'古老建筑',desc:'历经沧桑的历史建筑与独特设计',url:'https://picsum.photos/600/400?random=3'}]我们将为每个图片添加鼠标事件:@mouseenter="hoverIndex=index"@mouseleave="hoverIndex=-1"然后在动态样式中根据hoverIndex和当前index的关系来调整样式。注意:为了形成交错的旋转效果,我们可以根据索引是奇数还是偶数来决定旋转方向(或者根据除以3的余数等)。具体旋转值我们可以预设一个数组,或者根据索引计算。例如:rotation:index%2?5:-3->奇数索引旋转5度,偶数旋转-3度hover时:如果当前索引等于hoverIndex,则旋转0度,并放大另外,垂直偏移:我们可以让每张图片比前一张向下和向右(或向左)偏移一定量。偏移量计算:使用index乘以一个偏移值(例如10px)但在堆叠效果中,我们通常希望后面的图片在视觉上是在下面,所以位置会靠后(向下)并可能向两侧偏移。我们设置初始位置都为容器顶部,然后通过top和left进行偏移。设计:第一张:top:0,left:15%->默认第二张:top:30px,left:10%->比第一张向下向右偏移一些(这里left减少表示向左?)但是为了形成自然堆叠,我们可以让后面的图片在top上增加,在left上随机或交替。但为了简化,我们可以让每一张图片在top上增加30px,在left上减少5%(这样就会向左偏移,形成错落)。但是我们希望是垂直堆叠,所以主要是在垂直方向上的偏移。然而,在堆叠效果中,我们通常希望用户能看到下面图片的一角,所以除了垂直方向,水平方向也要有偏移。所以,我们这样设置:top:index*30pxleft:初始为50%,然后根据索引调整水平偏移,这样更灵活。但为了确保图片在容器内,我们使用百分比设置left。我们设定一个初始left,然后每一张图片的left在此基础上增加或减少一个很小的值(比如5%)。由于我们使用绝对定位,我们希望图片在水平方向居中,然后通过调整left来让它们左右错开。原CSS示例中:第一张:left:15%第二张:left:10%第三张:left:5%所以我们这样设置:left值=(15-index*5)%在悬停时,我们希望图片回到中间位置(比如left:25%),并且top回到0,然后放大。但是,由于我们要让所有图片在悬停时都能完整显示,所以我们可以让悬停的图片left为25%(或者50%减去图片宽度的一半)?因为我们的宽度是75%,所以为了居中,left应该为(100%-75%)/2=12.5%,但这样会破坏堆叠的错位感,所以我们悬停时不改变left?或者统一设置为居中?原设计是:悬停时,不改变left,只改变旋转、缩放和z-index。这样图片位置不会突变,只是放大和去除旋转。所以,我们悬停时不改变left和top,只改变transform(旋转和缩放),以及z-index。因此,我们动态样式分为两部分:1.基础定位:根据index设置top和left2.变换:根据是否为悬停状态设置transform同时,我们为所有图片设置相同的宽度和高度(百分比),然后让容器固定高度。我们将为每个图片设置一个动态类,以及动态样式。由于Vue2不支持组合式API,我们将在data中定义hoverIndex(当前悬停的图片索引,默认为-1),然后在模板中计算样式。具体代码实现如下:</think> # Vue2实现图片楼层叠放效果 下面我将用Vue2语法实现一个图片楼层叠放效果,模拟类似相册叠放的效果,其中图片有垂直错位和轻微旋转,用户可以清晰地看到每层内容。 ```html <!DOCTYPE html> <html lang="zh-CN"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Vue2图片楼层叠放效果</title> <script src="https://cdn.jsdelivr.net/npm/vue@2.6.14/dist/vue.js"></script> <style> * { margin: 0; padding: 0; box-sizing: border-box; } body { font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; background: linear-gradient(135deg, #1a2a6c, #b21f1f, #fdbb2d); min-height: 100vh; display: flex; justify-content: center; align-items: center; padding: 20px; color: #fff; } .container { max-width: 1200px; width: 100%; padding: 20px; text-align: center; } h1 { font-size: 2.8rem; margin-bottom: 20px; text-shadow: 0 2px 4px rgba(0, 0, 0, 0.3); } .description { font-size: 1.2rem; margin-bottom: 40px; max-width: 800px; margin-left: auto; margin-right: auto; line-height: 1.6; color: #e0e0e0; } .image-stack { position: relative; width: 85%; height: 500px; margin: 0 auto; perspective: 1200px; } .image-layer { position: absolute; width: 85%; height: 85%; background-size: cover; background-position: center; border-radius: 15px; box-shadow: 0 15px 35px rgba(0, 0, 0, 0.3); transition: all 0.5s cubic-bezier(0.25, 0.8, 0.25, 1); display: flex; align-items: center; justify-content: center; overflow: hidden; border: 8px solid white; cursor: pointer; transform-origin: center bottom; } .image-content { background: rgba(0, 0, 0, 0.7); padding: 25px; border-radius: 10px; max-width: 80%; transition: transform 0.3s; color: white; text-align: center; } .image-content h3 { font-size: 1.8rem; margin-bottom: 15px; } .image-content p { font-size: 1.1rem; line-height: 1.6; margin-bottom: 20px; } .details-btn { background: #fdbb2d; border: none; padding: 12px 25px; border-radius: 50px; font-size: 1rem; font-weight: bold; cursor: pointer; transition: all 0.3s; color: #333; box-shadow: 0 4px 8px rgba(0, 0, 0, 0.2); } .details-btn:hover { background: #ffa000; transform: translateY(-3px); box-shadow: 0 6px 12px rgba(0, 0, 0, 0.25); } .controls { margin-top: 30px; display: flex; justify-content: center; gap: 20px; } .control-btn { background: rgba(255, 255, 255, 0.2); border: none; padding: 12px 25px; border-radius: 50px; font-size: 1rem; font-weight: bold; cursor: pointer; transition: all 0.3s; color: white; backdrop-filter: blur(5px); box-shadow: 0 4px 8px rgba(0, 0, 0, 0.2); } .control-btn:hover { background: rgba(255, 255, 255, 0.3); transform: translateY(-2px); } @media (max-width: 768px) { .image-stack { height: 400px; } .image-layer { width: 90%; height: 80%; } } @media (max-width: 480px) { h1 { font-size: 2.2rem; } .image-stack { height: 350px; } .image-content { padding: 15px; } .image-content h3 { font-size: 1.4rem; } .controls { flex-direction: column; align-items: center; } } </style> </head> <body> <div id="app"> <div class="container"> <h1>图片叠放画廊</h1> <p class="description">探索我们的精选图片集,每张图片都有独特的角度和展示效果。点击或悬停在图片上查看详情。</p> <div class="image-stack"> <!-- 动态生成图片层 --> <div v-for="(image, index) in images" :key="image.id" class="image-layer" :style="{ top: calculateTop(index) + 'px', left: calculateLeft(index) + '%', transform: calculateTransform(index), zIndex: activeIndex === index ? 10 : images.length - index, backgroundImage: 'url(' + image.url + ')' }" @mouseover="setActive(index)" @mouseleave="resetActive" @click="setActive(index)" > <div class="image-content" v-if="activeIndex === index"> <h3>{{ image.title }}</h3> <p>{{ image.description }}</p> <button class="details-btn">查看详情</button> </div> </div> </div> <div class="controls"> <button class="control-btn" @click="prevImage">上一张</button> <button class="control-btn" @click="resetStack">重置叠放</button> <button class="control-btn" @click="nextImage">下一张</button> </div> </div> </div> <script> new Vue({ el: '#app', data: { images: [ { id: 1, title: '山间风光', description: '壮丽的日出笼罩着雄伟的山脉,清晨的阳光穿过云层,照亮了整个山谷。', url: 'https://picsum.photos/800/600?random=1' }, { id: 2, title: '海滨日落', description: '宁静的海滩上,金色的夕阳映衬着海浪,形成一幅美丽的画面。', url: 'https://picsum.photos/800/600?random=2' }, { id: 3, title: '古老建筑', description: '历史悠久的建筑矗立在城市中心,见证了几个世纪的变迁与发展。', url: 'https://picsum.photos/800/600?random=3' }, { id: 4, title: '宁静湖泊', description: '如镜的湖面倒映着周围的山峦,偶尔有候鸟飞过,打破湖面的平静。', url: 'https://picsum.photos/800/600?random=4' } ], activeIndex: -1, offsetAmount: 35 }, methods: { // 计算每张图片的顶部偏移 calculateTop(index) { return this.activeIndex === index ? 0 : index * this.offsetAmount; }, // 计算每张图片的左侧偏移 calculateLeft(index) { if (this.activeIndex === index) return 7.5; // 激活项居中 const middleIndex = (this.images.length - 1) / 2; const offsetFromCenter = (index - middleIndex) * 2; return 7.5 + offsetFromCenter; }, // 计算图片的变换效果 calculateTransform(index) { if (this.activeIndex === index) { return 'scale(1.05) rotate(0deg)'; } // 为未激活项创建错位旋转效果 const rotation = index % 2 === 0 ? 4 : -3; return `rotate(${rotation}deg)`; }, // 设置当前激活的图片 setActive(index) { this.activeIndex = index; }, // 重置激活状态 resetActive() { this.activeIndex = -1; }, // 切换到下一张图片 nextImage() { if (this.activeIndex === -1) { this.activeIndex = 0; } else { this.activeIndex = (this.activeIndex + 1) % this.images.length; } }, // 切换到上一张图片 prevImage() { if (this.activeIndex === -1) { this.activeIndex = this.images.length - 1; } else { this.activeIndex = (this.activeIndex - 1 + this.images.length) % this.images.length; } }, // 重置叠放效果 resetStack() { this.activeIndex = -1; } } }); </script> </body> </html> ``` ## Vue2实现原理说明 ### 1. 数据结构设计 使用`images`数组存储所有图片数据,每张图片包含: - `id`: 唯一标识 - `title`: 图片标题 - `description`: 图片描述 - `url`: 图片路径 ### 2. 动态样式绑定 通过Vue的样式绑定实现叠放效果: ```javascript :style="{ top: calculateTop(index) + 'px', left: calculateLeft(index) + '%', transform: calculateTransform(index), zIndex: activeIndex === index ? 10 : images.length - index, backgroundImage: 'url(' + image.url + ')' }" ``` ### 3. 叠放位置计算 ```javascript // 计算垂直方向偏移 calculateTop(index) { return this.activeIndex === index ? 0 : index * this.offsetAmount; } // 计算水平方向偏移 calculateLeft(index) { if (this.activeIndex === index) return 7.5; const middleIndex = (this.images.length - 1) / 2; const offsetFromCenter = (index - middleIndex) * 2; return 7.5 + offsetFromCenter; } ``` ### 4. 旋转效果实现 ```javascript // 激活项无旋转,非激活项轻微旋转 calculateTransform(index) { if (this.activeIndex === index) { return 'scale(1.05) rotate(0deg)'; } const rotation = index % 2 === 0 ? 4 : -3; return `rotate(${rotation}deg)`; } ``` ### 5. 交互功能 - `@mouseover="setActive(index)"`: 鼠标悬停时激活当前项 - `@mouseleave="resetActive"`: 鼠标离开时重置激活状态 - `@click="setActive(index)"`: 点击激活当前项 ### 6. 控制功能 - `nextImage()`: 切换到下一张图片 - `prevImage()`: 切换到上一张图片 - `resetStack()`: 重置叠放效果 ## 实现效果特点 1. **动态叠放**:图片根据位置动态偏移,形成立体叠放效果 2. **旋转展示**:非激活图片带有轻微旋转角度,便于查看内容 3. **激活状态**:激活的图片移至顶部、取消旋转并放大 4. **内容显示**:激活图片上显示标题和描述信息 5. **响应式设计**:自适应不同屏幕尺寸 6. **交互控制**:可通过按钮或点击切换图片状态 这个实现充分利用了Vue2的数据驱动特性和动态样式绑定,创建出具有视觉吸引力的图片叠放效果。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值