Vue.js 是一个用于构建用户界面的渐进式 JavaScript 框架。它由尤雨溪于2014年发布,旨在通过简单的 API 提供高效的开发体验。Vue 的核心库专注于视图层,易于与其他库或现有项目集成。Vue 的设计理念是“渐进式”,意味着你可以根据项目的需求逐步引入 Vue 的功能。
Vue 的主要特点包括:
v-if
、v-for
、v-bind
等),用于简化 DOM 操作。Vue 的响应式系统是其核心特性之一。Vue 通过 Object.defineProperty
(Vue 2)或 Proxy
(Vue 3)来实现数据的响应式。当数据发生变化时,Vue 会自动更新依赖该数据的视图。
在 Vue 2 中,Vue 通过 Object.defineProperty
将对象的属性转换为 getter 和 setter。当访问属性时,Vue 会收集依赖;当属性发生变化时,Vue 会通知依赖进行更新。
// Vue 2 响应式实现示例 function defineReactive(obj, key, val) { Object.defineProperty(obj, key, { get() { console.log(`get ${key}: ${val}`); return val; }, set(newVal) { if (newVal !== val) { console.log(`set ${key}: ${newVal}`); val = newVal; } } }); } const data = {}; defineReactive(data, 'name', 'Vue'); data.name; // get name: Vue data.name = 'React'; // set name: React
在 Vue 3 中,Vue 使用 Proxy
来实现响应式。Proxy
可以拦截对象的多种操作,提供了更强大的功能。
// Vue 3 响应式实现示例 function reactive(obj) { return new Proxy(obj, { get(target, key) { console.log(`get ${key}: ${target[key]}`); return target[key]; }, set(target, key, value) { if (target[key] !== value) { console.log(`set ${key}: ${value}`); target[key] = value; } return true; } }); } const data = reactive({ name: 'Vue' }); data.name; // get name: Vue data.name = 'React'; // set name: React
Vue 的组件化是其另一个核心特性。组件是 Vue 应用的基本构建块,每个组件都有自己的模板、逻辑和样式。组件可以嵌套使用,形成复杂的 UI 结构。
在 Vue 中,组件可以通过 Vue.component
全局注册,也可以通过 components
选项局部注册。
// 全局组件 Vue.component('my-component', { template: '<div>My Component</div>' }); // 局部组件 const MyComponent = { template: '<div>My Component</div>' }; new Vue({ el: '#app', components: { 'my-component': MyComponent } });
组件之间的通信是 Vue 开发中的常见需求。Vue 提供了多种通信方式,包括 props、事件、$emit
、$parent
、$children
、$refs
等。
// 父组件 Vue.component('parent-component', { template: ` <div> <child-component :message="message" @update="handleUpdate"></child-component> </div> `, data() { return { message: 'Hello from parent' }; }, methods: { handleUpdate(newMessage) { this.message = newMessage; } } }); // 子组件 Vue.component('child-component', { props: ['message'], template: ` <div> <p>{{ message }}</p> <button @click="updateMessage">Update Message</button> </div> `, methods: { updateMessage() { this.$emit('update', 'Hello from child'); } } });
Vue 组件有一系列的生命周期钩子函数,允许开发者在组件的不同阶段执行自定义逻辑。常见的生命周期钩子包括 beforeCreate
、created
、beforeMount
、mounted
、beforeUpdate
、updated
、beforeDestroy
、destroyed
等。
Vue.component('my-component', { template: '<div>My Component</div>', beforeCreate() { console.log('beforeCreate'); }, created() { console.log('created'); }, beforeMount() { console.log('beforeMount'); }, mounted() { console.log('mounted'); }, beforeUpdate() { console.log('beforeUpdate'); }, updated() { console.log('updated'); }, beforeDestroy() { console.log('beforeDestroy'); }, destroyed() { console.log('destroyed'); } });
Vue 的双向绑定是通过 v-model
指令实现的。v-model
是 v-bind
和 v-on
的语法糖,用于在表单元素上实现双向数据绑定。
<input v-model="message">
v-model
的实现原理如下:
v-model
将输入元素的值与 Vue 实例的数据属性绑定。v-model
监听输入元素的 input
或 change
事件,当用户输入时,更新 Vue 实例的数据属性。v-model
会自动更新输入元素的值。// v-model 的实现原理 Vue.component('my-input', { props: ['value'], template: ` <input :value="value" @input="$emit('input', $event.target.value)" > ` }); new Vue({ el: '#app', data: { message: '' } });
Vue 使用虚拟 DOM 来提高渲染性能。虚拟 DOM 是一个轻量级的 JavaScript 对象,它是对真实 DOM 的抽象。当数据发生变化时,Vue 会生成一个新的虚拟 DOM 树,并与旧的虚拟 DOM 树进行比较,找出差异,然后只更新真实 DOM 中需要变化的部分。
Vue 的虚拟 DOM 实现基于 Snabbdom 库。Vue 通过 h
函数创建虚拟 DOM 节点,并通过 patch
函数将虚拟 DOM 渲染到真实 DOM 中。
// 虚拟 DOM 示例 const vnode = h('div', { class: 'container' }, [ h('h1', { style: { color: 'red' } }, 'Hello Vue'), h('p', 'This is a virtual DOM example') ]); patch(document.getElementById('app'), vnode);
computed
和 watch
是 Vue 中用于处理数据变化的两种方式,但它们的使用场景和实现方式有所不同。
computed
是计算属性,它基于依赖的响应式数据进行计算,并返回一个新的值。computed
的值会被缓存,只有当依赖的数据发生变化时,才会重新计算。
new Vue({ el: '#app', data: { firstName: 'John', lastName: 'Doe' }, computed: { fullName() { return this.firstName + ' ' + this.lastName; } } });
watch
是侦听器,它用于监听某个数据的变化,并在数据变化时执行自定义的逻辑。watch
不会缓存结果,每次数据变化时都会执行。
new Vue({ el: '#app', data: { firstName: 'John', lastName: 'Doe', fullName: '' }, watch: { firstName(newVal) { this.fullName = newVal + ' ' + this.lastName; }, lastName(newVal) { this.fullName = this.firstName + ' ' + newVal; } } });
computed
适用于需要根据多个数据计算出一个新值的场景;watch
适用于需要在数据变化时执行异步操作或复杂逻辑的场景。computed
会缓存结果,只有当依赖的数据发生变化时才会重新计算;watch
不会缓存结果,每次数据变化时都会执行。computed
的性能通常优于 watch
,因为 computed
会缓存结果,减少不必要的计算。Vue 提供了多种组件通信方式,适用于不同的场景。
props
和 $emit
是 Vue 中最常用的组件通信方式。父组件通过 props
向子组件传递数据,子组件通过 $emit
向父组件发送事件。
// 父组件 Vue.component('parent-component', { template: ` <div> <child-component :message="message" @update="handleUpdate"></child-component> </div> `, data() { return { message: 'Hello from parent' }; }, methods: { handleUpdate(newMessage) { this.message = newMessage; } } }); // 子组件 Vue.component('child-component', { props: ['message'], template: ` <div> <p>{{ message }}</p> <button @click="updateMessage">Update Message</button> </div> `, methods: { updateMessage() { this.$emit('update', 'Hello from child'); } } });
$parent
和 $children
是 Vue 提供的用于访问父组件和子组件的实例。通过 $parent
和 $children
,组件可以直接访问父组件或子组件的数据和方法。
// 父组件 Vue.component('parent-component', { template: ` <div> <child-component></child-component> </div> `, data() { return { message: 'Hello from parent' }; } }); // 子组件 Vue.component('child-component', { template: ` <div> <p>{{ $parent.message }}</p> </div> ` });
$refs
是 Vue 提供的用于访问子组件或 DOM 元素的引用。通过 $refs
,父组件可以直接访问子组件的实例或 DOM 元素。
// 父组件 Vue.component('parent-component', { template: ` <div> <child-component ref="child"></child-component> <button @click="getChildMessage">Get Child Message</button> </div> `, methods: { getChildMessage() { console.log(this.$refs.child.message); } } }); // 子组件 Vue.component('child-component', { template: ` <div> <p>Hello from child</p> </div> `, data() { return { message: 'Hello from child' }; } });
provide
和 inject
是 Vue 提供的用于跨层级组件通信的方式。父组件通过 provide
提供数据,子组件通过 inject
注入数据。
// 父组件 Vue.component('parent-component', { provide() { return { message: 'Hello from parent' }; }, template: ` <div> <child-component></child-component> </div> ` }); // 子组件 Vue.component('child-component', { inject: ['message'], template: ` <div> <p>{{ message }}</p> </div> ` });
Vuex 是 Vue 的官方状态管理库,适用于大型应用的全局状态管理。Vuex 通过 state
、getters
、mutations
、actions
等概念来管理应用的状态。
// Vuex 示例 const store = new Vuex.Store({ state: { message: 'Hello from Vuex' }, mutations: { updateMessage(state, newMessage) { state.message = newMessage; } }, actions: { updateMessage({ commit }, newMessage) { commit('updateMessage', newMessage); } } }); new Vue({ el: '#app', store, computed: { message() { return this.$store.state.message; } }, methods: { updateMessage() { this.$store.dispatch('updateMessage', 'Hello from Vue'); } } });
Vue Router 是 Vue 的官方路由库,用于实现单页应用(SPA)的路由管理。Vue Router 通过 router-view
和 router-link
组件来实现路由的切换和视图的渲染。
Vue Router 的基本配置包括定义路由表、创建路由实例、将路由实例挂载到 Vue 实例中。
// 路由配置 const routes = [ { path: '/', component: Home }, { path: '/about', component: About } ]; // 创建路由实例 const router = new VueRouter({ routes }); // 挂载路由实例 new Vue({ router, el: '#app' });
Vue Router 支持动态路由,可以通过 :param
来定义动态路由参数。
const routes = [ { path: '/user/:id', component: User } ]; // 在组件中访问路由参数 Vue.component('User', { template: '<div>User {{ $route.params.id }}</div>' });
Vue Router 支持嵌套路由,可以通过 children
属性来定义嵌套路由。
const routes = [ { path: '/user', component: User, children: [ { path: 'profile', component: Profile }, { path: 'posts', component: Posts } ] } ];
Vue Router 提供了导航守卫功能,允许开发者在路由切换时执行自定义逻辑。常见的导航守卫包括 beforeEach
、beforeResolve
、afterEach
等。
router.beforeEach((to, from, next) => { if (to.path === '/admin' && !isAdmin) { next('/login'); } else { next(); } });
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。