V

Vue.js 的全面介绍🔥🚀

2025-05-28

Vue.js 的全面介绍🔥🚀

Vue.js是一个易于使用、功能多样、性能卓越且循序渐进的用户界面构建框架。其核心库专注于构建视图层。它借鉴了Angular(例如模板语法)和React(例如虚拟 DOM)的优点,并在此基础上添加了更多增强功能。

简介

网上有很多文章,但我还是想写一篇,因为它展现了我学习新框架/库的逻辑。Vue之所以能迅速流行起来,是因为它能够适应开发者的需求。它的另一个优点是迁移到 Vue 非常容易。你只需要在页面中添加一个 script 标签就可以了。

您甚至不需要知道什么是像webpack这样的捆绑器,或者像babel这样的高级编译器,或者使用像 Vue 这样的包管理器npm来开始使用。

它确实有一个CLI,可以帮助您构建具有各种配置选项的功能齐全的 SPA,包括 Babel、TypeScript、ESLint、PostCSS、PWA、单元测试和端到端测试。

它的 CLI 最好的一点是您不需要弹出create-react-app就可以自定义您的配置。

开始

好了,闲话少叙,让我们开始我们的第一个Vue应用吧。我会从最简单的方法开始。我们先创建一个简单的 HTML 页面:

<html>

<body>
    <div id="my-vue-app">
        <p>{{ hello }}</p>
    </div>
    <script src="https://unpkg.com/vue"></script>
    <script>
      new Vue({
        el: '#my-vue-app',
        data: {
          hello: 'Hello World!'
        }
      })
    </script>
</body>

</html>
Enter fullscreen mode Exit fullscreen mode

不管你信不信,以上就是你的第一个Vue应用启动运行所需的全部步骤。现在,我们来分解一下,看看到底发生了什么。

您首先看到的是一个段落,其中包含对名为 的变量的模板引用hello,类似于 Angular。这意味着该值将被替换为Vue。然后我们导入脚本,UNPKG该脚本在 之上构建了一个 CDN(内容分发网络)npm

然后,在第二个脚本标签中,我们创建一个新的Vue实例,并告诉它使用一个 id 为 的 DOM 元素#my-vue-app。Vue将控制此元素及其子元素。最后,我们指定一个带有属性的数据对象。Vuehello会在模板中替换此变量。因此,当您在浏览器中打开此文件时,应该会看到一个带有 id 的页面Hello World!

请注意,我们没有使用this.data.hello访问变量,这是因为Vue会自动使数据的每个属性都像高级变量一样可访问。

您可以在 CodePen 👇🏼 中实时查看此示例:

使用 CLI

现在,并非所有应用程序都像我们的 hello world 一样简单,因此我们需要了解Vue CLI,它可以帮助您从头开始构建完整的应用程序。在VS Code中打开终端,导航到您选择的文件夹并运行以下命令:

npx @vue/cli create my-cli-app
Enter fullscreen mode Exit fullscreen mode

或者,您可以全局安装它:

npm i -g @vue/cli

vue create create my-cli-app
Enter fullscreen mode Exit fullscreen mode

运行该命令时,系统会提示你选择一个预设。你可以选择基于Babel和 的默认预设ESList,也可以选择自定义预设,这样你可以有更多选择,例如 TypeScript、CSS 预处理器等。

由于本介绍的重点是 Vue 本身,因此我不会深入探讨 CLI 的细节,请访问其官方网站以获取有关如何使用 CLI 的更多信息。

当新应用程序创建完成后,您将得到如下文件夹结构:

Vue CLI 项目文件夹结构

您不需要关注所有这些文件,只需知道index.html包含Vue要处理的内容、divVue实例化的位置以及包含我们默认组件的单个文件组件(我稍后会解释这一点)。src/main.tssrc/App.vue

单文件组件:
单文件组件是一个包含Vue组件所需的所有内容(HTML、CSS 和 JavaScript)的文件。您甚至可以将样式限定在组件内,以避免与其他组件发生不必要的样式冲突。某种程度上,它类似于Shadow DOM

如果你查看App.vue文件中的 script 标签,你会发现它只是定义了一个组件,其中包含另一个HelloWorld引用自其他文件的组件。Hello world 组件是另一个单文件组件,它被传递了一个 props 参数,并显示在模板中。

我现在不会再进一步​​阐述这一点,但你明白我的意思了。

要运行该应用程序,只需打开 type npm run serve。你应该看到如下页面:

Vue CLI 项目的默认页面

Vue 根组件

现在我们已经了解了如何开始,让我们深入研究Vue的构建块。我们应该从它的根实例开始。

new Vue({ 
  el: '#vue-app',
  data: {
    name: 'Yaser'    
  },
  computed: {
    fullName: function() {
      return this.name + 'Adel';
    }
  },
  watch: {
    name: function(oldVal, newVal) {
      console.log(`Name changed from ${oldVal} to ${newVal}`)
    }
  },
  methods: {
    nickName: function() {
      return this.name === 'Yaser' ? 'Yashints' : 'NA';
    }
  },
  created: function() {
    console.log(`${this.name}`);
  }
  ...
})
Enter fullscreen mode Exit fullscreen mode

好的,这里发生了很多事情,所以让我们逐一分解。

埃尔

这是我们希望Vue使用的元素的 id 选择器。

数据

此对象包含您想要在应用程序中维护的任何属性。您可以在模板中通过属性名称获取它们的值。这之所以有效,是因为Vue会自动使所有属性在高级this上下文中可访问。

计算

有时你的模板中会有太多的逻辑,请看这个虚构的例子:

<div id="my-component">
  {{ name.split('').reverse().join('') }}
</div>
Enter fullscreen mode Exit fullscreen mode

在这种情况下,运行应用程序时会看到resaY,但在模板中包含这些函数调用并不是一个好习惯。您可以创建一个计算属性,在模板之外的其他位置处理所有这些逻辑。

var vm = new Vue({
  el: '#my-component',
  data: {
    name: 'Yaser'
  },
  computed: {
    // a computed getter
    reversedName: function () {
      // `this` points to the vm instance
      return this.name.split('').reverse().join('')
    }
  }
})
Enter fullscreen mode Exit fullscreen mode

在您的模板中,您只需:

<div id="my-component">
  {{ reversedName }}
</div>
Enter fullscreen mode Exit fullscreen mode

小心计算属性,这些属性是根据其依赖项的值进行缓存的,这意味着只有在值发生变化时才会重新评估。

这意味着下面的代码不会返回您所想的结果:

computed: {
  now: function () {
    return Date.now()
  }
}
Enter fullscreen mode Exit fullscreen mode

这是因为Date.now()它不是一种反应性依赖。

方法

方法是一种简单的函数,它能让你处理诸如点击和输入变化之类的事件。除此之外,你还可以将它们用于许多其他用途,但其主要用途是事件处理。

您可能会说我们可以使用一种方法来实现前面的计算属性:

<div id="my-component">
  {{ reversedName() }}
</div>
Enter fullscreen mode Exit fullscreen mode
methods: {
  reverseName: function () {
    return this.name.split('').reverse().join('')
  }
}
Enter fullscreen mode Exit fullscreen mode

最终结果完全相同,但不同之处在于计算属性会根据其对应的依赖关系进行缓存。这意味着计算属性只有在依赖关系发生变化时才会重新计算,而该方法无论如何都会被调用。

处理事件的理想方法是:

<div id="app">
  <button @click="sayhi">Hi</button>
  <p>{{ message }}</p>
</div>
Enter fullscreen mode Exit fullscreen mode

你的组件将具有:

new Vue({
  el: '#app',
  data() {
    return {
      message: null
    }
  },
  methods: {
    sayhi() {
      this.message = 'Hey you!'
    }
  }
})
Enter fullscreen mode Exit fullscreen mode

到目前为止,您还没有看到 指令@click。我将在本文后面详细介绍指令,但这是 的简写v-on:click

生命周期钩子

我在上面的代码片段中定义的函数created只是使用Vue时可以访问的众多生命周期钩子之一。可以将其视为每个组件实例化时必须经历的步骤。例如数据观察、模板编译、将实例挂载到 DOM、数据更改时更新 DOM 等等。

例如,created可以使用钩子在创建实例时运行一段代码。

⚠️ 注意,到目前为止,我还没有在任何示例中使用箭头函数。这是因为如果使用它们,您将失去对组件上下文 或 的访问权限。如果您碰巧遇到this这样的错误,那是因为您使用了箭头函数。Uncaught TypeError: Cannot read property of undefinedUncaught TypeError: this.myMethod is not a function

您可以在官方文档中查看可用钩子的完整列表

Vue 组件

正如你之前所见,Vue允许你定义组件并复用它们,就像 React 一样。然而,你应该知道,所有这些都是Vue本身的可复用实例。

可以使用Vuecomponent的方法来定义一个组件:

Vue.component('my-name', { /* options */ })
Enter fullscreen mode Exit fullscreen mode

由于每个组件都是Vue的一个实例,因此您可以使用除 之外的所有上述属性el

第一个参数是组件的名称,您将在模板中使用该名称将此组件添加到页面。

请参阅W3C 规则,了解应使用什么命名结构来防止与当前和未来的 HTML 元素发生冲突。

当您使用方法时,您正在创建全局组件,它可以在任何根VueVue.component实例的模板中使用

本地组件

有时,出于隔离的目的,你希望某个组件只能在应用程序的某个特定区域内访问。在这种情况下,你可以使用本地组件:

var ComponentA = { /* `... */ }`
Enter fullscreen mode Exit fullscreen mode

进而:

new Vue({
  el: '#app',
  components: {
    'component-a': ComponentA
  }
})
Enter fullscreen mode Exit fullscreen mode

您可以拥有任意数量的本地组件。每个属性的键是组件的名称,值是该组件的选项对象。

💡 本地组件在子组件中不可用。但你可以通过显式地将它们添加到子组件中来使其可用。

如果您想让本地组件在子组件中可用,只需明确添加它们:

var ComponentA = { /* `... */ }`

var ComponentB = {
  components: {
    'component-a': ComponentA
  },
  // ...
}
Enter fullscreen mode Exit fullscreen mode

道具

与其他框架一样,Vue支持将 props 传递给组件,以实现从父级到子级的单向通信。

Vue.component('search', {
  // camelCase in JavaScript
  props: ['searchTerm'],
  template: `
    <span>{{ searchTerm }}</span>
    <div>
      ...
    </div>
  `
})
Enter fullscreen mode Exit fullscreen mode
<search search-term="javascript"></search>
Enter fullscreen mode Exit fullscreen mode

请注意,HTML 属性不区分大小写,浏览器会将任何大写字母视为小写字母。因此,如果您使用驼峰命名的 prop 名称,则需要像上面一样使用相应的短横线命名。

您还可以传递多个道具:

props: ['searchTerm', 'filter', 'sortOrder']
Enter fullscreen mode Exit fullscreen mode

如果您使用的是 TypeScript,您可能需要定义每个 prop 的类型,在这种情况下,您可以使用对象而不是数组,其中键是 prop 名称,值是类型:

props: {
  searchTerm: String,
  filter: Number,
  sortOrder: Boolean,
}
Enter fullscreen mode Exit fullscreen mode

您可以使用非原始类型,例如Array,,,,ObjectFunctionPromise

单文件组件

好了,现在来看看什么是单文件组件。正如我之前提到的,它们包含组件所需的一切:

// component.vue

<template>
  <p>{{ greeting }} World!</p>
</template>

<script>
module.exports = {
  data: function () {
    return {
      greeting: 'Hello'
    }
  }
}
</script>

<style scoped>
p {
  font-size: 2em;
  text-align: center;
}
</style>
Enter fullscreen mode Exit fullscreen mode

使用单文件组件最重要的好处是:

  • 完整的语法高亮(你需要一个类似VeturVS Code 的扩展)
  • CommonJS 模块,这意味着您可以使用以下方式将您的组件导入到其他组件中require
  • 组件范围的 CSS

您还可以将 ES6 模块与 一起使用Bug,并且Babel可以使用 CLI 进行设置:

<template>
  <p>{{ greeting }} World!</p>
</template>


<script>
import OtherComponent from './OtherComponent.vue'
export default {
  components: {
    OtherComponent
  },
  data () {
    return {
      greeting: 'Hello'
    }
  }
}
</script>

<style scoped>
p {
  font-size: 2em;
  text-align: center;
}
</style>
Enter fullscreen mode Exit fullscreen mode

模板

到目前为止,我们刚刚介绍了Vue实例和组件。但任何组件最重要的部分之一是它的模板。Vue使用类似于 Angular 语法的插值进行数据绑定。

<p>Message: {{ msg }}</p>
Enter fullscreen mode Exit fullscreen mode

msg对象变量的值data在运行时被替换。

如果您只想执行一次插值,请使用v-once指令(我们将很快回顾指令):

<p v-once>Message: {{ msg }}</p>
Enter fullscreen mode Exit fullscreen mode

在这种情况下,如果您更改后者的值msg,模板将不会改变。

原始 HTML

如果你想渲染原始 HTML,你可能知道,出于安全原因,不建议在常规插值中使用它。在 Angular 中,你可以使用innerHTML属性,并使用 管道将其固定DomSanitizer。在 React 中,你可以使用<div dangerouslySetInnerHTML={createMarkup()} />。在Vuev-html中,使用指令非常简单:

<p>Using v-html directive: <span v-html="rawHtml"></span></p>
Enter fullscreen mode Exit fullscreen mode

属性

您不能在 HTML 属性中使用插值,而是需要使用v-bind指令:

<div v-bind:name="dynamicName"></div>
Enter fullscreen mode Exit fullscreen mode

💡 如果您使用v-bind布尔属性,例如disabledv-bind则当值为、或时将不包括nullundefined属性false

JS 表达式

您可以在数据绑定中使用表达式:

<div>{{ number + 1 }}</div>

<div>{{ ok ? 'YES' : 'NO' }}</div>

<div>{{ message.split('').reverse().join('') }}</div>

<div v-bind:id="'list-' + id"></div>
Enter fullscreen mode Exit fullscreen mode

正如我之前提到的,不要在模板中使用太多逻辑,而是使用方法或计算属性。

指令

到目前为止,我们已经了解了几个指令,但Vue提供的指令远不止这些。指令以 开头v-,但一些最常用的指令也有缩写形式,就像@click我们之前看到的那样。几乎所有指令的值都应该是一个JavaScript 表达式,除了v-for

<p v-if="error">📛 Something horrible happened!</p>
Enter fullscreen mode Exit fullscreen mode

参数

一些指令带有参数,这些参数在名称后使用冒号:

<a v-bind:href="url"> ... </a>
Enter fullscreen mode Exit fullscreen mode

你甚至可以使用动态表达式作为指令的参数。但此功能在v2.6.0中才引入。

<a v-bind:[attributeName]="url"> ... </a>
Enter fullscreen mode Exit fullscreen mode

修饰符

修饰符是位于指令名称之后的后缀,以分隔。

<form v-on:submit.prevent="onSubmit"> ... </form>
Enter fullscreen mode Exit fullscreen mode

在上面的代码片段中,.prevent是一个修饰符,将preventDefault()在提交事件时被调用。

CSS 类和样式绑定

在某些情况下,你需要操作 HTML 元素的 class 列表,或者为其添加一些内联样式。你可以使用v-bind来实现。

<div v-bind:class="{ active: isActive }"></div>
Enter fullscreen mode Exit fullscreen mode

您还可以同时添加多个课程:

<div
  class="message"
  v-bind:class="{ active: isActive, 'text-danger': hasError }">
</div>
Enter fullscreen mode Exit fullscreen mode

您可以使用对象而不是使用内联表达式:

<div v-bind:class="classObject"></div>
Enter fullscreen mode Exit fullscreen mode

和:

data: {
  classObject: {
    active: true,
    'text-danger': false
  }
}
Enter fullscreen mode Exit fullscreen mode

对于内联样式,可以使用类似的方法,但不是使用类,而是使用样式:

<div v-bind:style="{ color: activeColor, fontSize: fontSize + 'px' }"></div>
Enter fullscreen mode Exit fullscreen mode

您也可以像前面的示例一样使用对象。

条件渲染

我们v-if在前面的一个例子中使用过。只有当表达式返回真值时,HTML 块才会被渲染:

<h1 v-if="awesome">Vue is awesome!</h1>
Enter fullscreen mode Exit fullscreen mode

但更重要的是,您可以使用 else 块v-else

<h1 v-if="awesome">Vue is awesome!</h1>
<h1 v-else>Oh no 😢</h1>
Enter fullscreen mode Exit fullscreen mode

如果要在多个未嵌套的元素上使用 v-if,可以使用templateelement:

<template v-if="ok">
  <h1>Title</h1>
  <p>Paragraph 1</p>
  <p>Paragraph 2</p>
</template>
Enter fullscreen mode Exit fullscreen mode

从 2.1.0+ 版本开始,您可以使用v-else-if指令来更改几个条件:

<div v-if="type === 'A'">
  A
</div>
<div v-else-if="type === 'B'">
  B
</div>
<div v-else-if="type === 'C'">
  C
</div>
<div v-else>
  Not A/B/C
</div>
Enter fullscreen mode Exit fullscreen mode

v-if并不是Vuev-show中唯一的条件指令,你也可以使用:

<h1 v-show="ok">Hello!</h1>
Enter fullscreen mode Exit fullscreen mode

区别在于它们的 Angular 对应部分完全相同,v-show将始终呈现元素并使用display属性。

输入绑定

您可以使用v-model输入、文本区域或选择元素创建双向数据绑定:

<input v-model="message" placeholder="edit me">
Enter fullscreen mode Exit fullscreen mode

为了textarea能够使用正常插值,您必须使用v-model

❌这行不通:

<textarea>{{text}}</textarea>
Enter fullscreen mode Exit fullscreen mode

✔️ 相反:

<textarea v-model="message" placeholder="add multiple lines"></textarea>
Enter fullscreen mode Exit fullscreen mode

请注意,这将忽略元素上可能添加的v-model初始valuechecked和属性。因此,请使用数据对象上的属性来初始化它们。selected

<input type="checkbox" id="checkbox" v-model="checked">
Enter fullscreen mode Exit fullscreen mode

和:

//...
data: {
  checked: true
}
Enter fullscreen mode Exit fullscreen mode

对于多个复选框,您可以使用数组:

<div id='example-3'>
  <input type="checkbox" id="jack" value="Jack" v-model="checkedNames">
  <label for="jack">Jack</label>
  <input type="checkbox" id="john" value="John" v-model="checkedNames">
  <label for="john">John</label>
  <input type="checkbox" id="mike" value="Mike" v-model="checkedNames">
  <label for="mike">Mike</label>
  <br>
  <span>Checked names: {{ checkedNames }}</span>
</div>
Enter fullscreen mode Exit fullscreen mode

和:

new Vue({
  el: '#example-3',
  data: {
    checkedNames: []
  }
})
Enter fullscreen mode Exit fullscreen mode

对于选择,您可以使用单个属性(单选)或数组(多选)。

<select v-model="selected">
  <option disabled value="">Please select one</option>
  <option>A</option>
  <option>B</option>
  <option>C</option>
</select>
Enter fullscreen mode Exit fullscreen mode

对于数组:

<select v-model="selected" multiple>
  <option>A</option>
  <option>B</option>
  <option>C</option>
</select>
Enter fullscreen mode Exit fullscreen mode

和:

//...
data: {
  selected: []
}
Enter fullscreen mode Exit fullscreen mode

最后,v-for如果您想呈现自定义选项,可以使用。

<select v-model="selected">
  <option v-for="option in options" v-bind:value="option.value">
    {{ option.text }}
  </option>
</select>
Enter fullscreen mode Exit fullscreen mode

渲染列表

你可以使用v-for指令来渲染元素列表。其语法如下:item in itemsitems 是一个数组,item 是数组中每个元素的别名:

<ul class="navbar">
  <li v-for="item in items">
    <a v-bind:href="item.href" >{{item.title}}</a>
  </li>
</ul>
Enter fullscreen mode Exit fullscreen mode

您可以使用以下方式通过对象属性进行事件循环v-for

<ul id="v-for-object" class="demo">
  <li v-for="value in object">
    {{ value }}
  </li>
</ul>
Enter fullscreen mode Exit fullscreen mode

在你的组件中:

new Vue({
  el: '#v-for-object',
  data: {
    object: {
      title: 'How to do lists in Vue',
      author: 'Jane Doe',
      publishedAt: '2016-04-10'
    }
  }
})
Enter fullscreen mode Exit fullscreen mode

💡 Vue处理列表更新的方式有所不同。当数组更新时,Vue使用就地更新的方法。这意味着Vue不会移动 DOM 节点,而是会更新列表项以反映应渲染的内容。因此,如果您依赖表单输入值或子组件状态,则需要使用v-bind:key类似于trackByAngular 中的方法提供唯一键。

事件处理

既然我们已经了解了指令的用法,现在是时候讨论事件处理了。这是本介绍的最后一部分😉。

您可以使用它v-on来处理元素上发生的事件。

<button v-on:click="counter += 1">Add 1</button>
Enter fullscreen mode Exit fullscreen mode

您还可以使用方法来处理事件:

<button v-on:click="greet">Greet</button>
Enter fullscreen mode Exit fullscreen mode

和:

methods: {
  greet: function (event) {
    // `this` inside methods points to the Vue instance
    alert('Hello ' + this.name + '!')
    // `event` is the native DOM event
    if (event) {
      alert(event.target.tagName)
    }
  }
}
Enter fullscreen mode Exit fullscreen mode

如果需要访问原始事件,只需使用$event并将其传递给方法:

<button v-on:click="warn('Form cannot be submitted yet.', $event)">
  Submit
</button>
Enter fullscreen mode Exit fullscreen mode

和:

// ...
methods: {
  warn: function (message, event) {
    // now we have access to the native event
    if (event) event.preventDefault()
    alert(message)
  }
}
Enter fullscreen mode Exit fullscreen mode

我之前简单提过修饰符。以下是你可以使用的修饰符列表:

  • .stop
  • .prevent
  • .capture
  • .self
  • .once
  • .passive

但这超出了本文的介绍范围。您可以在这里找到更多信息

概括

这就是你开始使用Vue所需了解的全部内容。实际内容远不止我在这里提到的,但我相信你应该从小处着手,逐步深入到更高级的场景。我保证稍后会讲解一些高级主题,例如路由器、状态管理、表单处理、动画等等,敬请期待。

文章来源:https://dev.to/yashints/a-compressive-intro-to-vue-js-366j
PREV
我如何制作这个逼真的红色开关(纯 CSS)
NEXT
像 NASA 一样编码的 10 条规则(适用于解释型语言)