VUE基础

本文深入解析Vue框架的核心概念,如MVVM模式、组件化、数据驱动等,对比Vue与React的特点,阐述Vue的生命周期、指令、计算属性及组件通信机制,帮助开发者掌握Vue的高效应用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Vue  是一套用于构建用户界面的渐进式框架。与其它大型框架不同的是,Vue 被设计为可以自底向上逐层应用。

MVVM模式:面向数据进行开发,主要目的是分离视图(View)和模型(Model)

  • 模型

  • 模型是指代表真实状态内容的领域模型(面向对象),或指代表内容的数据访问层(以数据为中心)。

  • 视图

  • 就像在MVCMVP模式中一样,视图是用户在屏幕上看到的结构、布局和外观(UI)。

  • 视图模型

  • 视图模型是暴露公共属性和命令的视图的抽象。MVVM没有MVC模式的控制器,也没有MVP模式的presenter,有的是一个绑定器。在视图模型中,绑定器在视图和数据绑定器之间进行通信。

核心思想:

1.数据驱动

2.组件化

Vue和React框架对比:

Vue:                                                                          React:

1.模版和渲染函数的弹性选择                                 1.更适用于大型应用和更好的可测试性

2.简单的语法及项目构建                                         2.同时适用于Web端和原生App

3.更快的渲染速度和更小的体积                             3.更大的生态圈带来更多的支持和工具

 

相同点:

1.利用虚拟DOM实现快速渲染

2.轻量级

3.响应式组件

4.服务端渲染

5.易于集成路由工具,打包工具以及状态管理工具

生命周期:

每个Vue实例创建时,都会经历一系列的初始化过程,同时也会调用相应的生命周期钩子,可以利用这些钩子,在合适的时机执行我们的业务逻辑。

created:实例创建完成后调用,此阶段完成了数据的观测等,但尚未挂载,$el还不可用。需要初始化处理一些数据时会比较有用。

mounted:el挂载到实例上后调用,一般我们的第一个业务逻辑会在这里开始。

beforeDestroy:实例销毁之前调用。主要解绑一些使用addEvenListener监听的事件等。

这些钩子与el、data相似,也是作为选项写入Vue实例内,并且钩子的this指向的是调用它的Vue实例

插值与表达式:

使用双大括号"{{}}"是最基本的文本插值方法,它会自动将我们双向绑定的数据实时显示出来

 

VUE指令:

指令的主要职责就是当其表达式的值改变时,相应的将某些行为应用到DOM上。

v-bind指令的基本用途是动态更新HTML元素上的属性,比如id,class等

v-on指令用来绑定事件监听器,做一些交互


计算属性:computed

对于任何复杂的逻辑,都应用到计算属性,在一个计算属性里可以完成各种复杂的逻辑,包括运算、函数调用等,只要最终返回一个结果就可以。

计算属性经常用于动态地设置元素的样式名称class和内联样式style,当使用组件时,计算属性也经常用来动态传递props。

我们可以将同一函数定义为一个方法而不是一个计算属性。两种方式的最终结果确实是完全相同的。然而,不同的是计算属性是基于它们的依赖进行缓存的。需要缓存时使用计算属性,避免重复遍历。不需要时可以使用方法。

 

v-bind及class与style绑定:

绑定class的几种方式:

对象语法、数组语法

 

 

侦听属性:watch

用来观察和响应Vue实例上的数据变动,使用 watch 选项允许我们执行异步操作 (访问一个 API),限制我们执行该操作的频率,并在我们得到最终结果前,设置中间状态。这些都是计算属性无法做到的。

 

 

 

条件渲染:

v-if vs v-show

v-if 是“真正”的条件渲染,因为它会确保在切换过程中条件块内的事件监听器和子组件适当地被销毁和重建。

v-if 也是惰性的:如果在初始渲染时条件为假,则什么也不做——直到条件第一次变为真时,才会开始渲染条件块。

相比之下,v-show 就简单得多——不管初始条件是什么,元素总是会被渲染,并且只是简单地基于 CSS 进行切换。

一般来说,v-if 有更高的切换开销,而 v-show 有更高的初始渲染开销。因此,如果需要非常频繁地切换,则使用 v-show 较好;如果在运行时条件很少改变,则使用 v-if 较好。

 

<template>标签://v-show不能用在template标签上

因为 v-if 是一个指令,所以必须将它添加到一个元素上。但是如果想切换多个元素呢?此时可以把一个 <template> 元素当做不可见的包裹元素,并在上面使用 v-if。最终的渲染结果将不包含 <template> 元素。

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

 

Vue 包含一组观察数组的变异方法,所以它们也将会触发视图更新。这些方法如下:

  • push()
  • pop()
  • shift()
  • unshift()
  • splice()
  • sort()
  • reverse()

 

V-model:

V-model指令在表单<input>、<textarea>以及<select>元素上创建双向数据绑定

事件处理:

事件修饰符

在事件处理程序中调用 event.preventDefault() 或 event.stopPropagation() 是非常常见的需求。尽管我们可以在方法中轻松实现这点,但更好的方式是:方法只有纯粹的数据逻辑,而不是去处理 DOM 事件细节。

为了解决这个问题,Vue.js 为 v-on 提供了事件修饰符。之前提过,修饰符是由点开头的指令后缀来表示的。

  • .stop

  • .prevent

  • .capture

  • .self

  • .once

  • .passive

<!-- 阻止单击事件继续传播 -->
<a v-on:click.stop="doThis"></a>

<!-- 提交事件不再重载页面 -->
<form v-on:submit.prevent="onSubmit"></form>

<!-- 修饰符可以串联 -->
<a v-on:click.stop.prevent="doThat"></a>

<!-- 只有修饰符 -->
<form v-on:submit.prevent></form>

<!-- 添加事件监听器时使用事件捕获模式 -->
<!-- 即元素自身触发的事件先在此处理,然后才交由内部元素进行处理 -->
<div v-on:click.capture="doThis">...</div>

<!-- 只当在 event.target 是当前元素自身时触发处理函数 -->
<!-- 即事件不是从内部元素触发的 -->
<div v-on:click.self="doThat">...</div>

 

表单输入绑定:

可以用v-model指令在表单<input> <textarea> <select>元素上创建双向数据绑定, v-model负责监听用户的输入事件以更新数据

 

  Vue组件:

Vue.js的组件就是提高重用性的,让代码可以复用。

一个组件本质上是一个拥有预定义选项的一个Vue实例。在Vue中注册组件很简单:

//定义名为:todo-item的新组件

Vue.component('todo-item',{

   template:"<li>这是个待办项</li>"

})

用它来构建一个组件模板:

<ol>

<todo-item>  </todo-item>

</ol>

 

每一个组件都是可以重复使用的vue实例。

组件的data必须是函数,然后将数据return出去。因此每一个实例都可以维护一份被返回对象的独立的拷贝:

data: function () {

  return {

  count: 0

}

}

组件的注册分为全局注册和局部注册:

通过Vue.component全局注册,全局注册的组件可以用在其被注册之后的任何 (通过 new Vue) 新创建的 Vue 根实例,也包括其组件树中的所有子组件的模板中。

全局注册往往是不够理想的。比如,如果你使用一个像 webpack 这样的构建系统,全局注册所有的组件意味着即便你已经不再使用一个组件了,它仍然会被包含在你最终的构建结果中。这造成了用户下载的 JavaScript 的无谓的增加。

在这些情况下,你可以通过一个普通的 JavaScript 对象来定义组件:

var ComponentA = { /* ... */ }
var ComponentB = { /* ... */ }
var ComponentC = { /* ... */ }

然后在实例的 components 选项中定义你想要使用的组件:

new Vue({
  el: '#app',
  components: {
    'component-a': ComponentA,
    'component-b': ComponentB
  }
})

 

  注意局部注册的组件在其子组件中不可用

 

 

父组件通过Props向子组件传递数据:

在组件中,使用选项props来声明需要从父级接收的数据,props的值可以是两种,一种是字符串数组,一种是对象。

 

props中声明的数据与组件data函数return的数据主要区别就是props的来自父级,而data中的是组件自己的数据,作用域是组件本身。

 

有时候,传递的数据并不是直接写死的,而是来自父级的动态数据,这时可以使用指令v-bind来动态绑定props的值,当父组件的数据变化时,也会传递给子组件。

 

因为javascript中对象和数组是引用类型,指向同一个内存空间,所以当props是对象和数组时,在子组件内改变是会影响父组件的

 

 一个组件默认可以拥有任意数量的Prop,任何值都可以传递给任何Prop

 

业务中经常会遇到两种需要改变prop的情况。

一种是父组件传递初始值进来,子组件将它作为初始值保存起来,在自己的作用域下可以随意使用和修改,这种情况可以在组件data内再声明一个数据,引用父组件的prop,代码如下:

 

组件中声明了数据count,它在组件初始化时会获取来自父组件的initCount,之后就与之无关了,只用维护count,这样就可以避免直接操作initCount。

 

另一种情况就是prop作为需要被转变的原始值传入,这种情况用计算属性就可以,代码如下:

 

数据验证:

当组件需要提供给别人使用时,推荐进行数据验证,比如某个数据必须是数字类型,如果传入字符串,就会在控制台弹出警告。

当prop验证失败时,在开发版本下会在控制台抛出一条警告

 

组件通信:

父组件通过props向子组件传递数据,子组件通过$emit自定义事件向父组件传递数据

 

自定义事件:子组件用$emit()来触发事件,父组件用$on()来监听子组件的事件

 

props传递数据、events触发事件和slot内容分发构成了Vue组件的3个API来源,再复杂的组件也是由这三部分构成的。

 

非父子组件间传值(Bus/总线/观察者模式):

在生成Vue实例前,给Vue的原型上添加一个bus属性,这个属性是Vue的实例,之后创建的Vue实例都具有Bus这个属性

通过Bus向外触发事件

通过钩子函数监听事件:

 

父链:

在子组件中,使用this.$parent可以直接访问该组件的父实例或组件。父组件中也可以通过$this.children访问它所有的子组件

 

如何使用插槽:

使用slot分发内容:

什么是slot:

{{message}}就是一个slot

 

slot的用法:

 

单个slot:在子组件内使用特殊的<slot>元素就可以为这个子组件开启一个slot(插槽),在父组件模板里,插入在子组件标签内的所有内容都将替代子组件的<slot>标签及它的内容,代码如下:

 

具名slot:

给<slot>元素指定一个name后可以分发多个内容,具名Slot可以与单个Slot共存,例如:

 

作用域插槽:

作用域插槽的使用场景就是既可以复用子组件的slot,又可以使slot内容不一致。

 

 

 

动态组件:

Vue.js提供了一个特殊的元素<component>用来动态挂载不同的组件,使用is特性来选择要挂载的组件

<keep alive>包裹动态组件时,会缓存不活动的组件实例

 

异步更新队列:

$nextTick就是用来知道什么时候DOM更新完成的

 

 

自定义指令:

自定义指令的注册方法和组件很像,也分局部注册和全局注册,比如注册一个v-focus的指令

自定义指令的选项是由几个钩子函数组成的,每个都是可选的:

bind:只调用一次,指令第一次绑定到元素时调用,用这个钩子函数可以定义一个在绑定时执行一次的初始化动作

inserted:被绑定元素插入父节点时调用(父节点存在即可调用,不必存在于document中)

update:被绑定元素所在的模板更新时调用,而不论绑定值是否变化,通过比较更新前后的绑定值,可以忽略不必要的模块更新

componentUpdated:被绑定元素所在模板完成一次更新周期时调用

unbind:只调用一次,指令与元素解绑时调用

 

 

访问元素&组件:

访问根实例:

 

访问子组件实例或子元素:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值