一大坨东西
先复习一下vue
虚拟DOM 节省资源
声明式渲染
1 | <template> |
条件与循环
1 | <template> |
组件化应用构建
组件系统是 Vue 的另一个重要概念,因为它是一种抽象,允许我们使用小型、独立和通常可复用的组件构建大型应用.
简单来说,一个Vue文件就是一个组件,里面有template script style.
建立一个Vue文件,比如叫main-component.Vue1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30<template>
<!-- 鼠标悬浮看 title 属性 -->
<div v-if="seen" :title="msg" v-on:click="handleClick">
{{ msg }}
<!-- 循环渲染列表数据 -->
<template v-for="todo in todos" :key="todo">
<div>{{ todo }}</div>
</template>
</div>
</template>
<script>
export default {
name: "MainConcepts", // 组件名称
data() {
return {
msg: "hello 蓝桥",
seen: true, // 控制是否显示
todos: ["Vue", "React", "Angular"],
};
},
methods: {
handleClick() {
// alert(event.target.title);
this.seen = false;
},
},
};
</script>
<style></style>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15<template>
<!-- 渲染 MainConcepts 组件-->
<main-concepts />
</template>
<script>
import MainConcepts from "./main-concepts"; // 引入 MainConcepts 组件
export default {
name: "App",
components: {
MainConcepts,
},
};
</script>
<style></style>
在 Vue 中,组件分为:“普通组件”、“函数式组件”、“类组件”。
Props代表了根组件的属性值1
2
3
4
5
6
7
8
9
10<template>
<!-- 声明式渲染 msg 数据 -->
<div>{{ msg }}</div>
</template>
<script>
export default {
name: "App",
props: ["msg"], // 给 App 组件定义一个 msg 属性
};
</script>1
2
3
4import { createApp } from "vue";
import App from "./App";
// 传递根组件,并传递根组件属性
createApp(App, { msg: "我是根组件属性中的 msg" }).mount("#app");1
2
3
4
5
6
7const app = Vue.createApp(...)
// 注册一个全局组件 SearchInput
app.component('SearchInput', SearchInputComponent)
// 注册一个全局指令 focus
app.directive('focus', FocusDirective)
// 插件的使用
app.use(LocalePlugin)
模板语法
1 | <span>hello: {{ msg }}</span> |
1 | <template> |
指令
用 v-bind
指令给元素绑定了一个属性
用过v-if
条件指令去控制某个元素的显示,用过 v-on
指令绑定过 click
事件,用过 v-for
指令去循环渲染1
2
3
4
5
6
7<!-- 鼠标悬浮看 title 属性 -->
<div
v-if="seen"
:title="msg"
v-on:click="handleClick"
>
...
修饰符
修饰符 (modifier) 是以半角句号 .
指明的特殊后缀,用于指出一个指令应该以特殊方式绑定。例如,.prevent
修饰符告诉 v-on
指令对于触发的事件调用 event.preventDefault()
:1
<a v-on:click.prevent="handleLinkClick">...</a>
1
2
3
4
5
6
7
8
9<template>
<a
v-bind:[attributeName]="msg"
v-on:[eventName].prevent="handleClick"
href="https://www.lanqiao.cn/courses"
>
{{ "hello" + msg }}
</a>
</template>
data属性
组件的 Data
属性是一个函数。Vue 在创建新组件实例的过程中调用此函数。它应该返回一个对象,然后 Vue 会通过响应性系统将其包裹起来,并以 $data
的形式存储在组件实例中。可以直接通过组件实例访问 $data
对象中的属性。
组件外可以通过组件实例来访问组件 Data 属性1
2
3
4
5
6
7
8
9
10import { createApp } from "vue";
import App from "./App.vue";
// 创建 app 应用实例
const app = createApp(App);
// 获取 App 根组件实例
const rootComponent = app.mount("#app");
console.log("App 组件中的 Data 属性:", rootComponent.$data);
console.log("App 组件中的 msg 数据:", rootComponent.msg);
// 修改组件的响应式数据 msg
rootComponent.msg = "我是 msg 数据,我在组件外被修改了";
在定义 methods
时应避免使用箭头函数,因为这会阻止 Vue 绑定恰当的 this
指向。
计算属性
计算属性可以依赖多个 Vue 实例的数据,只要其中任一数据变化,计算属性就会重新执行,视图也会更新。
计算属性 computed
在使用时,一定要注意,函数里面的变量都会被监听,只要里面的某一个值变动,便会将整个函数执行一遍。
计算属性的setter与getter1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60<template>
<div>
<fieldset>
<legend>单价:</legend>
<input :value="price" @input="handlePriceInput" />
</fieldset>
<fieldset>
<legend>数量:</legend>
<input :value="count" @input="handleCountInput" />
</fieldset>
总价:{{ total }}
<div @click="handleTotal">私自修改一下 total</div>
</div>
</template>
<script>
export default {
name: "App",
data() {
return {
count: 0, // 数量
price: 0, // 单价
};
},
computed: {
// 计算属性声明
total: {
// 定义 total 计算属性
// getter
get() {
return parseInt(this.count) * parseFloat(this.price);
},
// setter
set(newValue) {
alert("不允许直接操作 total 的值,你计算的:" + newValue + "无效!");
},
},
},
methods: {
/**
处理单价输入
*/
handlePriceInput(event) {
this.price = event.target.value;
},
/**
处理数量输入
*/
handleCountInput(event) {
this.count = event.target.value;
},
/**
* 自定义处理 total
*/
handleTotal() {
this.total = 0;
},
},
};
</script>
监听器
虽然计算属性在大多数情况下更合适,但有时也需要一个自定义的侦听器。这就是为什么 Vue 通过 watch
选项提供了一个更通用的方法,来响应数据的变化。当需要在数据变化时执行异步或开销较大的操作时,这个方式是最有用的1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77<template>
<div>
<fieldset>
<legend>单价:</legend>
<input :value="price" @input="handlePriceInput" />
</fieldset>
<fieldset>
<legend>数量:</legend>
<input :value="count" @input="handleCountInput" />
</fieldset>
总价:{{ total }}
<div @click="handleTotal">私自修改一下 total</div>
</div>
</template>
<script>
export default {
name: "App",
data() {
return {
count: 0, // 数量
price: 0, // 单价
};
},
computed: {
// 计算属性声明
total: {
// 定义 total 计算属性
// getter
get() {
return parseInt(this.count) * parseFloat(this.price);
},
// setter
set(newValue) {
alert("不允许直接操作 total 的值,你计算的:" + newValue + "无效!");
},
},
},
watch: {
// 侦听器声明
count(newCount, oldCount) {
// 定义一个侦听器,名称跟响应式数据 count 一致
// 商品数量必须 >= 0
if (Number.isNaN(parseFloat(newCount)) || parseFloat(newCount) < 0) {
this.count = oldCount;
}
},
price(newPrice, oldPrice) {
// 定义一个侦听器,名称跟响应式数据 price 一致
// 单价必须 >= 0
if (Number.isNaN(parseFloat(newPrice)) || parseFloat(newPrice) < 0) {
this.price = oldPrice;
}
},
},
methods: {
/**
处理单价输入
*/
handlePriceInput(event) {
this.price = event.target.value;
},
/**
处理数量输入
*/
handleCountInput(event) {
this.count = event.target.value;
},
/**
* 自定义处理 total
*/
handleTotal() {
this.total = 0;
},
},
};
</script>
除了可以在 watch 选项中执行条件判断外,我们甚至可以在里面进行异步请求,并在我们得到最终结果前,设置中间状态。这些都是计算属性无法做到的
计算属性与侦听器的区别:
名称 | 特性 |
---|---|
计算属性(computed) | 1. 计算一个或多个响应式数据的值。 2. 应用:简化模版语法中的变量计算。 3. 具有缓存性,页面重新渲染值不变化,计算属性会立即返回之前的计算结果,而不必再次执行函数。 |
侦听器(watch) | 1. 观察一个响应式数据变化。 2. 应用:监听响应式数据的变化,做对应逻辑处理。 3. 具有缓存性,页面重新渲染值不变化,监听方法不会执行。 |
Vue-router
Hash模式
hash 模式是用 createWebHashHistory()
创建的:1
2
3
4
5
6
7
8import { createRouter, createWebHashHistory } from "vue-router";
const router = createRouter({
history: createWebHashHistory(),
routes: [
//...
],
});
它在内部传递的实际 URL 之前使用了一个哈希字符(#
)。由于这部分 URL 从未被发送到服务器,所以它不需要在服务器层面上进行任何特殊处理。不过,它在 SEO 中确实有不好的影响。如果你担心这个问题,可以使用 HTML5 模式
HTML5模式
1 | import { createRouter, createWebHistory } from "vue-router"; |
Vue-element-template
直接先看一下文档
vue-element-admin 是一个后台前端解决方案,它基于 vue 和 element-ui实现。它使用了最新的前端技术栈,内置了 i18 国际化解决方案,动态路由,权限验证,提炼了典型的业务模型,提供了丰富的功能组件
建议你可以把 vue-element-admin
当做工具箱或者集成方案仓库,在 vue-admin-template
的基础上进行二次开发,想要什么功能或者组件就去 vue-element-admin
那里复制过来。
布局
layout
对应代码@/layout
vue-element-admin
中大部分页面都是基于这个 layout
的,除了个别页面如:login
, 404
, 401
等页面没有使用该layout
。如果你想在一个项目中有多种不同的layout
也是很方便的,只要在一级路由那里选择不同的layout
组件就行
app-main
对应代码
这里在 app-main
外部包了一层 keep-alive
主要是为了缓存 <router-view>
的,配合页面的 tabs-view
标签导航使用,如不需要可自行去除。
其中transition
定义了页面之间切换动画,可以根据自己的需求,自行修改转场动画。相关文档。默认提供了fade
和fade-transform
两个转场动画,具体 css 实现见transition.scss。如果需要调整可在AppMain.vue中调整transition
的 name
。
路由和侧边栏
本项目侧边栏和路由是绑定在一起的,所以你只有在 @/router/index.js
下面配置对应的路由,侧边栏就能动态的生成了。大大减轻了手动重复编辑侧边栏的工作量。当然这样就需要在配置路由的时候遵循一些约定的规则
资料
一篇文章说清 webpack、vite、vue-cli、create-vue 的区别 - 金色海洋(jyk) - 博客园 (cnblogs.com)