目录
一、基础语法和概念
1.1.模板语法
模板语法包括:双花括号插值、指令、修饰符、模板中使用JavaScript表达式等。
1.双花括号插值
使用双花括号
{{ }}
可以将数据绑定到DOM文本节点上。例如,{{ message }}
会将Vue实例中message
属性的值插入到该位置
<div id="app">{{ message }}</div>
<script>
var vm = new Vue({
el: '#app',
data: {
message: 'Hello Vue!'
}
});
</script>
2.指令
Vue指令是带有
v-
前缀的特殊特性。指令用于在表达式的值改变时,将某些行为应用到DOM上。常见的指令包括:
v-bind
v-bind
:用于绑定HTML属性,可以简写为:
。
例如,<img v-bind:src="imageUrl">
或<img :src="imageUrl">
会绑定图片的src
属性到Vue实例的imageUrl
数据上。
<img v-bind:src="imageUrl" alt="Image">
<script>
var vm = new Vue({
el: '#app',
data: {
imageUrl: 'https://example.com/image.jpg'
}
});
</script>
v-model
v-model
:实现表单输入和应用状态之间的双向数据绑定。例如,<input v-model="message">
会创建一个双向数据绑定的文本框,其值与Vue实例的message
属性同步。
<input v-model="message" placeholder="Edit me">
<p>Message is: {{ message }}</p>
<script>
var vm = new Vue({
el: '#app',
data: {
message: ''
}
});
</script>
上述代码中,v-model
实现了表单输入和应用状态之间的双向数据绑定。当输入框的内容变化时,message
数据也会相应更新,并实时显示在<p>
标签中
v-if,v-else-if、v-else
v-if
、v-else-if
、v-else
:用于条件性地渲染元素。当表达式的值为真时,元素会被渲染;否则,不会渲染这个元素,或渲染v-else
指定的元素。
<div v-if="value === 0">零分</div>
<div v-else-if="value === 1">1分</div>
<div v-else-if="value === 2">2分</div>
<div v-else-if="value === 3">3分</div>
<div v-else>其他情况</div>
v-show
v-show指令根据表达式的真假值来切换元素的CSS属性display。
<p v-show="visible">现在你看到我了</p>
<script>
data() {
return {
visible: true
}
}
</script>
v-for
v-for
:基于源数据多次渲染元素或模板块。例如,<ul><li v-for="item in items">{{ item }}</li></ul>
会遍历items
数组,为每个元素渲染一个<li>
。
<ul>
<li v-for="item in items" :key="item.id">{{ item.text }}</li>
</ul>
<script>
var vm = new Vue({
el: '#app',
data: {
items: [
{ id: 1, text: 'Item 1' },
{ id: 2, text: 'Item 2' },
{ id: 3, text: 'Item 3' }
]
}
});
</script>
v-on
v-on
:用于监听DOM事件,并在触发时运行一些JavaScript代码。可以简写为@
。例如,<button v-on:click="incrementCounter">Add 1</button>
或<button @click="incrementCounter">Add 1</button>
会在按钮点击时调用incrementCounter
方法。具体在第四章中讲解事件处理详情
<button v-on:click="doSomething">点击我</button>
<!-- 简写 -->
<button @click="doSomething">点击我</button>
<script>
var app = new Vue({
el: '#app', // 假设您有一个id为app的元素来挂载Vue实例
data: {
// 可以在这里定义一些数据属性
},
methods: {
doSomething() {
alert('你点击了按钮!');
}
}
});
</script>
v-pre指令跳过这个元素和它的子元素的编译过程。可以用来显示原始Mustache标签。
<div v-pre>{{ 我是大胡子语法 }}</div>
3.修饰符
修饰符(Modifiers)是以
.
开头的特殊后缀,用于指示指令应该以特定方式绑定。以下是一些常用的修饰符:
.lazy(用于v-model
):
将v-model
在change
事件中同步输入框的值与数据,而不是在input
事件中。
这在输入框的每一次变化都会触发一些计算或验证逻辑时特别有用,可以减少这些逻辑被触发的频率。
.trim(用于v-model
):
自动过滤用户输入的首尾空格。
.number(用于v-model
):
将用户的输入尝试转换为数字类型。
如果转换失败,则值将变为NaN
。
.stop(用于v-on
):
调用event.stopPropagation()
来阻止事件冒泡。
.prevent(用于v-on
):
调用event.preventDefault()
来阻止事件的默认行为。
.capture(用于v-on
):
添加事件侦听器时使用捕获模式。
.self(用于v-on
):
只当事件是从侦听器绑定的元素本身触发时才触发回调。
.once(用于v-on
):
事件将只会触发一次。
.passive(用于v-on
):
滚动事件的默认行为(即滚动行为)将会立即触发,而不会等待v-on
完成。这个修饰符对于提高页面滚动性能很有帮助。
按键修饰符(用于v-on
):
.left
、.right
、.middle
:分别用于监听鼠标左、中、右键的点击事件。
.enter
、.tab
、.delete(捕获“删除”和“退格”键)、.esc、.space、.up、.down、.left、.right等,用于监听特定的键盘按键事件。
4.拓展:
v-for中key的作用
key属性用作Dom的唯一标识,当对象或数组发生增删时,默认是把数组全部元素重新绘制,当有了唯一标识以后,重新绘制节点之前会先和以后节点比较,看是否有相同的key 如果相同则复用 提高了Dom更新效率
v-if和v-show的区别?
v-if和v-show都是判断元素显示或者隐藏的
本质上区别,v-if判断的是是否加载,可以减轻浏览器的压力,在需要的时候载。
v-show一定会加载,只不过改变的只是dispaly:none的显示隐藏样式
v-for与v-if能一起使用吗
能但是不建议使用,因为在vue2中,v-for优先级比v-if要高,带来性能方面的浪费。
1.2.实例化VUE
1.创建Vue示例
使用new Vue()创建一个Vue实例,并传入一个选项对象来配置Vue示例的行为
<div id="app">{{ message }}</div>
<script>
var vm = new Vue({
el: '#app', // 指定挂载点
data: {
message: 'Hello Vue!' // 声明数据
},
methods: {
greet: function() {
alert('Hello Vue!');
}
}
});
</script>
上述代码中,创建了一个Vue实例,并将其挂载到ID为app
的DOM元素上。同时,在data
选项中声明了一个message
数据,并在methods
选项中定义了一个greet
方法。
2.配置选项
el:指定一个DOM元素作为Vue示例的挂载点
data:一个对象的字面量,用于声明应用的数据。
methods:一个包含了Vue实例方法的对象。
computed:一个包含Vue实例计算属性的对象
watch:一个对象,用于观察和响应Vue实例上数据的变化
1.3.数据和方法
1.数据
在data
选项中声明的数据会被添加到Vue实例的响应式系统中。当数据变化时,Vue会自动更新DOM以反映这些变化。
<div id="app">
<p>{{ message }}</p>
<button @click="changeMessage">Change Message</button>
</div>
<script>
var vm = new Vue({
el: '#app',
data: {
message: 'Hello Vue!'
},
methods: {
changeMessage: function() {
this.message = 'Message has been changed!';
}
}
});
</script>
2.方法
在methods
选项中定义的方法可以在模板中通过事件处理指令(如v-on
或@
)调用。这些方法可以接受参数,并可以访问Vue实例的数据和其他方法。
<div id="app">
<p>{{ message }}</p>
<button @click="greet">Greet</button>
</div>
<script>
var vm = new Vue({
el: '#app',
data: {
message: 'Hello Vue!'
},
methods: {
greet: function() {
alert(this.message);
}
}
});
</script>
二、组件化
2.1.创建和注册组件
1.定义组件
在 Vue 2 中,你可以通过 Vue.extend()
方法或对象字面量方式来定义一个组件。然而,更常见和推荐的方式是使用对象字面量,因为它更简洁。
// 使用对象字面量定义组件
var MyComponent = {
template: '<div>这是一个自定义组件</div>',
// 可以添加 data、methods、computed 等选项
};
2.注册组件
全局注册:注册的组件可以在任何新创建的 Vue 实例的模板中使用。
Vue.component('my-component', MyComponent);
局部注册:注册的组件只能在注册它的 Vue 实例的模板中使用
new Vue({
el: '#app',
components: {
'my-component': MyComponent
}
});
2.2.组件通讯
1.父组件向子组件传递数据(props)
父组件可以通过子组件标签上使用属性(即 props)来传递数据。
// 父组件
new Vue({
el: '#app',
data: {
message: 'Hello from Parent!'
},
components: {
'child-component': {
template: '<div>{{ messageFromParent }}</div>',
props: ['messageFromParent']
}
},
template: '<child-component :message-from-parent="message"></child-component>'
});
2. 子组件向父组件传递数据(事件)
子组件可以通过 $emit
方法触发一个事件,父组件可以监听这个事件来接收数据
// 子组件
var ChildComponent = {
template: '<button @click="notifyParent">通知父组件</button>',
methods: {
notifyParent() {
this.$emit('child-event', 'Hello from Child!');
}
}
};
// 父组件
new Vue({
el: '#app',
components: {
'child-component': ChildComponent
},
template: '<child-component @child-event="handleChildEvent"></child-component>',
methods: {
handleChildEvent(message) {
console.log(message); // 输出: Hello from Child!
}
}
});
vue组件的通讯方式有八种,更详细讲解在作者另一篇文章中 点击链接https://blog.csdn.net/m0_64455070/article/details/143625597
2.3.插槽
插槽允许我们让父组件向子组件的模板中插入 HTML 内容。
1. 默认插槽
// 子组件
var MyComponent = {
template: '<div><slot></slot></div>'
};
// 父组件
new Vue({
el: '#app',
components: {
'my-component': MyComponent
},
template: '<my-component>这是插入到子组件中的内容</my-component>'
});
2.具名插槽
// 子组件
var MyComponent = {
template: `
<div>
<slot name="header"></slot>
<slot></slot> <!-- 默认插槽 -->
<slot name="footer"></slot>
</div>
`
};
// 父组件
new Vue({
el: '#app',
components: {
'my-component': MyComponent
},
template: `
<my-component>
<template v-slot:header>这是头部内容</template>
这是主体内容(默认插槽)
<template v-slot:footer>这是底部内容</template>
</my-component>
`
});
2.4.动态组件和异步组件
1.动态组件
动态组件允许我们在同一个挂载点动态地切换多个组件。
new Vue({
el: '#app',
data: {
currentComponent: 'component-a'
},
components: {
'component-a': { template: '<div>组件 A</div>' },
'component-b': { template: '<div>组件 B</div>' }
},
template: '<component :is="currentComponent"></component>',
methods: {
switchComponent() {
this.currentComponent = this.currentComponent === 'component-a' ? 'component-b' : 'component-a';
}
}
});
2.异步组件
异步组件允许我们延迟加载组件,直到它们真正被需要时。这有助于提高应用性能,特别是在大型应用中
Vue.component('async-example', () => ({
// 异步加载组件定义
component: import('./MyComponent.vue'),
// 加载时的异步组件工厂函数返回一个对象,
// 对象中的 `loading`、`error`、`delayed` 和 `timeout`
// 选项可用于定制加载行为
loading: LoadingComponent,
error: ErrorComponent,
delay: 200,
timeout: 3000
}));
三、Vue实例
3.1.实例化选项
在创建Vue实例时,可以传入一个包含多个选项的对象,这些选项定义了实例的行为和初始状态。以下是一些关键选项的详细解释:
el:
类型:字符串或HTMLElement
用途:指定Vue实例将要挂载的DOM元素。如果是一个选择器字符串,Vue将使用document.querySelector
来找到对应的元素。
data:
类型:对象或函数
用途:声明应用的数据。如果是一个函数,它必须返回一个对象,这样每个实例都可以维护一份被返回对象的独立的拷贝。
methods:
类型:对象
用途:定义实例的方法。这些方法可以在模板表达式或计算属性中被调用。方法的上下文(即this
)指向Vue实例。
computed:
类型:对象
用途:定义计算属性。计算属性是基于它们的依赖进行缓存的响应式属性。只有当相关依赖发生改变时,计算属性才会重新求值。
watch:
类型:对象
用途:侦听器,观察和响应Vue实例上数据变动的回调。这个选项允许你指定一些数据属性,当这些属性发生变化时,执行特定的回调函数。
props(注意:在组件中使用,而非实例):
类型:数组或对象
用途:声明父组件传递给子组件的数据。在Vue 2中,props不能在组件的实例选项中直接定义,而应该在组件的选项对象中定义。
components:
类型:对象
用途:注册子组件,以便在模板中使用。通过此选项,你可以将自定义组件注册到Vue实例中,并在模板中通过标签形式使用。
拓展:
两者的 区别,使用场景?
computed支持缓存,不支持异步,当计算属性中存在异步操作的时,无法监听数据的变化。使用场景就是购物车
watch不支持缓存,支持异步,可以监听一个数据的变化,返回两个参数,第一个参数是新数据,第二个参数是旧数据。
使用场景:监听路由的变化,监听id发生变化的时候调接口
3.2.实例方法
Vue实例提供了多种方法,用于控制实例的行为和状态。以下是一些关键方法的详细解释:
$mount():
用途:手动挂载一个未挂载的Vue实例。如果实例已经挂载,则这个方法不会起作用。它接受一个可选的挂载点(DOM元素或选择器字符串),如果未指定,则使用el
选项指定的元素。
$destroy():
用途:完全销毁一个Vue实例。销毁后,实例绑定的所有东西都会解绑,所有的事件监听器和子实例都会被移除。在销毁实例之前,你可以使用$beforeDestroy
和$destroyed
这两个生命周期钩子进行清理工作。
$nextTick():
用途:将回调延迟到下次DOM更新循环之后执行。在修改数据之后立即使用这个方法,可以获取更新后的DOM。这对于需要在DOM更新后执行某些操作的场景非常有用。
$forceUpdate():
用途:强制Vue实例重新渲染。注意,它仅影响实例本身和插入插槽内容的子组件,而不是所有子组件。通常,你应该避免使用这个方法,因为它会绕过Vue的响应式系统,可能导致不必要的性能开销。
set()∗∗和∗∗delete():
用途:这两个方法用于动态地向响应式对象添加或删除属性,并确保这些操作能够触发视图更新。$set()
方法接受三个参数:目标对象、属性名和新值;$delete()
方法接受两个参数:目标对象和属性名。
3.3.实例属性
Vue实例还提供了多种属性,用于访问实例的状态和配置。以下是一些关键属性的详细解释:
$el:
类型:HTMLElement
用途:Vue实例使用的根DOM元素。这是Vue通过el
选项或$mount()
方法挂载的元素。
$data:
类型:对象
用途:Vue实例观察的数据对象。Vue实例代理了对其data对象属性的访问和修改,使得你可以在模板中直接使用这些数据属性。
$props:
类型:对象
用途:当前组件接收到的props对象。这是响应式的,当父组件传递的props更新时,它们也会更新。注意,这个属性在组件实例中可用,而不是在根Vue实例中。
$children:
类型:数组
用途:当前实例的直接子组件。这是一个包含当前实例所有子组件实例的数组。需要注意,$children
并不保证顺序,也不是响应式的。
$parent:
类型:Vue实例或null
用途:父实例,如果当前实例有的话。这是一个指向当前实例父实例的引用。如果当前实例是根实例,则此属性为null。
$root:
类型:Vue实例
用途:当前组件树的根Vue实例。如果当前实例没有父实例,此实例将会是其自己。这个属性对于在深层嵌套的组件中访问根实例非常有用。
slots∗∗和∗∗scopedSlots:
类型:对象
用途:这两个属性用于访问被插槽分发的内容。$slots
包含所有具名插槽的内容,而$scopedSlots
包含所有作用域插槽的内容。这些属性在组件实例中可用,用于在组件内部处理插槽内容。
四、事件处理
4.1.事件监听
使用v-on指令绑定事件。
v-on
指令用于监听DOM事件,并在触发时运行一些JavaScript代码。v-on
可以简写为 @
。
<template>
<div>
<button v-on:click="handleClick">Click me</button>
<!-- 简写 -->
<button @click="handleClick">Click me too</button>
</div>
</template>
<script>
export default {
methods: {
handleClick() {
alert('Button clicked!');
}
}
}
</script>
4.2.事件修饰符
例如:.stop、.prevent等,用于控制事件行为。
.stop
:调用 event.stopPropagation()
阻止事件冒泡。
.prevent
:调用 event.preventDefault()
阻止默认行为。
.capture
:添加事件监听器时使用捕获模式。
.self
:只有在事件是从该元素本身触发时才触发回调。
.once
:事件将只会被触发一次。
<template>
<div>
<form @submit.prevent="handleSubmit">
<input type="text" @input.stop="handleInput">
<button @click.self="handleButtonClick">Click me (self)</button>
<button @click.once="handleOnceClick">Click me once</button>
</form>
</div>
</template>
<script>
export default {
methods: {
handleSubmit(event) {
alert('Form submitted!');
// event.preventDefault() 已由 .prevent 修饰符处理
},
handleInput(event) {
alert('Input changed!');
// event.stopPropagation() 已由 .stop 修饰符处理
},
handleButtonClick() {
alert('Button clicked (self)!');
},
handleOnceClick() {
alert('Button clicked once!');
// 后续点击不会触发此函数
}
}
}
</script>
4.3.自定义事件
自定义事件:在组件之间传递事件。
子组件:
<!-- ChildComponent.vue -->
<template>
<button @click="emitEvent">Click me to emit event</button>
</template>
<script>
export default {
methods: {
emitEvent() {
this.$emit('custom-event', 'Hello from child component!');
}
}
}
</script>
父组件
<!-- ParentComponent.vue -->
<template>
<div>
<ChildComponent @custom-event="handleCustomEvent"></ChildComponent>
</div>
</template>
<script>
import ChildComponent from './ChildComponent.vue';
export default {
components: {
ChildComponent
},
methods: {
handleCustomEvent(message) {
alert(message);
}
}
}
</script>
五、数据绑定
5.1.单向数据绑定
单向数据绑定是指数据从数据源(通常是 Vue 实例的
data
属性)流向视图(模板),但视图中的变化不会反向影响数据源。
1.插值表达式({{}})
插值表达式用于在模板中显示数据。当数据源中得变量发生变化时,插值表达式所在的位置会自动更新为最新的值
<div id="app">
<p>{{ message }}</p>
</div>
<script>
export default {
new Vue({
el: '#app',
data: {
message: 'Hello, Vue!'
}
});
}
</script>
2.v-bind指令
v-bind
指令用于绑定属性或元素的 HTML 特性(如 href
、src
等)到数据模型。它也可以简写为 :
。
<div id="app">
<a v-bind:href="url">Link</a>
<!-- 简写 -->
<a :href="url">Link</a>
</div>
<script>
export default {
new Vue({
el: '#app',
data: {
url: 'https://www.example.com'
}
});
}
</script>
3.计算属性
计算属性是基于它们的依赖进行缓存的响应式属性,当依赖发生变化时,计算属性会重新计算,并更新视图
<div id="app">
<p>Original Message: {{ message }}</p>
<p>Reversed Message: {{ reversedMessage }}</p>
<!-- 可以通过输入框来改变 message 的值,以观察计算属性的更新 -->
<input v-model="message" placeholder="Change the message">
</div>
<script>
export default {
new Vue({
el: '#app',
data: {
message: 'Hello, Vue!'
},
computed: {
reversedMessage: function() {
// 依赖于 message 变量,并返回其反转字符串
return this.message.split('').reverse().join('');
}
}
});
}
</script>
5.2.双向数据绑定
双向数据绑定意味着数据可以在数据模型和视图之间双向流动。Vue.js 提供了
v-model
指令来实现这一功能。v-model
通常用于表单输入元素,如<input>
、<textarea>
和<select>
。
1.v-model
指令:
v-model
在表单输入元素(如 <input>
、<textarea>
和 <select>
)上创建双向数据绑定。
当用户在表单元素中输入内容时,v-model
会将输入的值更新到绑定的数据源中。
同时,当数据源中的值发生变化时,表单元素的值也会自动更新。
<div id="app">
<input v-model="message" placeholder="Edit me">
<p>Message is: {{ message }}</p>
</div>
<script>
export default {
new Vue({
el: '#app',
data: {
message: 'Hello, Vue!'
}
});
}
</script>
2.双向数据绑定的原理
vue采用的是数据劫持结合开发者订阅模式的方式,通过Object.defineProperty()来劫持
set,get,在数据变动的时候发布给订阅者,触发响应式回调。
当数据模型发生变化时,Vue 的响应式系统会自动更新视图中所有依赖该数据模型的部分。
同时,当用户在视图中修改数据时(如输入内容),
v-model
会监听相应的输入事件(如input
事件),并将输入的值更新到绑定的数据模型中。
3.双向数据绑定的应用场景
双向数据绑定非常适合用于表单输入、实时数据同步等场景。
它简化了数据与视图之间的同步逻辑,使得开发者可以更加专注于业务逻辑
六、路由
在Vue 2中,Vue Router是官方的路由管理器,它允许你构建单页面应用(SPA)中的页面路由。以下是关于Vue Router在Vue 2中的安装、配置、路由钩子以及嵌套路由的详细介绍:
6.1.安装和配置:
如何在Vue应用中安装和配置Vue Router。
1.安装Vue Router
如果已经有一个Vue CLI创建的项目,或者手动搭建了Vue2环境
npm install vue-router@3
这里指定版本@3
是为了确保与Vue 2兼容。
详细过程可以看作者的 vue路由和路由安装https://blog.csdn.net/m0_64455070/article/details/140206904
6.2.路由钩子
Vue Router提供了多种路由钩子函数,这些钩子函数允许你在路由导航的不同阶段执行特定的逻辑。它们主要分为全局钩子、路由独享钩子和组件内钩子。
路由守卫又称导航守卫,指是路由跳转前、中、后过程中的一些钩子函数。路由跳转前做一些验证,比如登录验证,是网站中的普遍需求
1.全局钩子
beforeEach(to, from, next)
:全局前置守卫。在每个路由跳转之前被调用,可以用来进行权限验证、页面标题设置、记录页面访问日志等操作。如果需要在导航被确认前进行一些异步操作,可以使用next
函数的回调来处理。
beforeResolve(to, from, next)
:全局解析守卫。在导航被确认前,同时在所有组件内守卫和异步路由组件被解析后调用。这通常用于在路由跳转前进行一些异步操作,如获取数据等。
afterEach(to, from)
:全局后置钩子。在每个路由跳转后被调用,可以用来进行页面跳转后的操作,如停止加载动画、页面统计等。这个钩子不接收next
函数,因为导航已经确认。
其中路由守卫钩子函数都有三个参数:
to: 想去哪个路由
from: 从哪个路由过来的
next: 跳转到哪,执行跳转
2.路由独享钩子
beforeEnter(to, from, next)
:路由独享守卫。在路由配置中定义,导航到该路由时被调用。这通常用于在进入某个特定路由之前执行特定逻辑,如权限验证等。
3.组件内钩子
beforeRouteEnter(to, from, next)
:在路由进入该组件之前被调用。此时组件实例还未被创建,无法访问组件实例的this
。但是,你可以通过next
函数的回调来访问组件实例。
beforeRouteUpdate(to, from, next)
:在当前路由复用的组件中,路由更新但是组件被复用时被调用。这允许你在组件复用之前更新数据或执行其他操作。此时可以访问组件实例的this
。
beforeRouteLeave(to, from, next)
:在导航离开该组件的路由时调用。这允许你在路由切换之前执行一些清理操作,如保存数据等。此时也可以访问组件实例的this
。
6.3.嵌套路由
嵌套路由是指通过路由实现组件的嵌套展示,它主要由页面结构决定。实际项目中的应用界面通常由多层嵌套的组件组合而成,为了使多层嵌套的组件能够通过路由访问,路由也需要具有嵌套关系
1.定义嵌套路由
在Vue Router的配置中,通过children
属性来定义子路由。子路由的path
属性前不要带“/”,否则会永远以根路径开始请求。
const router = new VueRouter({
routes: [
{
path: '/parent',
component: ParentComponent,
children: [
{
path: 'child', // 注意这里不要带"/"
component: ChildComponent
},
{
path: 'another-child', // 同样不要带"/"
component: AnotherChildComponent
}
]
},
// 其他路由配置...
]
});
2.在父组件中使用<router-view>
在父组件的模板中,使用<router-view>
来显示子路由组件。当导航到父路由时,父组件会被渲染,同时<router-view>
会根据当前子路由的路径来渲染相应的子组件。
<template>
<div>
<h1>Parent Component</h1>
<router-link to="/parent/child">Go to Child</router-link>
<router-link to="/parent/another-child">Go to Another Child</router-link>
<router-view></router-view> <!-- 子路由组件将渲染在这里 -->
</div>
</template>
3.嵌套路由的链接
在嵌套路由中,你可以使用<router-link>
来创建导航链接。注意,链接的路径应该是相对于父路由的路径。例如,在上面的例子中,/parent/child
和/parent/another-child
就是相对于/parent
父路由的子路由路径。
6.4.动态路由
1.动态路由的基本概念
动态添加路由:在应用运行期间,根据某些条件(如用户权限、应用状态等)动态地向Vue Router实例添加新的路由规则。
动态匹配路由:使用通配符或动态段(如/user/:id
)来匹配不同的URL,并根据这些URL动态地渲染不同的组件。
动态修改路由:在应用运行期间,修改现有的路由规则,例如更改路由的组件、元信息(meta)等。
动态删除路由:根据需求,从Vue Router实例中移除不再需要的路由规则。
实现动态路由的步骤
在Vue 2中,你可以通过以下步骤来实现动态路由:
定义基本的路由配置:在创建Vue Router实例时,你可以定义一些基本的、静态的路由规则。
在组件或Vuex中管理路由状态:你可以将路由的配置信息存储在Vuex状态树中,或者在组件的data属性中管理。这样,你就可以根据应用的状态动态地改变路由配置。
监听状态变化并更新路由:使用Vuex的mutation或组件的watcher来监听状态的变化,并在状态变化时调用Vue Router的addRoutes
方法来动态添加路由,或者使用其他方法来修改路由配置。
使用<router-link>
和<router-view>
:在你的组件中,使用<router-link>
来创建导航链接,并使用<router-view>
来显示当前路由对应的组件
// router/index.js
import Vue from 'vue';
import Router from 'vue-router';
import Home from '@/components/Home.vue';
Vue.use(Router);
const router = new Router({
routes: [
{
path: '/',
name: 'Home',
component: Home,
},
// 其他静态路由...
],
});
// 假设你有一个函数来动态添加路由
function addDynamicRoutes(newRoutes) {
newRoutes.forEach(route => {
router.addRoute(route);
});
}
// 你可以在应用启动时或在某个组件中调用这个函数来添加动态路由
// 例如,根据用户的权限来添加路由
const userRoutes = [
{
path: '/user/:id',
name: 'User',
component: () => import('@/components/User.vue'),
},
// 其他根据用户权限动态添加的路由...
];
addDynamicRoutes(userRoutes);
export default router;
在用户登录后动态添加路由
// router/index.js
import Vue from 'vue';
import Router from 'vue-router';
import Home from '@/components/Home.vue';
import Login from '@/components/Login.vue';
Vue.use(Router);
const staticRoutes = [
{
path: '/',
name: 'Home',
component: Home,
},
{
path: '/login',
name: 'Login',
component: Login,
},
// 其他静态路由...
];
const router = new Router({
routes: staticRoutes,
mode: 'history', // 使用HTML5历史模式
});
// 假设你有一个函数来处理登录后的路由添加
function handleLogin(user) {
// 根据用户角色或权限动态添加路由
const dynamicRoutes = [
{
path: '/dashboard',
name: 'Dashboard',
component: () => import('@/components/Dashboard.vue'),
// 可以添加meta字段来存储额外的信息,如权限要求
meta: { requiresAuth: true, role: 'user' },
},
// 其他根据用户角色或权限动态添加的路由...
];
// 使用addRoutes方法动态添加路由
router.addRoutes(dynamicRoutes);
// 跳转到登录后的默认页面,如仪表盘
router.push({ name: 'Dashboard' });
}
// 你可以在某个组件中调用这个函数,比如Login组件的登录成功回调中
export { router, handleLogin };
// 在你的main.js或类似的入口文件中
import Vue from 'vue';
import App from './App.vue';
import { router } from './router';
new Vue({
router,
render: h => h(App),
}).$mount('#app');
七、状态管理
Vuex是Vue.js的官方状态管理库,它主要用于管理Vue应用中多个组件的共享状态。
7.1.安装和配置
通过npm或yarn来安装Vuex
npm install vuex@3.0.0 --save
# 或者
yarn add vuex@3.0.0
安装完成后,你需要在Vue项目中配置Vuex。通常,你会在项目的src
目录下创建一个store
文件夹,并在其中创建一个index.js
文件来定义你的Vuex store。以下是一个简单的配置示例:
// src/store/index.js
import Vue from 'vue';
import Vuex from 'vuex';
Vue.use(Vuex);
const store = new Vuex.Store({
state: {
// 定义你的状态
count: 0
},
mutations: {
// 定义修改状态的方法
increment(state) {
state.count++;
}
},
actions: {
// 定义异步操作,可以提交mutation
incrementAsync({ commit }) {
setTimeout(() => {
commit('increment');
}, 1000);
}
},
getters: {
// 定义派生状态
countPlusOne: state => state.count + 1
}
});
export default store;
然后,你需要在Vue的入口文件中(通常是main.js
)引入并注册这个store:
// src/main.js
import Vue from 'vue';
import App from './App.vue';
import store from './store';
new Vue({
store,
render: h => h(App),
}).$mount('#app');
7.2.核心概念
State:Vuex中的单一状态树(Single Source of Truth),它包含了应用中大部分的状态。你可以通过this.$store.state
来访问这些状态,或者在组件的计算属性中返回某个状态。
Getter:类似于Vue中的计算属性,Getter用于从state中派生出一些状态。你可以通过this.$store.getters.yourGetterName
来访问Getter。
Mutation:Vuex中唯一允许更新应用状态的方法是提交mutation。Mutation必须是同步函数,它接收state作为第一个参数。你可以通过this.$store.commit('yourMutationName', payload)
来提交一个mutation。
Action:Action类似于mutation,但它是异步的。Action可以包含任意异步操作,并且可以通过调用commit
方法来提交mutation。你可以通过this.$store.dispatch('yourActionName', payload)
来触发一个action。
vue的工作流程
当组件想要修改state里面的数据,
1. 首先需要调用this.$store.dispatch来触发actions里面的方法,在这个方法中会返回两个参数,一个是commit方法,一个是传递过来的值,
2. 然后在这个方法内部调用commit方法去触发mutations里面的函数,mutations这个函数是专门修改存储state里面的数据,当mutations里面的函数触发后state里面的数据就会发生变化。就会存储到state中。
7.3.模块化
随着应用变得复杂,状态管理也会变得困难。为了解决这个问题,Vuex允许我们将store分割成模块(module)。每个模块拥有自己的state、mutation、action、getter,甚至是嵌套子模块。
// src/store/modules/user.js
const state = {
name: 'John Doe'
};
const mutations = {
setName(state, newName) {
state.name = newName;
}
};
const actions = {
updateName({ commit }, newName) {
commit('setName', newName);
}
};
const getters = {
userName: state => state.name
};
export default {
namespaced: true, // 开启命名空间
state,
mutations,
actions,
getters
};
// src/store/index.js
import Vue from 'vue';
import Vuex from 'vuex';
import user from './modules/user';
Vue.use(Vuex);
const store = new Vuex.Store({
modules: {
user
}
});
export default store;
八、生命周期钩子
在Vue2中,生命周期钩子(也称为生命周期事件或生命周期回调)是Vue实例在其生命周期的不同阶段自动调用的函数。这些钩子提供了在特定时刻运行代码的机会,允许开发者在组件实例创建、挂载、更新和销毁时执行自定义逻辑。
常用钩子
beforeCreate
调用时机:在实例初始化之后,数据观测(data observer)和事件配置(event/watcher setup)之前被调用。
使用场景:这个阶段组件的data和methods等属性还未初始化,因此无法在这个钩子中进行数据操作或访问组件方法。它主要用于一些非常早期的初始化工作,但实际应用中较少用到。
created
调用时机:在实例创建完成后被调用。此时组件的实例已经创建,data和methods等属性已经初始化完成。
使用场景:这是进行数据初始化操作的最佳时机,如发起异步请求获取数据,并将数据保存到组件的data属性中。
beforeMount
调用时机:在组件挂载之前调用。此时组件的模板已经编译完成,但还未生成真实的DOM。
使用场景:这个钩子通常用于在组件挂载到DOM之前进行一些准备工作,但由于此时DOM还未生成,因此无法进行DOM操作。
mounted
调用时机:在组件挂载完成后调用。此时组件的模板已经编译为真实的DOM,并插入到页面中。
使用场景:这是进行DOM操作和第三方库集成的最佳时机。例如,使用jQuery插件对组件的DOM元素进行初始化设置,或使用图表库初始化图表等。
beforeUpdate
调用时机:在组件更新之前调用。当组件的数据发生变化时会触发该钩子函数。
使用场景:这个钩子通常用于在组件更新之前执行一些操作,如保存滚动位置或获取输入框的焦点,以便在更新后能够恢复状态。
updated
调用时机:在组件更新完成后调用。此时组件的视图已经重新渲染。
使用场景:这个钩子通常用于在组件更新后执行一些操作,如更新DOM元素的样式或重新计算布局等。但需要注意的是,如果更新操作会导致新的数据变化,可能会触发新的更新循环。
beforeDestroy
调用时机:在组件销毁之前调用。
使用场景:这个钩子通常用于在组件销毁之前执行一些清理工作,如取消事件监听、清除定时器或释放资源等。以避免内存泄漏和不必要的性能损耗。
destroyed
调用时机:在组件销毁之后调用。此时组件实例已经被销毁,组件的状态和数据都不能再访问。
使用场景:这个钩子通常用于执行一些最终的清理工作,如移除全局事件监听器等。但需要注意的是,在这个阶段已经无法访问组件的实例和状态了。
vue父子组件生命周期的执行顺序的详细内容,可以看本文作者的VUE2——父子组件生命周期的执行顺序https://mp.csdn.net/mp_blog/creation/editor/140504387
使用场景总结
数据初始化:在created
钩子函数中进行数据的初始化操作,如发起异步请求获取数据。
DOM操作:在mounted
钩子函数中进行DOM操作,如使用jQuery插件或第三方库对DOM元素进行初始化设置。
数据更新:在beforeUpdate
钩子函数中执行一些需要在组件更新之前的操作,如保存滚动位置或获取输入框的焦点。
清理工作:在beforeDestroy
钩子函数中执行一些清理工作,如取消事件监听、清除定时器或释放资源。
拓展
vue虚拟dom?
通过js创建一个Object对象来模拟真实DOM结构,这个对象包含标签名 (tag)、属性 (attrs) 和子元素对象 (children) 三个属性,通过vue中的render()函数把虚拟dom编译成真实dom,在通过appendChild()添加到页面中。创建虚拟DOM就是为了更 好将虚拟的节点渲染到页面视图中,
为什么需要虚拟DOM,
DOM是很慢的,虚拟dom用来解决频繁操作dom而引发的浏览器 卡顿问题,vue中虚拟 DOM 最大的优势是 diff 算法,减少 JavaScript 操作真实 DOM 的带来的性能消耗。
上文内容,还会查漏补缺,如有不足,还望各位大神留言
码字不易,欢迎点赞收藏。
标签:Vue,DOM,基础知识,实例,VUE2,组件,message,路由 From: https://blog.csdn.net/m0_64455070/article/details/144156434