简介

Vue一款用于构建用户界面的 JavaScript 框架。它基于标准 HTML、CSS 和 JavaScript 构建,并提供了一套声明式的、组件化编程模型,帮助你高效地开发用户界面。无论是简单还是复杂的界面,Vue 都可以胜任。

构建用户名界面:在合适的时刻将数据应用到合适的位置

渐进式: Vue可以自底向上逐层的应用,即需要什么用什么,可以只用一个vue核心库,也可以装一堆插件库

Vue特点:

  1. 组件化模式,提高代码复用率,让代码更好维护
  2. 声明式编码,无需直接操作DOM,提高开发效率
  3. 响应性,Vue 会自动跟踪 JavaScript 状态并在其发生变化时响应式地更新 DOM
  4. 使用虚拟DOM和优秀的Diff算法,尽量复用DOM节点

引入与挂载

引入的方式有两种,通过cdn或者本地文件引入

1
2
<script src="https://cdn.chuckle.top/npm/vue@2.7.14/dist/vue.js"></script>
<script src="/js/vue.js"></script>

使用步骤:

  1. 创建Vue实例(引入文件后就多了一个Vue的全局构造函数)
  2. 挂载到某个dom节点上
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
// 这里通过引入cdn来创建Vue实例
<html>
<head>
<title>test</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<link rel="stylesheet" type="text/css" href="style.css">
</head>
<body>
<div id = "app">
<div>{{ name }}</div>
</div>

<script type="text/javascript" src="script.js"></script>
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.14/dist/vue.js"></script>
<script>
var vm = new Vue({
el: "#app",
data: {
name: "snailuu"
},
})
</script>
</body>
</html>

模板语法

Vue有两种模板语法:

  1. 插值语法:{{}}
  2. 指令语法:v-

插值语法用于标签体内容

指令

常见的有v-ifv-else-ifv-elsev-forv-bind

v-bind中, style较为特殊,属性值采用对象写法,class同理

1
2
3
4
5
6
<img 
:style="{
width: size + 'px',
height:size + 'px'
}"
>

数据传递

props

  • 数组写法

    1
    props: ['name']
  • 对象写法

    1
    2
    3
    4
    5
    6
    7
    props: {
    name: {
    type: String,
    required: true,
    default:'snailuu'
    }
    }

父组件调用:

1
<test name="snailuu"></test>

注意:子组件不能改动父组件传递的数据信息

$emit

通过vue.$emit来向父组件发出事件通知

子组件通过vue.$emit("事件名称", "事件参数")向父组件发出通知,父组件通过<App @事件名称="处理函数">来进行处理

抛出事件:子组件在某个时候发生了一件事,但自身无法处理,于是通过事件的方式通知父组件处理

事件参数:子组件抛出事件时,传递给父组件的数据

注册事件:父组件申明,当子组件发生某件事的时候,自身将做出一些处理

结构说明

template

存放一些html代码,用于构建虚拟dom树

script

style

加了scoped字段,vue会自动在该组件内类名后面加上一段哈希值来保证唯一(调用不同组件的相同类名会保证不同,以此隔绝不同的组件)

1
2
3
4
5
6
7
<style scoped>
.avatar-img{
border-radius: 50%;
object-fit: cover;
display: block;
}
</style>

计算属性

计算属性从代码层度看很想一个方法/函数,但不同于方法/函数的地方在于计算属性会基于其响应式依赖被缓存,也就是需要被计算的属性return包含的属性)如果没发生改变的话,后面不断调用的话就直接返回缓存内容

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
export default {
data() {
return {
firstName: 'John',
lastName: 'Doe'
}
},
computed: {
fullName: {
// getter
get() {
return this.firstName + ' ' + this.lastName
},
// setter
set(newValue) {
// 注意:我们这里使用的是解构赋值语法
[this.firstName, this.lastName] = newValue.split(' ')
}
}
}
}

全局样式

在css中可以用类似js中的导入文件方式导入样式文件

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
// var.less
@danger: #cc3600; // 危险、错误
@primary: #6b9eee; // 主色调、链接
@words: #373737; // 大部分文字、深色文字
@lightWords: #999; // 少部分文字、浅色文字
@warn: #dc6a12; // 警告
@success: #7ebf50; // 成功
@gray: #b4b8bc; // 灰色
@dark: #202020; // 深色


// gloabal.less
@import './var.less';
html {
color: @words;
font-family: "-apple-system", "BlinkMacSystemFont", "Roboto", "Helvetica Neue",
"微软雅黑", sans-serif;
overflow: hidden;
}
body {
overflow: hidden;
margin: 0;
}
a {
text-decoration: none;
color: inherit;

&:hover {
color: @primary;
}
}

vue中可以使用~@来返回到src目录

v-if 和 v-show

两个都是控制dom元素是否显示,区别:

  1. v-if还有分支 —> v-else-if、v-else
  2. v-if会把dom真实增添和删除
  3. v-show始终会生成dom元素,而是通过控制dom元素的css:display=none;隐藏

插槽

有时候父组件要在子组件的某个区域中再增加新的内容,用插槽可以将内容插入到指定区域

默认插槽只要在子组件声明<slot>区域,但这样只会到一个区域中

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
<!-- message组件:一个弹窗消息 -->
<div class="message-container">
<div class="content">
<!-- slot是vue的内置组件 -->
<slot></slot>
</div>
<button>确定</button>
<button>关闭</button>
</div>

<!-- 父组件App -->
<Message>
<div class="app-message">
<p>App Message</p>
<a href="">detail</a>
</div>
</Message>

<!-- 最终的结果 -->
<div class="message-container">
<div class="content">
<div class="app-message">
<p>App Message</p>
<a href="">detail</a>
</div>
</div>
<button>确定</button>
<button>关闭</button>
</div>
image-20201202152326210

也可以使用具名插槽来指定某个内容在某个区域,在子组件的<slot name="插槽名">,声明一个唯一的插槽名,在父组件就可以通过v-slot:插槽名来将内容插入到指定的槽中,也可以将v-slot:插槽名 简写成:#插槽名

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
<!-- Layout 组件 -->
<div class="layout-container">
<header>
<!-- 我们希望把页头放这里,提供插槽,名为header -->
<slot name="header"></slot>
</header>
<main>
<!-- 我们希望把主要内容放这里,提供插槽,名为default -->
<slot></slot>
</main>
<footer>
<!-- 我们希望把页脚放这里,提供插槽,名为footer -->
<slot name="footer"></slot>
</footer>
</div>

<!-- 父组件App -->
<BaseLayout>
<template v-slot:header>
<h1>Here might be a page title</h1>
</template>

<template v-slot:default>
<p>A paragraph for the main content.</p>
<p>And another one.</p>
<template v-slot:default>

<template v-slot:footer>
<p>Here's some contact info</p>
</template>
</BaseLayout>
image-20201202153229391