vue.js初学习

Node.js

在学习VUE.js之前,非常有必要理解什么是node.js,因为vue.js依赖于node.js进行运行。

什么是node。js?

实际上node.js是一个C++编写的服务器,这个服务器使用了chrome的V8引擎来解释运行javascript,作为服务器应用。

所以node。js能够运行javascript代码,但是不同的在node。js环境下js不能使用document等浏览器才有的环境,可以直接使用http对象,等等于浏览器环境有一点不同。

什么是npm?

npm是一个简写,全称是node package manager意思是node的包管理器。事实上npm已经成为了世界上最大的软件包仓库。

在安装好node.js之后,可以直接使用npm命令下载仓库中的软件包。

npm install moment

什么是Vue?

Vue和Vue.js不同,Vue包含Vue.js,这里先介绍一下Vue.js是什么.

Vue.js是什么?

Vue.js是一个javaScript库,包含很多的js对象,函数…

这个库不依赖于其他的库,可以独立引入使用。

Vue.js是vue框架的核心

什么是vue框架?

vue框架是开发前端的一套工具,包含html,js,css的开发,使用vue语法来加速开发,最后通过编译(vue CLI等工具)生成html,css,js文件

将这些文件部署在服务器上即可,事实上他们就是普通的静态资源文件.所以可见vue框架的适用性.

更流行的方式

现在的web开发更倾向于前后端分离设计.

这意味着,前端(静态资源)和后端API是独立开发,部署和运行的.

解释一下独立部署运行,意思是可能运行在不同的服务器上,这意味着后端不能直接操作,返回资源,而更多的是被动回应前端的数据请求(返回json).

所以需要使用到RESTful API形式

在 Vue.js 应用中,通过 AJAX 请求或者现代的 Fetch API 与 Java 后端的 API 进行通信。这包括发送 HTTP 请求到后端,并处理后端返回的数据。

跨域资源共享(CORS)处理: 由于前后端分离架构,前端和后端可能运行在不同的域名下,因此可能会遇到跨域问题。在 Java 后端中进行相应的跨域资源共享(CORS)配置,以允许来自 Vue.js 前端的跨域请求。

前后端分离的架构,其中Vue.js应用程序作为一个独立的客户端应用程序,与后端API进行通信,而后端API则托管在另一个域名下的服务器上。

例如,你可以将Vue.js应用程序部署在www.example.com,而后端API则托管在api.example.com,两者分别使用不同的域名。这样做的好处包括更好的代码分离、更灵活的部署选项以及更好的性能和安全性管理。

跨域访问攻击

跨站请求伪造(Cross-Site Request Forgery,CSRF)攻击是一种网络安全攻击,它利用了用户当前已经认证的会话来执行未经用户授权的操作。攻击者通过引诱用户访问恶意网站或者点击包含恶意代码的链接,来触发用户在已登录的受信任网站上的操作。

具体来说,CSRF 攻击通常包括以下步骤:

  1. 用户登录受信任网站: 用户在浏览器中登录了一个受信任的网站,并获得了有效的会话凭证,如 Cookie 或 Session ID。
  2. 攻击者构造恶意请求: 攻击者在另一个网站上(通常是恶意网站)构造了一个恶意请求,其中包含了对目标网站的操作请求,如修改用户账户信息、发起资金转账等。
  3. 用户访问恶意网站: 用户在浏览器中访问了包含恶意请求的网站,触发了该请求。
  4. 浏览器发送请求: 由于用户已经在目标网站登录并具有有效的会话凭证,浏览器会在发送请求时自动携带会话凭证。
  5. 目标网站接收请求: 目标网站收到了包含恶意操作请求的请求,并认为是合法的请求,因为请求包含了有效的会话凭证。
  6. 执行未经授权的操作: 目标网站在接收到恶意请求后,执行了其中包含的操作,导致了未经用户授权的操作的发生,如修改用户信息、发起资金转账等。

为了防范 CSRF 攻击,常见的防御方法包括使用 CSRF Token、检查请求的来源头(如 Origin 头)等。

所以不允许跨域请求的原因是因为容易被恶意网站绑架客户端发请请求而用户不知道的情况

安全存储: CSRF Token 应该以安全的方式存储在客户端,并且不能被轻易获取或篡改。通常情况下,CSRF Token 应该存储在不可访问于 JavaScript 的 HttpOnly Cookie 中,这样可以防止恶意脚本访问 Token。HttpOnly cookie使得这个cookie只能在当前浏览器使用,而不被远程获取是吗?

Vue的基本语法

参考1: https://www.w3ccoo.com/vue

实际上Vue一款javascript前端框架,便于用户轻松地构建交互性强、可维护性高的现代 Web 应用

文本插值

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
<!DOCTYPE html>
<html>
<head>
<title>我的第一个 Vue 页面</title>
<style>
#app {
display: inline-block;
padding: 10px;
font-size: x-large;
background-color: lightgreen;
}
</style>
</head>
<body>

<h1>Vue 示例</h1>

<p>通过在 id="app" 的 div 中写入 {{ message }} 来从 Vue 实例内的“data”获取消息。</p>
<!-- 可以粗浅的看出语法是连续的两个括号加上空格字段来表示 -->
<div id="app">
{{ information }} , {{ message }}
</div>
<!-- 先导入 vue.js 来解释我们的vue语法 -->
<script src="https://unpkg.com/vue@3/dist/vue.global.js"></script>

<script>
// 定义了一个对象, 通过vue的工厂方法,传入参数是一个对象
const app = Vue.createApp({
// 具体就是有个data方法 return 一个对象,这个对象的一个属性message的值是"Hello world"
data() {
return {
message: "Hello World!",
information: "i guss it's will work!"
}
}
})
// 然后这个对象可以解释到 某个div标签,通过整儿表达式替换了div中的innerText中的内容
app.mount('#app')

</script>

</body>
</html>

基础语法

文本插值,就是在innerText中使用语法从vue中实例中获取文本,进行替换

具体的语法就是双花括号,还可以在双括号里面写javascript代码

v-bind 指令 (可以简写为:)

前面是文本替换的解决方案,而v-bind就是标签属性替换的解决方案.

  1. 属性值替换

我们使用 v-bind:原属性 这样的属性 性

这样就需要通过vue.js进行解释才能获得属性具体的值

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
 <html>
...
<div id="app">

<div v-bind:class="vueClass">
这个class动态可变
</div>
</div>
...
<script>
const app = Vue.createApp({
data(){
return {
vueClass:"实际类型"
}
}
})
app.mount("#app");
</script>
</html>

可以注意到,实际上无论是文本还是属性替换都是共用vue实例中的data()返回对象中的属性的

v-bind与文本替换不同的一点是,v-bind中的值,那串字符串本身就是一段javascript代码,vue会执行

v-bind是智能检测值位置的字符串,如果是在vue中定义好的属性,那么就会进行替换

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<div id="app">
<div v-bind:style="{ fontSize: size }">文字示例</div>
</div>
...
<script>
const app = Vue.createApp({
data() {
return {
size: '28px'
}
}
})
app.mount('#app')
</script>

如果在vue实例中有size属性,那么就会将size替换,如果没有就会设置为默认值

  1. 使用javascript语法

在这个字符串内,也支持javascript语法

1
2
3
<div v-bind:style="{ fontSize: size + 'px' }">
Text example
</div>
  1. 使用对象表示是否启用
1
2
3
<div v-bind:class="{ myClass: true }">
The class is set conditionally to change the background color
</div>

原来这里写的应该是v-bind:class=”myClass”,现在可以通过这种形式来选择是否启用这个属性

1
2
3
<div v-bind:class="{ myClass: isImportant }">
The class is set conditionally to change the background color
</div>

v-if指令

v-if可以使用vue实例中的值,来进行dom,template中的标签 的控制

例如

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<p v-if="typewriterCount > 0">
in stock
</p>

<p v-else>
not in stock
</p>
...
<script>
const app = Vue.createApp({
data(){
return {
typewriterCount: 10
}
}
})
</script>

这里v-if通过判断后面的boolean值来工作,所以后面的实际上是javascript表达式,不过会先经过vue的解析

1
2
3
4
5
6
7
8
9
10
11
12
13
<div id="app">
<p v-if="text.includes('pizza')">The text includes the word 'pizza'</p>
<p v-else>The word 'pizza' is not found in the text</p>
</div>
...
<script>
...
data() {
return {
text: 'I like taco, pizza, Thai beef salad, pho soup and tagine.'
}
}
</script>

像这种直接使用的javascript原生的函数也是可以的

一共有这么几种

指令 详细信息
v-if 可以单独使用,也可以与 v-else-if 和/或 v-else 一起使用。 如果 v-if 内的条件为”true”,则不考虑 v-else-ifv-else
v-else-if 必须在 v-if 或另一个 v-else-if 之后使用。 如果 v-else-if 内的条件为”true”,则不考虑后面的 v-else-ifv-else
v-else 如果 if 语句的第一部分为 false,则这部分将会发生。 必须放置在 if 语句的最末尾,在 v-ifv-else-if 之后。

v-show指令

这个是改变元素的可见性,不会改变dom文档,所以更加快捷,相比v-if

不过v-show只有两种,show与hidden

语法和v-if是是一样的

v-for指令

会循环在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
<div>
<img v-for="x in manyFoods" v-bind:src="x">
</div>
...

<script>
const app = Vue.createApp({
data() {
return {
manyFoods: [
'img_burrito.svg',
'img_salad.svg',
'img_cake.svg',
'img_soup.svg',
'img_fish.svg',
'img_pizza.svg',
'img_rice.svg'
]
}
}
})

app.mount('#app')

</script>

注意到这里定义了一个数组,使用了javascript中的in语法

v-for中的表达式是一个vue表达式,会先经过vue解析变成javascript再执行

x in manyFoods实际上变成了 const x; for(x in manyFoods)

这令定义的变量与在data()返回的对象中定义的属性是同等地位,等都能v-bind之类的匹配到

实际上可以获得更多信息

1
2
3
<p v-for="(x, index) in manyFoods">
{{ index }}: "{{ x.name }}", url: "{{ x.url }}" <br>
</p>

将当前循环,赋予给一个元组,可以得到当前的迭代对象和在数组中的索引

vue事件

事件响应是javascript的一大功能,所以vue也有支持

vue有三种方式来全方位支持事件响应

  1. Vue v-on 指令 最基本的
  2. Vue 方法 就是指令中调用方法
  3. Vue v-on 修饰符 控制了事件的粒度

v-on指令(可以简写为@)

很像普通的javascript时间响应,但是这里可以调用vue实例内部的函数

v-on:原事件=”表达式

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<div id="app">
<input v-on:input="inpCount++">
<p>{{ 'Input events occured: ' + inpCount }}</p>
</div>

<script src="https://unpkg.com/vue@3/dist/vue.global.js"></script>
<script>
const app = Vue.createApp({
data() {
return {
inpCount: 0
}
}
})
app.mount('#app')
</script>

也可以是调用vue中定义的方法

v-on:原事件=”方法名

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<div id="app">
<p>Move the mouse pointer over the box below:</p>
<div v-on:mousemove="mousePos"></div>
</div>

<script src="https://unpkg.com/vue@3/dist/vue.global.js"></script>
<script>
const app = Vue.createApp({
data() {
return {
xPos: 0,
yPos: 0
}
},
methods: {
mousePos(event) {
this.xPos = event.offsetX
this.yPos = event.offsetY
}
}
})
app.mount('#app')
</script>

注意这里在vue实例中定义方法的语法是

data()方法的级别中,有一个methods属性,这个属性中定义方法对象

方法对象中有很多方法,这些方法以属性的形式存在于方法对象中

传递参数

我们的函数可以传递一些参数

例如,定义成这样子

1
2
3
4
5
methods: {
addMoose(number) {
this.count = this.count + number
}
}

也可以传递多个参数

传递参数和事件对象

但是当我们既要又要的时候,我们就需要注意语法,不然编译器不知道event是事件对象还是形参

1
2
3
4
5
6
7
8
9
<button v-on:click="addAnimal($event, 5)">+5</button>
...
methods: {
addAnimal(e, number) {
if(e.target.parentElement.id==="tigers"){
this.tigers = this.tigers + number
}
}
}

主要就是在传递的时候使用$event来传递事件对象

事件修饰符

主要是为了更加精确的监听某一个事件

例如,我要监听enter键按下的情况

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<input v-on:keydown.enter="getKey">
<p> {{ keyValue }} </p>
...
data() {
return {
keyValue = ''
}
},
methods: {
getKey(evt) {
this.keyValue = evt.key
console.log(evt.key)
}
}
按键修饰符 详细信息
.[*Vue key alias*] Vue 中最常见的键都有自己的别名:.enter``.tab``.delete``.esc``.space``.up``.down``.left``.right
.[*letter*] 指定按下该键时出现的字母。 例如:使用 .s 键修饰符来监听”S”键。
.[*system modifier key*] .alt.ctrl.shift.meta。 这些键可以与其他键结合使用,或者与鼠标单击结合使用。

可以任意组合.例如

1
2
v-on:keydown.ctrl.s
<!-- 就可以表示同时按下ctrl和s -->

除了按键修饰符之外,还有

鼠标修饰符

可以使用 .left, .center.right 修饰符表示具体按下哪一个键

1
2
v-on:click.left <!-- 表示左键 -->
v-on:click.right <!-- 表示右键 -->

.prevent修饰符可以防止点击的时候出现默认下拉菜单

实际上可以通过event.preventDefault()来阻止出现默认响应,但是使用事件修饰符更加可读和维护

1)prevent: 阻止默认事件(常用);
2)stop:阻止事件冒泡(常用);
3)once:事件只触发一次(常用);
4)capture:使用事件的捕获模式;
5)self:只有event.target是当前操作的元素时才触发事件;
6)passive: 时间的默认行为立即执行,无需等待事件回调执行完毕。

vue 表单

表单当然是很重要的一块了,先看看下面的段代码

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
<!DOCTYPE html>
<html>
<head>
<title>购物清单</title>
<style>
form {
border: dashed black 1px;
width: 200px;
padding: 20px;
}
</style>
</head>
<body>

<h1>示例:购物清单</h1>
<div id="app">
<!-- 事件响应函数 -->
<form v-on:submit.prevent="addItem">
<p>
你需要什么?
<!-- 可以看到vue将会把值赋予vue实例中的同名字段 -->
<!-- 通过 v-model指定要赋予的字段 -->
<input type="text" required placeholder="item name.." v-model="itemName">
</p>
<p>
多少个?
<!-- 这个也是一样的,通过v-mode指定要将值注入哪一个字段 -->
<input type="number" placeholder="number of items.." v-model="itemNumber">
</p>
<button type="submit">新增项目</button>
</form>

<div>
<p>购物清单:</p>
<ul>
<!-- 通过v-for生成 文档节点 -->
<li v-for="item in shoppingList">商品名:{{ item.name }}, 数量:{{ item.number}}</li>
</ul>
</div>
</div>


<script src="https://unpkg.com/vue@3/dist/vue.global.js"></script>
<script>
const app = Vue.createApp({
data() {
return {
// 关键就是这里,要声明字段,这样才能成功注入
itemName: null,
itemNumber: null,
shoppingList: [
{ name: 'Tomatoes', number: 5 },
{ name: 'patato', number: 100 }
]
}
},
methods: {
addItem(){
let item = {
name: this.itemName,
number: this.itemNumber
}
this.shoppingList.push(item)
this.itemName = null
this.itemNumber = null
}
}
})
app.mount('#app')
</script>

</body>
</html>

注意v-model提供的是双向绑定,也就是可以在vue中改变自身字段值从而改变文档中的输入框中的值

提供的双向绑定 v-model:

  • v-model 当 HTML 输入改变时更新 Vue 实例数据
  • v-model 当 Vue 实例数据发生变化时也会更新 HTML 输入

v-model指令

根据上面的例子可以知道v-model是一个与表单元素相互绑定的指令

vue css绑定

实际上就是之前提到的v-bind:style以及v-bind:class

需要注意的是,v-bind:style是修改的元素的内联样式,优先级非常高

以下是关于使用 v-bind:classv-bind:style 的不同方面,我们之前在本教程中没有见过:

  1. 当 CSS 类分配给同时具有 class=""v-bind:class="" 的 HTML 标签时,Vue 会合并这些类,而不是二选一。
  2. 包含一个或多个类的对象会被分配 v-bind:class="{}"。 在对象内部,可以打开或关闭一个或多个类。
    -> 记得v-bind:class=”{yourClass: false}”吗,可以用来启用类,这里一个类就是一个属性.
  3. 对于内联样式 (v-bind:style),定义 CSS 属性时首选驼峰命名法,但如果将其写在引号内,也可以使用”kebab-case”。例如 v-bind:style=”{‘font-size’:100px, fontSize:100px}”
  4. CSS 类可以使用数组/数组表示法/语法进行分配
    <div v-bind:class="[{ impClass: isImportant }, 'yelClass' ]"> 此 div 标签属于一个或两个类,具体取决于 isImportant 属性。</div>
    因为我们知道,v-bind:class中的类可以用{}表示,那么;类值集合就要用另外的符号,所以就用了数组的括号

vue 计算属性

实际上就是要我们不要直接引用vue实例中的字段值,而是要通过方法来访问,这样有很多的好处

但是计算属性和methods重定义的方法有一些不同

在 Vue 中,computed 和 methods 都是用来定义方法的,但有一些重要的区别:

  1. computed
    • 计算属性 (computed) 是基于它们的依赖进行缓存的。
    • computed 方法是响应式依赖追踪的,只有依赖数据发生改变时,才会重新计算
    • computed 属性本质上是一个 getter 函数,会返回计算后的值,类似于 data 中的数据属性。
  2. methods
    • 方法 (methods) 每次被调用时都会执行代码块。
    • methods 中的函数在每次触发时都会执行,不会进行缓存
    • methods 主要用于处理用户交互,或执行一些具体的操作

因此,如果需要根据依赖动态计算属性值,并且希望这个值在依赖没有改变时进行缓存,建议使用 computed。而如果需要在用户交互或事件触发时执行某些逻辑操作,则应该使用 methods。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<input type="checkbox" v-model="chbxVal"> {{ isImportant }}
...
data() {
return {
chbxVal: false
}
},
computed: {
isImportant() {
if(this.chbxVal){
return 'yes'
}
else {
return 'no'
}
}

所以一定要注意我们将methods和computed区分开定义

另一点如果methods中的方法没有写()表示引用函数地址而不用调用函数,而computed中不写()也表示调用

Vue watch观察者

主要用于记录旧值

就例如我们数据库中的触发器,有一个new和old表一样,保存值给我们使用

具体的语法是

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
const app = Vue.createApp({
data() {
xPos: 0,
xDiff: 0
},
watch: {
xPos(newVal,oldVal){
this.xDiff = newVal-oldVal
}
},
methods: {
updatePos(evt) {
this.xPos = evt.offsetX
}
}
})

有一个特殊的属性,watch,这个对象中定义一个与实例中属性同名属性的方法,两个参数,第一个参数是新值,第二个参数是旧值

当属性的值发生变化的时候,这个函数就是被调用

观察者和方法都写成函数,但有很多区别:

  • 方法从 HTML 调用。
  • 方法通常在事件发生时被调用。
  • 方法自动接收事件对象作为输入。
  • 我们还可以将我们选择的其他值发送给方法
  • 观察者仅在观察的数据属性值发生变化时才会被调用,并且这种情况会自动发生。
  • 观察者自动从被观察的属性接收新值和旧值。
  • 我们无法选择以观察者作为输入发送任何其他值.

所以观察者中定义的方法不是给我们自己调用的,是给程序自动调用的

观察者只能依赖一个属性的改变

Vue 拓展

为了开发更加大型的项目(大型项目往往有更为复杂的html,css部分),获得更好的开发环境

就像jsp,将html作为主题,将逻辑代码作为修改一样,vue提供了新的文件格式来编写vue代码

一种就是SFC,另一个是*.vue文件

简单理解*.vue文件组成

所有 *.vue 文件仅由三部分组成:

  • <template> 代表 HTML 内容所在的位置。
  • <script> 代表我们的 Vue 代码。
  • <style> 代表我们编写 CSS 样式的位置。

如何起作用?

SFC和.vue文件不能直接被浏览器理解运行,所以我们编写的SFC和.vue文件需要先经过编译,得到对应的 .html、.css 和 .js 文件,以便浏览器可以运行我们的 Vue 应用程序。

所以我们需要下载编译器和支持vue模板语法的编辑器

这里使用的是vscode和vue的官方插件volar

  1. 先下载Vs code

有许多不同的编辑器可用于 Vue 项目。 我们使用 VS Code 编辑器。 下载 VS Code 并安装。

  1. 添加volar插件

要在编辑器中使用 *.vue 文件突出显示和自动完成,请打开 VS Code,转到左侧的”扩展”。 搜索”Volar”并安装下载次数最多且描述为”Vue 3 的语言支持”的扩展。

Screenshot Volar Extension

  1. 下载node.js

这是因为我们的构建工具,编译器vite要使用node.js

下载并安装最新版本的 Node.js,因为 Vue 构建工具”Vite”在此基础上运行。

Node.js 是一个开源服务器端 JavaScript 运行时环境。

创建我们的项目

使用终端,进入到我们的工作目录

  1. 初始化vue项目
1
npm init vue@latest
  1. 填写项目配置

会让你填写项目名称,项目是否支持typescript语法之类的…

项目名中不要存在大写

新手项目我们直接都选择否即可

img

  1. 现在项目创建完毕,安装依赖运行项目

img

我们先进入项目内部cd firstsfc

然后安装依赖npm install或者cnpm install(cnmp install是npm的国内镜像,安装的更快)

然后使用开发服务器node.js中的,运行这个项目npm run dev

然后就可以看到输出了项目的网址

img

项目文件快速介绍

在我们创建的vue工程中,可以看到在顶级目录下src文件夹中的文件就是源文件

img

main.js告诉vite构建器如何基于App.vue(这个里面就是vue实例代码)构建vue项目,告诉了这个项目由那些文件构成

我们在下面的index.html中导入这个main.js即可,实际上在导入的时候main.js已经编程编译后的js文件了

1
2
3
4
5
6
import "/src/assets/main.css"

import {createApp} from "/node_modules/.vite/deps/vue.js?v=a245d952"
import App from "/src/App.vue?t=1712223247435"

createApp(App).mount('#app')

可以看到,变成了对于本地.vite中的vue.js的导入

App.vue也变成了对于编译后的文件的导入

就和我们之前使用script标签给出CDN链接告诉浏览器如何运行我们的vue代码是一样的,同时告诉浏览器如何将vue实例挂载到标签上

App.vue在同一示例项目文件夹中,找到”App.vue”文件并将其打开。 与所有其他 *.vue 文件一样,”App.vue”包含三个部分:<script> 部分、<template> 部分和 <style> 部分。

image-20240404164800651

页面介绍

在App.vue中,一共有三部分

  1. <template>

  2. <script>

  3. <style>

template标签中书写我们的html的内容

在script中直接书写vue实例中的内容

style中书写css样式

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<template>
<h1>{{ message }}</h1>
</template>

<script>
export default {
data() {
return {
message: 'This is some text'
};
}
};
</script>
<style></style>

注意,export default 使得 ‘main.js’ 可以用 import App from './App.vue' 捕获数据,以便将其挂载到 ‘index.html’ 内的 <div id="app"> 标签上。

但是这是之前的选项式API风格

在Vue3之后推出了组合式API,就不需要使用export default了

可以直接通过defineProps,defineComponent直接定义

Vue组件

使得我们的可以动态拓展我们的网页

1 编写组件

创建一个组件并将其添加到我们的项目中。

  1. src 文件夹内创建一个新文件夹 components
  2. components 文件夹中,创建一个新文件 FoodItem.vue。 通常使用 PascalCase 命名约定来命名组件,不带空格,并且所有新单词都以大写字母(也是第一个单词)开头。
  3. 确保 FoodItem.vue 文件如下所示:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<template>
<div>
<h2>{{ name }}</h2>
<p>{{ message }}</p>
</div>
</template>

<script>
export default {
data() {
return {
name: 'Apples',
message: 'I like apples'
}
}
};
</script>

<style></style>

每一个组件自成一派

有自己的html表现

有自己的vue实例逻辑

有自己的css样式

小坑提示

实际上