Vue.js初体验:踏入前端开发的灵活世界

前言

在前端领域,众多框架和库的涌现使得开发变得更加高效和灵活。Vue.js(简称Vue)作为其中一员,在其简洁而强大的特性下,吸引了越来越多的开发者。本文将分享我的Vue初体验,探索这个流行的JavaScript框架的基本概念和使用感受。篇尾附上一个实战小demo。

Vue.js:轻巧而强大

Vue.js是一款渐进式JavaScript框架,专注于构建用户界面。相比于其他框架,Vue更加轻量,容易上手,同时在大型项目中也能展现出强大的表现。它由尤雨溪(Evan You)于2014年创建,并迅速在开发者社区中崭露头角。

我的第一个Vue实例

xml 复制代码
<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title></title>
</head>

<body>
  <div id="app"></div>
  <template id="tel">
    <h3>{{message}}</h3>
  </template>

  <script src="https://unpkg.com/vue@3/dist/vue.global.js"></script>
  <script>
    Vue.createApp({
      template: '#tel',
      data: function () {
        // 数据存放的地方
        return {
          message: 'Hello BiangBiang!'
        }
      }
    }).mount('#app')
  </script>
</body>

</html>

解释:

  • <div id="app">:定义一个带有ID为 "app" 的空<div>元素,作为Vue应用的挂载点。
  • <template id="tel">...</template>:使用了Vue 3的模板语法,定义了一个模板,其中有一个<h3>标签,通过{{message}}插值语法展示一个动态的文本。这个模板被放在了<template>标签中,并通过ID为 "tel" 的模板标签进行引用。
  • <script src="https://unpkg.com/vue@3/dist/vue.global.js"></script>:引入Vue 3的全局构建,这是通过UNPKG提供的CDN链接引入Vue库。

可在Vue.js的官网找到:

  • Vue.createApp({...}):通过Vue.createApp方法创建了一个Vue应用实例。
  • template: '#tel':在Vue应用实例中指定了模板,使用了之前定义的ID为 "tel" 的模板。
  • data: function () {...}:定义了一个数据属性 message,初始值为 'Hello BiangBiang!'。
  • .mount('#app'):将Vue应用实例(也就是上述创建的app)挂载到ID为 "app" 的HTML元素上,使Vue应用能够在该元素内进行渲染和交互。

效果:

初次学的时候还没一眼看出Vue的优势,心想原本一行可以解决的代码却写的这么麻烦,可又很简单能想到,实际项目开发代码量是巨大的,Vue的优势到那个时候想必就能体现出来了。由于本人还刚初次接触,只了解Vue的一些优势,有的优势看了也不是很能理解,下面引用网上给出的Vue开发的优势。

  1. 简洁易学: Vue.js的设计简单直观,易于学习和上手。Vue提供了清晰的文档和逐步增量的学习曲线,使新手能够快速入门。
  2. 响应式数据绑定: Vue采用了双向数据绑定,当数据发生变化时,视图会自动更新,反之亦然。这简化了DOM操作,提高了开发效率。
  3. 组件化开发: Vue推崇组件化开发思想,将一个应用划分为多个独立的组件,每个组件负责自己的状态和视图。这使得代码更易于维护、复用和测试。
  4. 灵活性: Vue并不强制使用特定的工具链,可以逐步采用,也可以与其他库和项目无缝集成。这种灵活性使得Vue可以适应各种项目规模和需求。
  5. 渐进式框架: Vue是一个渐进式框架,可以根据项目的需要逐步引入。你可以选择只使用Vue的一部分功能,如只使用Vue的数据绑定而不使用其它特性。
  6. 虚拟DOM: Vue使用虚拟DOM来提高性能。通过在内存中维护一个虚拟DOM树,Vue能够在数据变化时计算出最小化的DOM更新,从而减少真实DOM操作的次数,提高页面渲染效率。
  7. 社区和生态系统: Vue拥有庞大而活跃的社区,开发者可以从社区获取支持、学习经验,并分享自己的知识。此外,Vue的生态系统也在不断壮大,有许多插件和第三方库可供选择。
  8. 适用于单页应用(SPA): Vue对单页应用提供了良好的支持,通过Vue Router进行路由管理,通过Vuex进行状态管理,使得开发复杂的前端应用变得更加容易。
  9. 良好的性能: Vue的虚拟DOM和合理的更新策略使得应用具有良好的性能表现,同时Vue 3引入了一些新的优化策略,进一步提升了性能。

以上9点我目前并没有全部切身感受到,其中第1,2,5,6点目前都能感受到一点,我等下也会通过最近的学习来举例,但是相信不出一个月,我对Vue的认识也会更深一步。到时候也可以给大家分享更深层次的Vue的学习体验。下面简单介绍一下最近学习的Vue的部分指令,以及computed和watch的基本使用。

Vue指令

1.v-html

  • 作用:插入HTML
  • 例子:<div v-html="info"></div>,将info中的HTML代码插入到元素中。

2.v-text

  • 作用:插入文本
  • 例子:<div v-text="msg"></div>,将msg中的文本代码插入到元素中。
xml 复制代码
<body>
  <div id="app"></div>

  <template id="my-app">
    <div>{{msg}}</div>
    <div v-text="msg"></div>
    
    <div v-html="info"></div>
  </template>

  <script src="https://unpkg.com/vue@3/dist/vue.global.js"></script>

  <script>
    const App = {
      template:'#my-app',
      data(){
        return {
          msg:'hello World!',
          info:`<h1>这是一个富文本</h1>`
        }
      }
    }

    Vue.createApp(App).mount('#app')
  </script>
</body>

3.v-once

  • 作用:只渲染一次渲染了一次就不再渲染了
  • 例子:<h1 v-once>{{count}}</h1>,count变化一次之后就不会再变了,如下图。

不加该属性:

加上该属性:

代码案例:

xml 复制代码
<body>
  <div id="app"></div>

  <template id="my-app">
    <h2>{{count}}</h2>
    <button @click="add">+1</button>
    <!-- v-once 只渲染一次 变了一次之后就不会再变了 -->
    <h1 v-once>{{count}}</h1>
  </template>

  <script src="https://unpkg.com/vue@3/dist/vue.global.js"></script>

  <script>
    const App = {
      template: '#my-app',
      data() {
        return {
          count: 100
        }
      },
      methods:{
        add(){
          this.count++;
        }
      }
    }

    Vue.createApp(App).mount('#app')
  </script>
</body>

可以看到加上了v-once之后,原本都需要增加的下面的点击确不会再增加了。

4.v-bind

  • 作用:进行属性绑定,可以v-bind:class(动态类名) 也可以 v-bind:style(样式)
  • 例子:<a v-bind:href="url">Link</a>,将href属性绑定到url变量。

5.v-on

  • 作用:进行事件绑定,可简写成@事件名
  • 例子:<button v-on:click="change">按我</button>,当按钮被点击时执行 change 方法。

6.v-pre

  • 语法:v-pre
  • 例子:<span v-pre>{{ 这里不会被编译,而是连同括号一起输出 }}</span>,使元素和它的所有子节点都跳过编译。

7.v-if

  • 作用:条件渲染,和其他编程语言的if语句类似
  • 例子:<h2 v-if="count === 1">今天你写代码了吗?</h2> <h2 v-else-if="count === 2">今天你看掘金文章了吗?</h2> <h2 v-else>都看了</h2>

效果展示:

xml 复制代码
<body>
  <div id="app"></div>
  <template id='my-app'>
    <h2 v-if="count === 1">今天你写代码了吗?</h2>
    <h2 v-else-if="count === 2">今天你看掘金文章了吗?</h2>
    <h2 v-else>都看了</h2>
  </template>


  <script src="https://unpkg.com/vue@3/dist/vue.global.js"></script>
  <script>
    const App = {
      template: '#my-app',
      data: function () {
        return {
          count: 0
        }
      },
      methods: {
        change() {
          this.count++;
          if (this.count == 3) {
            this.count = 0;
          }
          this.count %= 3;
        }
      }
    }

    Vue.createApp(App).mount('#app')
  </script>
</body>

8.v-show

  • 作用:条件显示 ,v-show = "条件"
  • 例子:<p v-show="isShown">Hello World</p>,根据isShown的值决定是否显示元素。

值得注意的是:相比于上面的v-if等等, v-show存在一个弊端,v-show是直接修改style属性 ,将display改为none ,而上面的是直接删除动物结构或者添加动物结构,所以它消失后不会允许用户右键检查直接修改display属性,而v-show可以。但是v-show也有好处,由于v-if是直接删除或添加动物结构,但在频繁切换时可能涉及到DOM的销毁和创建,带来一些性能开销。而v-show更适用于需要频繁切换的场景,它的性能开销较小。

9.v-for

  • 作用:循环渲染 v-for="item in items" 或 v-for="(item,index) in items"
  • 例子:<li v-for="item in items">{{ item.text }}</li>,根据数组items的内容渲染列表项。

效果展示:

xml 复制代码
<body>
  <div id="app"></div>
  <template id="my-app">
    <h2>歌曲列表</h2>
    <ul>
      <!-- 使用v-for时 常在v-for其后加上 :key="唯一且不同的标识"   否则性能就会降低 ,但下面这个index其实也没有用 这个以后再了解 -->
      <li v-for="(item ,index) in songs" :key="index" v-if="">{{index+1}}--{{item}}
        <a href="#" @click="del(index)">x</a>
      </li>
    </ul>
  </template>

  <script src="https://unpkg.com/vue@3/dist/vue.global.js"></script>
  <script>
    const App = {
      template: '#my-app',
      data() {
        return {
          songs: [
            '说好不哭',
            '稻香',
            '说好的幸福呢',
            '等你下课',
            '告白气球',
            '半岛铁盒',
            '夜曲'
          ]
        }
      },
      methods:{
        del(i){
          this.songs.splice(i, 1);
        }
      }
    }

    Vue.createApp(App).mount('#app')
  </script>
</body>

计算属性computed

  • 动态更新

直接上案例:

xml 复制代码
<body>
  <div id="app"></div>
  <template id="my-app">
    <h2>今天温度:{{temp}}°</h2>
    <h3>温馨提示:建议出门穿:{{suggestion}}</h3>

    <button @click="add">+</button>
    <button @click="down">-</button>

  </template>

  <script src="https://unpkg.com/vue@3/dist/vue.global.js"></script>
  <script>
    const App = {
      template: '#my-app',
      data() {
        return {
          temp: 10,

        }
      },
      computed: {
        // computed 里面的属性时响应式执行 执行条件是当它依赖的数据源发生变化时(如:下述案例为temp) 它才会执行
        suggestion() {
          let res = '夹克'

          if (this.temp >= 20) {
            res = '短袖'
          } else if (this.temp <= 0) {
            res = '棉袄'
          } else {
            res = '夹克'
          }
          return res
        }
      },
      methods: {
        add() {
          this.temp += 5
        },
        down() {
          this.temp -= 5
        }
      }
    }

    Vue.createApp(App).mount('#app')
  </script>
</body>

效果如下:

上述代码,我们将suggestion函数放在methods里面也能执行,但是为什么还要增加一个computed计算属性呢。这是因为计算属性它是依赖缓存的,它只有依赖关系发生了变化,计算属性才会重新计算。这也意味着在多次访问相同的计算属性时,Vue会返回之前计算的结果,而不用重新计算,这显然提高了性能。而methods每次调用都会执行一次,这也是计算属性的优势之处。

侦听器watch

  • 添加侦听,也可以进行动态更新
xml 复制代码
<body>
  <div id="app"></div>
  <template id="my-app">
    <h2>今天温度:{{temp}}°</h2>
    <h3>温馨提示:建议出门穿:{{suggestion}}</h3>

    <button @click="add">+</button>
    <button @click="down">-</button>

  </template>

  <script src="https://unpkg.com/vue@3/dist/vue.global.js"></script>
  <script>
    const App = {
      template: '#my-app',
      data() {
        return {
          temp: 30,
          suggestion: '夹克'
        }
      },
      watch: {  // 侦听器
        // 侦听temp数据
        temp: {
          // newVal:新改变的值 oldVal:原先的值
          handler: function (newVal, oldVal) {
            if (newVal >= 20) {
              this.suggestion = '短袖'
            } else if (newVal <= 0) {
              this.suggestion = '羽绒服'
            } else {
              this.suggestion = '夹克'
            }
          },
          // 加载页面时立即执行一遍上面的handler函数,(因为我们拿到得温度初始值可能是30,但默认的是夹克,显然不合理)
          immediate:true
        }
      },
      methods: {
        add() {
          this.temp += 5
        },
        down() {
          this.temp -= 5
        }
      }
    }

    Vue.createApp(App).mount('#app')
  </script>
</body>

效果和上述computed计算属性是一样的,不过它可以加一个属性immediate,当值为true时表示加载页面的时候就会立即执行一遍。正好会覆盖掉我们设置的初始值。

了解了上面这些之后,下面是一个简单的实战小demo,刚接触Vue的可先自行完成,效果如下:

附上上述小demo的代码:

HTML:

HTML 复制代码
<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
  <link rel="stylesheet" href="./style.css">
</head>

<body>

  <div id="app"></div>

  <template id="my-app">
    <table>
      <thead>
        <th>序号</th>
        <th>书籍名称</th>
        <th>出版日期</th>
        <th>价格</th>
        <th>购买数量</th>
        <th>操作</th>
      </thead>
      <tbody>
        <tr v-for="(book,index) in books" :key="index">
          <td>{{book.id}}</td>
          <td>{{book.name}}</td>
          <td>{{book.date}}</td>
          <td>{{book.price}}</td>
          <td>
            <button @click="down(index)">-</button>
            <span class="counter">{{book.count}}</span>
            <button @click="add(index)">+</button>
          </td>
          <td>
            <button @click="remove(index)">移除</button>
          </td>
        </tr>
      </tbody>
    </table>
    <h2>总价格: {{totalPrice}} </h2>
  </template>

  <script src="https://unpkg.com/vue@3/dist/vue.global.js"></script>
  <script src="./index.js"></script>

</body>

</html>

CSS:

CSS 复制代码
table {
  border: 1px solid #e9e9e9;
  border-collapse: collapse;
  border-spacing: 0;
}

th, td {
  padding: 8px 16px;
  border: 1px solid #e9e9e9;
  text-align: left;
}

th {
  background-color: #f7f7f7;
  color: #5c6b77;
  font-weight: 600;
}

.counter {
  margin: 0 5px;
}

JS:

JS 复制代码
Vue.createApp({
  template: "#my-app",
  data() {
    return {
      books: [
        {
          id: 1,
          name: '《算法导论》',
          date: '2006-9',
          price: 85.00,
          count: 0
        },
        {
          id: 2,
          name: '《UNIX编程艺术》',
          date: '2006-2',
          price: 59.00,
          count: 0
        },
        {
          id: 3,
          name: '《编程珠玑》',
          date: '2008-10',
          price: 39.00,
          count: 0
        },
        {
          id: 4,
          name: '《代码大全》',
          date: '2006-3',
          price: 128.00,
          count: 0
        },
      ],
    }
  },
  computed: {
    totalPrice() {
      // 两种计算价格的方式都可以
      // return this.books.reduce((sum, book) => {
      //   return sum + book.price * book.count;
      // }, 0);
      let sum = 0;
      for (let i = 0; i < this.books.length; i++) {
        sum += this.books[i].price * this.books[i].count;
      }
      return sum;
    },
  },
  methods: {
    add(index) {
      this.books[index].count++;
    },
    down(index) {
      if (this.books[index].count != 0) {
        this.books[index].count--;
      }
    },
    remove(index) {
      this.books.splice(index, 1);
    }
  }
}).mount("#app");

留言

博主刚接触Vue,可能上述内容比较简单,以后随着学习的深入,我还会持续更新质量更高的内容♥(ˆ◡ˆԅ)。

相关推荐
NiNg_1_23416 分钟前
npm、yarn、pnpm之间的区别
前端·npm·node.js
秋殇与星河18 分钟前
CSS总结
前端·css
NiNg_1_23419 分钟前
Vue3 Pinia持久化存储
开发语言·javascript·ecmascript
读心悦20 分钟前
如何在 Axios 中封装事件中心EventEmitter
javascript·http
BigYe程普40 分钟前
我开发了一个出海全栈SaaS工具,还写了一套全栈开发教程
开发语言·前端·chrome·chatgpt·reactjs·个人开发
神之王楠1 小时前
如何通过js加载css和html
javascript·css·html
余生H1 小时前
前端的全栈混合之路Meteor篇:关于前后端分离及与各框架的对比
前端·javascript·node.js·全栈
花花鱼1 小时前
@antv/x6 导出图片下载,或者导出图片为base64由后端去处理。
vue.js
程序员-珍1 小时前
使用openapi生成前端请求文件报错 ‘Token “Integer“ does not exist.‘
java·前端·spring boot·后端·restful·个人开发
axihaihai1 小时前
网站开发的发展(后端路由/前后端分离/前端路由)
前端