Vue万字学习笔记(入门1)

目录

简介

Vue是什么

渐进式框架

单文件组件

API 风格​

选项式 API (Options API)​

组合式 API (Composition API)​

创建一个 Vue 应用

挂载应用

DOM 中的根组件模板​

应用配置

多个应用实例​

模板语法​

文本插值​

原始 HTML​

Attribute 绑定​

简写​

同名简写 ​

布尔型 Attribute

动态绑定多个值​

使用 JavaScript 表达式​

仅支持表达式​

受限的全局访问​

指令 Directives​

参数 Arguments​

动态参数​

动态参数值的限制​

动态参数语法的限制​

修饰符 Modifiers​


简介

(我们这里统一使用的是组合式)

Vue是什么

我们使用的是Vue3

Vue是一款用于构建用户界面的 (JS)JavaScript 框架。它基于标准 HTML、CSS 和 JavaScript 构建,并提供了一套声明式的、组件化的编程模型。

下面是一个基本的例子,这个写法非常的基础,createApp{}被绑定到mount('#app')这个div上

import { createApp, ref } from 'vue'

createApp({
  setup() {
    return {
      count: ref(0)
    }
  }
}).mount('#app')

当button被点击(click)时,我们执行count++,两个button之间是我们的插值表达式(在页面上显示count的值。‌当count的值发生变化时,‌这个表达式会自动更新以显示最新的值)。

<div id="app">
  <button @click="count++">
    Count is: {{ count }}
  </button>
</div>

结果展示:

点击数字会+1。

我们这里的count(html里的)是从上面的JS的count获取的,如果我们在JS里修改count的值,对应HTML里显示的count也会发生变化,他们两个数据是绑定好的。

上面的示例展示了 Vue 的两个核心功能:

  • 声明式渲染:Vue 基于标准 HTML 拓展了一套模板语法(如在html里的@click和{}都是模版),使得我们可以声明式地描述最终输出的 HTML 和 JavaScript 状态之间的关系。

  • 响应性:Vue 会自动跟踪 JavaScript 状态并在其发生变化时响应式地更新 DOM。

渐进式框架

可以用不同的方式使用 Vue:

  • 无需构建步骤,渐进式增强静态的 HTML
  • 可以作为 Web Components 嵌入(在任何页面中)
  • 单页应用 (SPA)
  • 全栈 / 服务端渲染 (SSR)
  • Jamstack / 静态站点生成 (SSG)
  • 开发桌面端、移动端、WebGL,甚至是命令行终端中的界面

单文件组件

在大多数启用了构建工具的 Vue 项目中,我们可以使用一种类似 HTML 格式的文件来书写 Vue 组件,它被称为单文件组件 (也被称为.vue文件,英文 Single-File Components,缩写为 SFC)。顾名思义,Vue 的单文件组件会将一个组件的逻辑 (JavaScript),模板 (HTML) 和样式 (CSS) 封装在同一个文件里。下面我们将用单文件组件的格式重写上面的计数器示例:

<script setup>
import { ref } from 'vue'
const count = ref(0)
</script>

<template>
  <button @click="count++">Count is: {{ count }}</button>
</template>

<style scoped>
button {
  font-weight: bold;
}
</style>

这里就不用像上面一样进行绑定了(不用写createApp之类的了,只需要写里面的setup部分即可,这里我们换用了其他语句。< script setup >中的代码会在每次组件实例被创建的时候执行。顶层的绑定会被暴露给模板,在模版表达式中我们这里导入vue,ref值在模版中使用的时候会自动解包),直接写一个template模版里面就是我们要写的html的内容,下面的style是关于当前的样式。

如果你的用例需要进行构建,我们推荐用它来编写 Vue 组件。

API 风格

Vue 的组件可以按两种不同的风格书写:选项式 API 和组合式 API

选项式 API (Options API)

使用选项式 API,我们可以用包含多个选项的对象来描述组件的逻辑,例如data、method,这些都是不同的对象来描述逻辑,他们所定义的属性会暴露在函数内部的this上,指向当前第一个实例。

<script>
export default {
  // data() 返回的属性将会成为响应式的状态
  // 并且暴露在 `this` 上
  data() {
    return {
      count: 0
    }
  },

  // methods 是一些用来更改状态与触发更新的函数
  // 它们可以在模板中作为事件处理器绑定
  methods: {
    increment() {
      this.count++
    }
  },

  // 生命周期钩子会在组件生命周期的各个不同阶段被调用
  // 例如这个函数就会在组件挂载完成后被调用
  mounted() {
    console.log(`The initial count is ${this.count}.`)
  }
}
</script>

<template>
  <button @click="increment">Count is: {{ count }}</button>
</template>

展示结果:Count is:0

组合式 API (Composition API)

通过组合式 API,我们可以使用导入的 API 函数来描述组件逻辑。在单文件组件中,组合式 API 通常会与<script setup>搭配使用。这个setupattribute 是一个标识,在编译时进行一些处理,让我们可以更简洁地使用组合式 API。比如,<script setup> 中的导入和顶层变量/函数都能够在模板中直接使用。

下面是使用了组合式 API 与<script setup>改造后和上面的模板完全一样的组件:

<script setup>
import { ref, onMounted } from 'vue'

// 响应式状态
const count = ref(0)

// 用来修改状态、触发更新的函数
function increment() {
  count.value++
}

// 生命周期钩子
onMounted(() => {
  console.log(`The initial count is ${count.value}.`)
})
</script>

<template>
  <button @click="increment">Count is: {{ count }}</button>
</template>

两种 API 风格都能够覆盖大部分的应用场景。它们只是同一个底层系统所提供的两套不同的接口。意思就这两种API只是不同的表现形式,实际上底层都是Vue,选项式 API 是在组合式 API 的基础上实现的,关于 Vue 的基础概念和知识在它们之间都是通用的。

选项式 API 以“组件实例”的概念为中心,对于有面向对象语言背景的用户来说,这通常与基于类的心智模型更为一致,就是已经有类的想法了。同时,它将响应性相关的细节抽象出来,并强制按照选项来组织代码,从而对初学者而言更为友好。

组合式 API 的核心思想是直接在函数作用域内定义响应式状态变量,并将从多个函数中得到的状态组合起来处理复杂问题。这种形式更加自由,也需要你对 Vue 的响应式系统有更深的理解才能高效使用。相应的,它的灵活性也使得组织和重用逻辑的模式变得更加强大。

组合式的API带来了潜在收益。

  • 在学习的过程中,如果是Vue新手,我们建议学习时采用易于自己理解的风格即可,核心概念在两个风格之间是通用的。
  • 在生产项目中:当你不需要使用构建工具,或者打算主要在低复杂度的场景中使用 Vue,例如渐进增强的应用场景,推荐采用选项式 API;当你打算用 Vue 构建完整的单页应用,推荐采用组合式 API + 单文件组件。

创建一个 Vue 应用

每个 Vue 应用都是通过createApp函数创建一个新的 应用实例

import { createApp } from 'vue'

const app = createApp({
  /* 根组件选项 */
})

我们传入createApp的对象实际上是一个组件,每个应用都需要一个“根组件”,其他组件将作为其子组件。

如果你使用的是单文件组件,我们可以直接从另一个文件中导入根组件。

import { createApp } from 'vue'
// 从一个单文件组件中导入根组件
import App from './App.vue'

const app = createApp(App)

虽然许多示例只需要一个组件,但大多数真实的应用都是由一棵嵌套的、可重用的组件树组成的。例如,一个待办事项 (Todos) 应用的组件树可能是这样的:

App (root component)
├─ TodoList
│  └─ TodoItem
│     ├─ TodoDeleteButton
│     └─ TodoEditButton
└─ TodoFooter
   ├─ TodoClearButton
   └─ TodoStatistics

挂载应用

应用实例必须在调用了.mount()方法后才会渲染出来。该方法接收一个“容器”参数,可以是一个实际的 DOM 元素或是一个 CSS 选择器字符串:

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

这里根应用的内容会被渲染在容器元素里面。容器元素自己将不会被视为应用的一部分。

.mount方法应该始终在整个应用配置和资源注册完成后被调用。同时请注意,不同于其他资源注册方法,它的返回值是根组件实例而非应用实例。

DOM 中的根组件模板

根组件的模板通常是组件本身的一部分,但也可以直接通过在挂载容器内编写模板来单独提供:

<div id="app">
  <button @click="count++">{{ count }}</button>
</div>
import { createApp } from 'vue'

const app = createApp({
  data() {
    return {
      count: 0
    }
  }
})

app.mount('#app')

当根组件没有设置template选项时,Vue 将自动使用容器的innerHTML作为模板。

DOM 内模板通常用于无构建步骤的 Vue 应用程序。它们也可以与服务器端框架一起使用,其中根模板可能是由服务器动态生成的。

应用配置

应用会暴露一个.confid的对象,允许我们做一些应用级的选项配置如定义一个错误处理器

app.config.errorHandler = (err) => {
  /* 处理错误 */
}

还提供一些方法来注册应用范围内可用的资源,如注册组件。

app.component('TodoDeleteButton', TodoDeleteButton)

多个应用实例

应用实例并不只限于一个。允许你在同一个页面中创建多个共存的 Vue 应用,而且每个应用都拥有自己的用于配置和全局资源的作用域。

const app1 = createApp({
  /* ... */
})
app1.mount('#container-1')

const app2 = createApp({
  /* ... */
})
app2.mount('#container-2')

如果你正在使用 Vue 来增强服务端渲染 HTML,并且只想要 Vue 去控制一个大型页面中特殊的一小部分,应避免将一个单独的 Vue 应用实例挂载到整个页面上,而是应该创建多个小的应用实例,将它们分别挂载到所需的元素上去。(这种情况比较少,大部分情况下我们是将整个挂载都放进去)

模板语法

Vue 使用一种基于 HTML 的模板语法,使我们能够声明式地将其组件实例的数据绑定到呈现的 DOM 上。所有的 Vue 模板都是语法层面合法的 HTML,可以被符合规范的浏览器和 HTML 解析器解析。

在底层机制中,Vue 会将模板编译成高度优化的 JavaScript 代码。结合响应式系统,当应用状态变更时,Vue 能够智能地推导出需要重新渲染的组件的最少数量,并应用最少的 DOM 操作。

文本插值

最基本的数据绑定形式是文本插值,它使用的是“Mustache”语法 (即双大括号):

<span>Message: {{ msg }}</span>

双大括号标签会被替换为相应组件实例中msg属性的值。同时每次msg属性更改时它也会同步更新。

原始 HTML

双大括号会将数据解释为纯文本,而不是 HTML。若想插入 HTML,你需要使用v-html指令:

<p>Using text interpolation: {{ rawHtml }}</p>
<p>Using v-html directive: <span v-html="rawHtml"></span></p>

下面是运行后显示的对应效果:

Using text interpolation: <span style="color: red">This should be red.</span>

Using v-html directive: This should be red.

这里我们可以看到v-html是一个指令,由v-作为前缀的特殊attribute,表明了他是vue的一些特殊属性,它将为渲染的DOM应用特殊的响应式行为。这里我们做的事情简单来说就是:在当前组件实例上,将此元素的 innerHTML 与ranHtml属性保持同步,如果我们将表达式的值改变,因为两者同步,故影响将会响应式的作用于DOM。

<div id="app">
    <p v-html="rawHtml"></p>
</div>
 
<script>
    var vm=new Vue({
        el:'#app',
        data:{
            rawHtml:'<span style="color:red">this is should be red</span>'
        }
    });
</script>

运行结果:This should be red.

注意:网站上动态渲染任意HTML是危险的,容易造成XSS漏洞,请仅在内容安全可信时再使用v-html,并且永远不要使用用户提供的HTML内容。

指令:带有v-前缀的特殊attribute,有下面几个指令:

v-once:变量的值只变化一次。

<span v-once>{{msg}}</span>
<!--msg的值只会在Vue对象渲染时赋值,即时后面对msg的值进行改变,插值处的内容也不会更新。-->

v-bind:Attribute 绑定​

v-html:v-html="rawHTML"(rawHTML变量中可以写html原生代码)。
    指令需要加到某一个标签上,为这个指令赋予一个变量值的方式进行指令参数的传递。
 

v-on:指令用于监听DOM事件,可以绑定HTML元素所有的事件 

<a v-on:click="doSomething">...</a>
    参数click是监听的事件名

v-if:

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title>指令</title>
		<!-- 指令 (Directives) 是带有 v- 前缀的特殊 attribute。
		指令 attribute 的值预期是单个 JavaScript 表达式 (v-for 是例外情况,稍后我们再讨论)。
		指令的职责是,当表达式的值改变时,将其产生的连带影响,响应式地作用于 DOM。 -->
		<script src="vue.js" type="text/javascript"></script>
	</head>
	<body>
		<div id="app">
			<!-- p标签是否被渲染取决于seen的值 -->
			<p v-if="seen"> You can see me.</p>
			<a v-bind:href="url">vue教程</a>
			<!-- @click绑定一个点击事件 -->
			<div @click="click1">
				<div @click="click2">
					click me
				</div>
			</div>	
			<div @click="click3">
				<!-- stop是vue.js的修饰符,指当前click事件一旦执行完毕后就停止 -->
				<div @click.stop="click4">
					click me2
				</div>
			</div>
		</div>
		<span id="app2">
			{{meg}}
		</span>
	</body>
	<script type="text/javascript">
		var vm=new Vue({
			el:"#app",
			data:{
				seen:false,//设置seen值为false,p标签内的元素将不会被渲染
				url:"https://cn.vuejs.org/guide/introduction.html",
			},
			methods:{
				click1:function(){
					console.log("click1事件");
				},
				click2:function(){
					console.log("click2事件");
				},
				click3:function(){
					console.log("click3事件");
				},
				click4:function(){
					console.log("click4事件");
				}
			}
		});
		var vm2=new Vue({
			el:"#app2",
			data:{
				meg:"data2"
			}
		})
	</script>
</html>

这里我们因为v-if="seen"的seen的值为false,故无法被看到,后面的vue教程是使用的v-bind,在下面的url被赋值为一个网址,我们点击页面显示的vue教程字样会跳转进入url提供的网址,下面的click me点击之后会在控制台看到click2和click1,再点击click me2会在控制台显示click4,如下图所示:

Attribute 绑定

双大括号不能在 HTML attributes 中使用(就是不能在<div 这个里面使用>,只能在<>这里使用<>)。想要响应式地绑定一个 attribute,应该使用v-bind指令:

 语法:v-bind:属性=""

用法:v-bind:属性名=值
            :属性名=值
            :[属性名]=值

    <a v-bind:href="url">...</a>
    v-bind指令将该元素的href属性与表达式url的值绑定。

  响应式地更新HTML属性
    使用JavaScript表达式:表达式会在所属vue实例的数据作用域下作为JavaScript被解析。
    限制:每个绑定都只能包含单个表达式,流控制也不会生效。

例:v-bind的使用

<div id="app">
    <!-- 为v-bind绑定一个动态样式 -->
	<div v-bind:class="color">v-bind使用</div>
</div>
 
<script>
    var vm=new Vue({
        el:'#app',
        data:{
            color:"blue",
        }
    });
</script>

v-bind指令指示 Vue 将元素的class attribute 与组件的color属性保持一致。如果绑定的值是 null 或者 undefined,那么该 attribute 将会从渲染的元素上移除。

简写

因为v-bind非常常用,我们提供了特定的简写语法:

<div :class="color"></div>

开头为 : 的 attribute 可能和一般的 HTML attribute 看起来不太一样,但它的确是合法的 attribute 名称字符,并且所有支持 Vue 的浏览器都能正确解析它,不会出现在最终渲染的 DOM 中。简写语法是可选的,我们在实际开发中更经常使用简写的版本。

同名简写 

如果 attribute 的名称与绑定的 JavaScript 值的名称相同,那么可以进一步简化语法,省略 attribute 值:(注:只能在Vue3.4及以上版本使用)

<!-- 与 :id="id" 相同 -->
<div :id></div>

<!-- 这也同样有效 -->
<div v-bind:id></div>

布尔型 Attribute

布尔型attribute依据 true / false 值来决定 attribute 是否应该存在于该元素上。disabled就是最常见的例子之一。

v-bind在这种场景下的行为略有不同:

<button :disabled="isButtonDisabled">Button</button>

当 isButtonDisabled 为真值或一个空字符串 (即 <button disabled="">) 时,元素会包含这个 disabled attribute。而当其为其他假值时 attribute 将被忽略。

动态绑定多个值

如果你有像这样的一个包含多个 attribute 的 JavaScript 对象:

const objectOfAttrs = {
  id: 'container',
  class: 'wrapper',
  style: 'background-color:green'
}

通过不带参数的v-bind,你可以将它们绑定到单个元素上(意思是id、class、style都会被objectOfAttrs绑定):

<div v-bind="objectOfAttrs"></div>

使用 JavaScript 表达式

我们仅在模板中绑定了一些简单的属性名, Vue 实际上在所有的数据绑定中都支持完整的JavaScript 表达式:

它可以做加法、三元表达式、分割、反转、连接等都是可以的

{{ number + 1 }}

{{ ok ? 'YES' : 'NO' }}

{{ message.split('').reverse().join('') }}

<div :id="`list-${id}`"></div>
<!--双大括号不行这里,但是${}可以,我们可以取它的参数-->

这些表达式都会被作为 JavaScript ,以当前组件实例为作用域解析执行。

在 Vue 模板内,JavaScript 表达式可以被使用在如下场景上:

  • 在文本插值中 (双大括号)
  • 在任何 Vue 指令 (以v-开头的特殊 attribute) attribute 的值中

仅支持表达式

每个绑定仅支持单一表达式,也就是一段能够被求值的 JavaScript 代码。一个简单的判断方法是是否可以合法地写在 return 后面。

因此,下面的例子都是无效的:

<!-- 这是一个语句,而非表达式 -->
{{ var a = 1 }}

<!-- 仅支持三元表达式,条件控制也不行 -->
{{ if (ok) { return message } }}

但是如果说我们在表达式中使用另一个组件的方法

<time :title="toTitleDate(date)" :datetime="date">
  {{ formatDate(date) }}
</time>

比如这里的formateDate是另一个组件的方法,直接调用就可以了

绑定在表达式中的方法在组件每次更新时都会被重新调用,因此应该产生任何副作用,比如改变数据或触发异步操作。

受限的全局访问

模板中的表达式将被沙盒化,仅能够访问到有限的全局对象列表。该列表中会暴露常用的内置全局对象,比如 Math 和 Date

没有显式包含在列表中的全局对象是无法访问的,例如自己加到window上的一些属性,然而,我们可以在 app.config.globalProperties 里显式的添加它们,是通过在这个应用上加设置组件来绑定它的。

指令 Directives

指令是带有 v- 前缀的特殊 attribute。Vue 提供了许多内置指令,包括上面我们所介绍的v-bind和v-html。

指令 attribute 的期望值为一个 JavaScript 表达式 (除了少数几个例外,即之后要讨论到的v-forv-on 和 v-slot)。一个指令的任务是在其表达式的值变化时响应式地更新 DOM。以 v-if 为例:

<p v-if="seen">Now you see me</p>

这里v-if指令会基于seen表达式的值,如果是真就能够看到,如果是假,p元素就看不到。

参数 Arguments

某些指令会需要一个“参数”,在指令名后通过一个冒号隔开做标识。例如用v-bind指令后的href,我们通过这个属性来来更新、设置值,从而实现响应式地更新一个 HTML attribute:

<a v-bind:href="url"> ... </a>

<!-- 简写 -->
<a :href="url"> ... </a>

这里 href 就是一个参数,它告诉 v-bind 指令将表达式 url 的值绑定到元素的 href attribute 上。在简写中,参数前的一切 (例如 v-bind:) 都会被缩略为一个 : 字符。

另一个例子是 v-on 指令,它将监听 DOM 事件:

<a v-on:click="doSomething"> ... </a>

<!-- 简写 -->
<a @click="doSomething"> ... </a>

点击、鼠标触碰、空格的点击,或者某个字母的点击都是可以借助这个来实现。

简写用@代替v-on:。

动态参数

在指令参数上也可以使用一个 JavaScript 表达式,需要包含在一对方括号内,比如说:

<!--
注意,参数表达式有一些约束,
参见下面“动态参数值的限制”与“动态参数语法的限制”章节的解释
-->
<a v-bind:[attributeName]="url"> ... </a>

<!-- 简写 -->
<a :[attributeName]="url"> ... </a>

这里的attributeName是可以换的,而且在未赋值之前并不能确定。

这里的 attributeName 会作为一个 JavaScript 表达式被动态执行,计算得到的值会被用作最终的参数。如果说它的值为 "href",那么这个绑定就等价于 v-bind:href

还可以将一个函数绑定到动态的事件名称上:

<a v-on:[eventName]="doSomething"> ... </a>

<!-- 简写 -->
<a @[eventName]="doSomething"> ... </a>

当 eventName 的值是 "focus" 时,v-on:[eventName] 就等价于 v-on:focus

动态参数值的限制

动态参数中表达式的值应当是一个字符串,或者是 null。(这是限制)特殊值 null 意为显式移除该绑定。其他非字符串的值会触发警告。

动态参数语法的限制

动态参数表达式因为某些字符的缘故有一些语法限制,比如空格和引号,在 HTML attribute 名称中都是不合法的。例如下面的示例(中括号里空格和引号是会引发编译器警告的):

<!-- 这会触发一个编译器警告 -->
<a :['foo' + bar]="value"> ... </a>

如果你需要传入一个复杂的动态参数,我们推荐使用计算属性替换复杂的表达式,也是 Vue 最基础的概念之一,我们很快就会讲到。

当使用 DOM 内嵌模板 (直接写在 HTML 文件里的模板) 时,我们需要避免在名称中使用大写字母,因为浏览器会强制将其转换为小写:

<a :[someAttr]="value"> ... </a>

上面的例子将会在 DOM 内嵌模板中被转换为 :[someattr]。如果你的组件拥有 “someAttr” 属性而非 “someattr”,这段代码将不会工作。单文件组件内的模板受此限制。

修饰符 Modifiers

修饰符是以点开头的特殊后缀,表明指令需要以一些特殊的方式被绑定。例如 .prevent 修饰符会告知 v-on 指令对触发的事件调用 event.preventDefault()

<form @submit.prevent="onSubmit">...</form>

在这里你可以直观地看到完整的指令语法:

参考内容:Vue.js

  • 29
    点赞
  • 25
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值