【vue2.0入门】vue单文件组件
目录
- 引言
- 一、配置编辑器vue2代码片段模版
- 1. 配置vue2代码模版
- 2. 使用vue模版
- 二、模版介绍
- 1. template区域
- 2. script 区域
- 2.1 name
- 2.2 components
- 2.3 props
- 2.4 data
- 2.5 computed
- 2.6 watch
- 2.7 methods
- 2.8 生命周期函数
- 3. style 区域
- 三、总结
引言
本系列教程旨在帮助一些零基础的玩家快速上手前端开发。基于我自学的经验会删减部分使用频率不高的内容,并不代表这部分内容不重要,只是对于初学者来说没必要一开始就学的面面俱到。我希望可以先通过主干内容带大家入门前端,细节技巧性内容,可以在后续的开发工作中自行发现并掌握。
在上一篇 【vue2.0入门】认识vue工程 中,我们已经对vue工程有了最基础的了解,这些目前就够了。其他的内容就算现在不去关心也暂时不会影响你进行常规页面开发,本篇我们开始认识一下vue的单文件组件,这是我们将来vue项目开发主要的编码部分。
一、配置编辑器vue2代码片段模版
在vue项目中,我们所需要编写的页面文件大都是以
.vue
为后缀的文件,它们都有共同的格式。我们可以利用vscode的代码片段,提前将这些格式准备好,一键生成。
1. 配置vue2代码模版
- 如图所示打开配置
新代码片段
- 点选
新代码片段
后提示输入代码片段文件名,随意取一个就行。
回车键确认
会自动弹出一个配置页面,内容是一个json格式的对象。
- 按照以下我给你提供的代码片段模版
完全替换
配置页面的json对象。
键盘按下Ctrl + s
保存文件并关闭
{"生成vue模板": {"prefix": "vue2","body": ["<template>"," <div></div>","</template>","","<script>","export default {"," //import引入组件才能使用"," components: {},"," props: {},"," data() {"," return {",""," };"," },"," // 计算属性"," computed: {},"," // 监听data中的数据变化"," watch: {},"," // 方法集合"," methods: {",""," },"," // 生命周期,创建完成时(可以访问当前this实例)"," created() {",""," },"," // 生命周期:挂载完成时(可以访问DOM元素)"," mounted() {",""," },"," beforeCreate() { },//生命周期:创建之前"," beforeMount() { },//生命周期:挂载之前"," beforeUpdate() { },//生命周期:更新之前"," updated() { },//生命周期:更新之后"," beforeDestroy() { },//生命周期:销毁之前"," destroyed() { },//生命周期:销毁完成"," activated() { },//如果页面有keep-alive缓存功能,这个函数会触发执行","}","</script>","<style scoped>","$4","</style>"],"description": "生成vue2模板"}
}
2. 使用vue模版
我们就利用
HelloWorld.vue
组件做测试。
- 在vscode中打开文件:
src\components\HelloWorld.vue
- 键盘按下
Ctrl + a
选中所有内容,按下delete
键删除所有内容 - 在文件内输入
vue2
,提示代码片段,按下键盘tab
键补全代码
- 当你完成以上操作后你的文件应该长这样
二、模版介绍
以
.vue
为后缀的文件,一般都包含三个区域template
、script
、style
,分别对应原生前端开发的html
、js
、css
三个部分,比较符合一开始做前端开发的编码习惯。
1. template区域
这里就是编写html的区域,你可以完全按照原来html学习时的内容进行编写。
需要注意的点!!!
在vue2版本中,每一个template内都需要有一个根节点,当前页面里的所有内容都需要在根节点内部完成。你可以把这个根节点理解为html中的body标签,你的其他标签代码,写在里边就行。
2. script 区域
这部分可能和原来学习的js编写有点区别,vue2是以配置项的形式整合了js脚本。
script部分主要包含以下内容:
- 数据定义:props、data、computed
- 数据监听:watch
- 函数定义:methods
- 生命周期函数:beforeCreate、created、beforeMount、mounted、beforeUpdate、updated、beforeDestroy、destroyed
所有的数据定义:props、data、computed,或是函数定义:methods,以及生命周期函数都是以键值对形式存放在export default {}
中。
2.1 name
name 属性是一个可选的选项,它主要用于指定组件的名称
其主要作用有:
- 当使用 Vue Devtools 调试代码时,组件的名称会在组件树中显示。这样可以帮助开发者更容易地识别和追踪组件,特别是在大型项目中,组件树可能会变得非常复杂。
- 如果你需要创建一个递归组件(即组件在其自身的模板中引用自己),那就需要给组件命名。Vue 需要知道哪个组件是递归调用的,因此 name 属性在这种情况下是必需的。
- 当发生错误时,Vue 会生成错误报告。如果组件有名称,错误报告中会包含组件的名称,这有助于更快地定位问题。
命名规范:
- 小驼峰命名法,例如:myComponent
- 具有一定的意义,例如:userInfo
- 命名唯一性,当遇到两个组件属于不同模块,但是作用是一样的,那么就需要根据模块的区别进行命名区别,例如:adminUserList 和 customerUserList
- 避免使用js预留的关键字,例如:class、function、delete、new
2.2 components
用于注册或引用其他组件。在这个对象中,键名是组件的名字,值则是组件的定义对象或者通过import导入的组件(当键名和键值定义的变量名一致时可以简写为一个)。
如下图以 App.vue
引用当前文件 HelloWorld
组件为例
// 简写形式components: {HelloWorld}// 写法等价于,建议使用上边的简写形式components: {HelloWorld: HelloWorld}
这里的流程是
- 先通过
import
关键字将./components/HelloWorld.vue
这个目录下vue文件作为组件引入,并起名为HelloWorld
。一般与文件名相同就行,也可以随便取别的(一个vue文件中可能要引用多个组件,注意别重名)。 - 通过
components
配置项,将HelloWorld
组件注册进入当前的vue文件上下文环境中。 - 在template中使用
HelloWorld
组件(必须引用、注册两步操作完成后才可以使用)。
2.3 props
定义了组件接收的外部参数。这些参数可以从父组件传递给子组件,使得子组件能够更加灵活地复用。
还是以 App.vue
引用当前文件 HelloWorld
组件为例
- 在
App.vue
引入、注册并使用HelloWorld
组件,在组件标签上添加msg
属性并赋值。这是个自定义的属性,名字随便取(最好是有特殊含义的单词,不能与id、class这些固有属性重名)
- 在组件内部通过props来接收这个传入的属性,这里的
msg
对象与App.vue
中HelloWorld
标签里的msg
属性相对应。- 通过配置
type
,限定父组件(App.vue)传进来的值是否匹配类型(规避一些传值类型错误的bug)。 - 配置
default
提供默认值,谨防父组件在使用HelloWorld
组件时没有传入msg属性,而HelloWorld
组件内部又确实需要这个属性。
- 通过配置
props: {msg: {type: String,default: "hello world!",},},
当传入数据类型不同时,编写方法也有些不一样(引用类型的default是一个函数),以下是常用类型的举例:
- 在template中,可以通过
{{ 变量名 }}
使用。 - 在script中,任何可以编写js代码的地方都可以通过
this.变量名
获取到该变量的值。(this代表当前组件的实例化对象
,props接收到的变量都会作为属性赋值给组件实例化对象
)。 - props传入的组件的变量,一般可以认为是只读变量。禁止对这些变量值做修改,防止出现意外bug。
- 如果需要修改 props 中的属性值,则需要从源头修改。对父组件传入子组件的属性值进行修改,也称之为单向数据流(数据只能从父组件流入子组件,不能回流,避免出现bug)。
2.4 data
本身是一个函数,返回一个对象,该对象包含了组件实例的所有响应式数据属性。每次创建一个新的组件实例时,都会调用这个函数以确保不同实例之间的数据隔离。
data里的内容就相当于js文件中定义的变量。
data() {return {localMsg: "local msg",};},
- 在template中,可以通过
{{ 变量名 }}
使用。 - 在script中,任何可以编写js代码的地方都可以通过
this.变量名
获取到该变量的值。(this代表当前组件的实例化对象
,data定义的变量都会作为属性赋值给组件实例化对象
)。 - data中定义的变量,可以在当前vue文件中能够执行js的地方进行修改值的操作。
- 注意不要和props中的变量名重复。
2.5 computed
计算属性,用于声明式地描述基于其他数据动态计算出的值。计算属性是基于它们的依赖进行缓存的,只有当依赖的数据发生变化时,计算属性才会重新求值。
我们可以理解为 computed
的作用就是:利用 data
或是 props
中定义的变量参与到表达式运算中,得到一个新的符合需求的完整值,并将其返回(return 值是必须的)
// 一般这么写就行,可能和之前学的对象键值对的结构不同,这个属于es6的简写形式computed: {newPropsMsg() {return this.msg + "做了一些加工1";},newLocalMsg() {return this.localMsg + "做了一些加工2";},},// 你同样可以按照原有的对象键值对的形式编写,但是建议用上边的写法computed: {// 使用传统的函数表达式newPropsMsg: function () {return this.msg + "做了一些加工1";},newLocalMsg: function () {return this.localMsg + "做了一些加工2";},},
this.msg
就是获取到props
中的msg
。this.localMsg
就是获取到data
中的localMsg
- 在
template
中,可以通过{{ 变量名 }}
使用。 - 在
script
中,任何可以编写js代码的地方都可以通过this.变量名
获取到该变量的值。(this
代表当前组件的实例化对象
,computed
加工过的变量都会作为属性赋值给组件实例化对象
)。 computed
加工的组件变量,一般可以认为是只读变量。禁止对这些变量值做修改,防止出现意外bug。- 如果需要修改
computed
加工的组件变量,则需要从源头修改。例如修改参与到computed变量表达式
里的data
属性。或是修改父组件传入子组件的props属性。 - 注意不要和props、data中的变量名重复。
2.6 watch
监听器,用于观察和响应Vue实例上的数据变动。
watch 可以用于监听数据的变化,可以监听props、data、computed中定义的变量。
两种写法
- monitorVariables的监听属于简写,当你需要监听一个基本数据类型的变化时可以使用简写。
- monitorObject的监听属于完整写法,vue的监听器默认只监听最表层的变化,也就是基本数据类型的变化。或是引用数据类型整体重复赋值时也会被监听到(因为引用的内存地址变化了)。
- 当监听引用数据类型的属性变化时,设置
deep
属性为true
。 - 当需要页面初始化是默认触发一次监听时(由undefined变化为初始化的值),设置
immediate
属性为true
。 - 当不填这俩属性时,默认都为false。
- hander是默认监听触发函数,其参数就是你监听变量的新旧值。
- 当监听引用数据类型的属性变化时,设置
watch: {monitorVariables(newVal, oldVal) {console.log("newVal monitorVariables", newVal);console.log("oldVal monitorVariables", oldVal);},// 监听对象属性的变化monitorObject: {handler(newVal, oldVal) {console.log("newVal monitorObject", newVal);console.log("oldVal monitorObject", oldVal);},immediate: true, // 初始化时立即执行deep: true, // 深度监视},},
2.7 methods
vue文件中定义函数的区域。包含各种组件的方法,这些方法可以在模板中绑定事件处理器,也可以在组件内部调用。
定义方式与computed类似,但是不强调必须return内容。可以根据函数功能需求自行决定是否返回内容。
methods: {getLocalMsg() {console.log(this.localMsg);},},
vue文件中的方法函数一般只有三种调用方式
- 将函数绑定到template中标签的事件处理器上,例如
- @click 点击事件
- @mouseenter 鼠标移入事件
- @mouseleave 鼠标移出事件
- @change input标签的数据变更时触发事件
- 其他组件自定义事件
- vue组件生命周期内自动调用
- 其他函数触发后,函数体内部调用另一个函数。
2.8 生命周期函数
vue的生命周期函数也是函数,他会随着vue组件页面的数据准备、加载、更新、移除等阶段自动执行,如果你编写的函数需要在这些阶段被自动调用而不是手动触发,那么就可以把你写的函数在这些生命周期函数里调用。
初学阶段你只需要关注created、mounted和beforeDestroy这三个生命周期函数就行。当你的经验逐渐丰富,代码执行的细度更加精确之后,可以考虑深入了解一下剩余的几个生命周期函数。
created
- 什么时候调用:在实例创建完成后立即调用。在这一步,实例已完成以下的配置:数据观测 (data observer),属性和方法的运算,watch/event 事件回调。
- 特点:可以访问到 props、data、computed 和 methods,但 DOM 尚未生成。
- 用途:适合进行数据初始化、发送网络请求等操作。
mounted
- 什么时候调用:在实例挂载完成后被调用,此时 el 已经被挂载到实例上,可以操作 DOM。
- 特点:DOM 已经生成,可以访问到真实的 DOM 元素。
- 用途:适合进行 DOM 操作、初始化第三方库、启动定时器等。
beforeDestroy
- 什么时候调用:实例销毁之前调用。在这一步,实例仍然是完全可用的。
- 特点:可以访问到所有 Vue 实例的数据和方法。
- 用途:适合进行资源清理,比如停止定时器、销毁第三方库实例化对象等。
官网有个经典示意图
3. style 区域
这部分和原始的css编写没有任何区别
因为项目会多人协作进行开发,组件间难免会存在样式的选择器冲突,所以墙裂推荐每个vue单文件的style标签都要添加 scoped
属性,vue会自动根据组件的唯一值编码,进行区分。
<style scoped>
.test {color: red;
}
</style>
有了这个唯一值区分后,两个组件中 test
类就不会互相影响。
在vue项目中常常还会引入css预处理工具,例如sass、less、Stylus ,(具体功能引入一般在项目初期由研发负责人处理好),开发人员需要在编写style时添加一个标识即可。
<style lang="scss" scoped>
// 样式表
</style>// 或是
<style lang="less" scoped>
// 样式表
</style>// 或是
<style lang="stylus" scoped>
// 样式表
</style>
使用css预处理器可以显著提高开发效率和代码质量。通过变量、嵌套、混合、继承、函数、条件语句和循环等功能,你可以编写更加简洁、模块化和易于维护的样式代码。
近几年css的标准也在逐步完善,目前可以支持变量、内置的函数,新版本的浏览器可以支持嵌套,其他高级功能暂时还不能够支持。
不过也不用过于焦虑,原生css已经可以支持你完成所有的开发工作。只是当你需要编写一个类似于UI组件库等标准化的前端组件时,利用css预处理器的函数、继承、混合、条件语句、循环这些高级功能会大大提高效率。与此同时它所带来的学习成本也是需要考虑的东西。
具体是使用原生还是预处理器可以根据项目需求和学习成本综合考虑后做取舍。
三、总结
以上即为vue单文件组件常用的内容,有了这些内容做支撑,加上你原有的html、js、css的基础知识,就可以在vue项目中编写页面了。在开发时需要贯彻组件化开发思想,从项目整体设计的维度以及单一功能的维度共同考虑,抽离出合适的组件,互相拼凑完成页面编写。
在下篇中,我会结合应用场景讲解如何使用vue的语法技巧,帮助你更快的进行页面编写。通过操作数据来控制页面内容的表现。
再接再厉~