vue2与vue3的差异
- 响应式系统的差异:
- Vue 2 使用
Object.defineProperty
实现响应式系统,而 Vue 3 使用了 Proxy。
- 在 Vue 2 中,对于数组的响应式处理有一些限制,比如不能检测数组索引和长度的变化,而 Vue 3 中这些问题得到了解决。
- 组件和API的变化:
- Vue 2 中的组件选项(如
data
, methods
, computed
等)与 Vue 3 中可能有所不同,特别是在组合式 API(Composition API)的引入上。
- Vue 3 引入了
setup
函数和响应式引用(ref
, reactive
),这在 Vue 2 中是没有的。
- 生命周期钩子的变化:
- Vue 3 中引入了一些新的生命周期钩子,如
beforeUnmount
和 unmounted
,它们在 Vue 2 中分别对应 beforeDestroy
和 destroyed
。
- 模板和JSX的变更:
- Vue 3 支持更多编译时优化,模板的写法也更加灵活,例如
v-model
可以用在多个参数上。
- Vue 3 的 JSX 写法也有所不同,特别是在使用
setup
函数时。
- 全局API和配置:
- Vue 2 中的一些全局 API 和配置(如
Vue.filter
, Vue.mixin
)在 Vue 3 中被移除或改为使用应用实例上的 API。
在学习 Vue 2 时可以重点掌握的内容:
- Vue 2 的响应式原理:理解
Object.defineProperty
如何工作,以及如何追踪依赖和触发更新。
- Vue 2 的选项式 API:深入理解
data
, props
, computed
, methods
, watch
, lifecycle hooks
等组件选项的使用。
- Vue 2 的指令:熟悉
v-if
, v-for
, v-bind
, v-model
, v-on
等指令的用法和原理。
- Vue 2 的组件系统:学习组件的注册、组件间的通信(props, events, slots, provide/inject)。
- Vue 2 的路由和状态管理:了解 Vue Router 和 Vuex 在 Vue 2 中的使用方式。
- Vue 2 的性能优化:学习如何优化 Vue 2 应用的性能,比如使用
v-once
, v-memo
, Object.freeze
等。
- Vue 2 的构建工具:熟悉 Vue CLI 和其插件系统,以及如何配置 Vue 2 项目。
创建项目
- 通过npm安装Vue CLI(基于webpack):
npm install -g @vue/cli
。
- 创建一个新项目:
vue create project-name
。
通过cdn引入vue2的方法:
| |
| <script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script> |
| |
| <script src="https://cdn.jsdelivr.net/npm/vue@2"></script> |
声明式渲染
| <div id="app"> |
| {{ message }} |
| </div> |
| |
| var app = new Vue({ |
| el: '#app', |
| data: { |
| message: 'Hello Vue!' |
| } |
| }) |
响应式系统
| |
| var data = { a: 1 } |
| |
| |
| var vm = new Vue({ |
| data: data |
| }) |
| |
| |
| |
| vm.a == data.a |
| |
| |
| vm.a = 2 |
| data.a |
| |
| |
| data.a = 3 |
| vm.a |
| |
| |
| vm.b = 'hi' |
| |
| |
| Object.freeze(obj) |
模板语法
插值与绑定指令
- 原始HTML
双大括号会将数据解释为普通文本,而非 HTML 代码。
为了输出真正的 HTML,需要使用 v-html
指令:
| // rawHtml: "<span style="color: red;">This should be red.</span>" |
| // 动态渲染的任意 HTML 可能会非常危险,因为它很容易导致 XSS 攻击 |
| <p>Using mustaches: {{ rawHtml }}</p> |
| <p>Using v-html directive: <span v-html="rawHtml"></span></p> |
| <button v-bind:disabled="isButtonDisabled">Button</button> |
| <a v-bind:[attributeName]="url"> ... </a> |
| // data property attributeName,其值为 "href" |
| // 那么这个绑定将等价于 v-bind:href |
| <a v-on:[eventName]="doSomething"> ... </a> |
| |
| |
| |
| |
| |
| |
| <a v-bind:[someAttr]="value"> ... </a> |
| |
| <div |
| class="static" |
| v-bind:class="{ active: isActive, 'text-danger': hasError }" |
| ></div> |
| data: { |
| isActive: true, |
| hasError: false |
| } |
计算属性
| |
| |
| computed: { |
| now: function () { |
| return Date.now() |
| } |
| } |
| computed: { |
| fullName: { |
| get: function () { |
| return this.firstName + ' ' + this.lastName |
| }, |
| |
| set: function (newValue) { |
| var names = newValue.split(' ') |
| this.firstName = names[0] |
| this.lastName = names[names.length - 1] |
| } |
| } |
| } |
key属性
| |
| |
| <template v-if="loginType === 'username'"> |
| <label>Username</label> |
| <input placeholder="Enter your username"> |
| </template> |
| <template v-else> |
| <label>Email</label> |
| <input placeholder="Enter your email address"> |
| </template> |
| |
| |
| |
| <template v-if="loginType === 'username'"> |
| <label>Username</label> |
| <input placeholder="Enter your username" key="username-input"> |
| </template> |
| <template v-else> |
| <label>Email</label> |
| <input placeholder="Enter your email address" key="email-input"> |
| </template> |
| |
条件渲染
v-show
不支持 <template>
元素,也不支持 v-else
。
v-if
有更高的切换开销,而 v-show
有更高的初始渲染开销。
列表渲染
-
数组更新: 包裹(变异方法)能够触发视图的更新
push()
/ pop()
/shift()
/unshift()
/splice()
/sort()
/reverse()
-
对象更新:
this.$set(this.obj, 'newProp', 'New Value');
this.obj = { ...this.obj, newProp: 'New Value' };
-
数组替换: 不会变更原始数组,而总是返回一个新数组
filter()
、concat()
和 slice()
| example1.items = example1.items.filter(function (item) { |
| return item.message.match(/Foo/) |
| }) |
事件处理
| <div id="example-1"> |
| <button v-on:click="counter += 1">Add 1</button> |
| <p>The button above has been clicked {{ counter }} times.</p> |
| </div> |
表单输入绑定
修饰符:
.lazy
: 在“change”时而非“input”时更新
<input v-model.lazy="msg">
.number
: 自动将用户的输入值转为数值类型
<input v-model.number="age" type="number">
.trim
: 自动过滤用户输入的首尾空白字符
<input v-model.trim="msg">
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通