失眠网,内容丰富有趣,生活中的好帮手!
失眠网 > Vue「三」—— vue 侦听器 vue 计算属性 vue-cli vue 组件

Vue「三」—— vue 侦听器 vue 计算属性 vue-cli vue 组件

时间:2024-06-17 02:53:23

相关推荐

Vue「三」—— vue 侦听器 vue 计算属性 vue-cli vue 组件

本文为 Vue 系列笔记第三篇。参考:>> 黑马程序员 Vue 全套视频教程

系列文章阅读 📑📑

>> Vue「一」—— 前端工程化 、webpack 的基本使用及常用配置

>> Vue「二」—— vue 基本使用 、vue 指令 、vue 过滤器

>> Vue「三」—— vue 侦听器、vue 计算属性、vue-cli、vue 组件

>> Vue「四」—— 组件生命周期、数据共享

>> Vue「五」—— 动态组件、插槽、自定义指令

>> Vue「六」—— 前端路由、vue-router

🐾 文章内容预览

一、watch 侦听器1. 侦听器基本语法 2. 对象格式的侦听器 3. immediate 选项4. deep 选项5. 监听对象单个属性的变化二、计算属性三、vue-cli1. 单页面应用程序2. 什么是 vue-cli3. vue-cli 的安装4. vue-cli 的使用5. vue 项目的运行流程四、vue 组件1. vue 中的组件化开发2. vue 组件的三个组成部分3. 组件之间的父子关系4. 私有子组件与全局组件5. 组件的 props6. 组件之间的样式冲突问题

一、watch 侦听器

1. 侦听器基本语法

watch 侦听器 允许开发者监视数据的变化,从而针对数据的变化做特定的操作。也就是 当数据发生变化时,及时做出响应处理 。

下面是采取方法格式来定义侦听器,这种方法比较简便常用。此外,如果遇到某些特殊需求时,也可采取对象格式来定义侦听器(后文介绍)。

<div id="app"><input type="text" v-model="username"></div><script>const vm = new Vue({el: "#app",data: {username: ''},// 侦听器定义在 watch 节点下watch: {username(newVal, oldVal) {console.log('👍👍👍', newVal, oldVal);}}})</script>

文本框中连续输入123,打印效果如下:

>> 几个注意点

所有的侦听器,都应该定义在 watch 节点下。侦听器本质上是一个函数,要监听哪个数据的变化,只需把对应数据名作为方法名即可。注意新值在前面,旧值在后面。此外,这种方法默认不会被自动调用,也就是刚打开页面时不会触发侦听器。

>> 应用场景:使用 watch 检测用户名是否可用

需求:监听 username 值的变化,并使用 axios 发起 Ajax 请求,从服务器获取数据来判断,检测当前输入的用户名是否可用

import axios from 'axios'export default {name: 'MyWatch',data() {return {username: ''}},watch: {async username(newVal, oldVal) {const {data: res } = await axios.get(`/api/finduser/${newVal}`)console.log(res)}}}

2. 对象格式的侦听器

此前侦听器的写法是方法格式的写法,也就是直接将对应数据名作为方法名来写函数。这种方法是最常用的,因为它比较简便。

你也可以利用对象格式来定义 watch 侦听器,如下:

watch: {username: {// handler 是固定写法,表示当 username 的值变化时,自动调用 handler 处理函数handler(newVal, oldVal) {// 。。。}}}

这种语法下,需要将侦听器的响应处理写在handler(){}方法内。

3. immediate 选项

默认情况下,组件在初次加载完毕后不会调用 watch 侦听器。如果想让 watch 侦听器 立即被调用,则需要使用 immediate 选项 。

watch: {username: {handler(newVal, oldVal) {console.log(newVal);},// 默认 false, 控制侦听器是否自动触发imediate: true}}

4. deep 选项

如果 watch 侦听的是一个对象,如果对象中的 属性值发生了变化,则 无法被监听 到。此时需要使用 deep 选项 。

watch: {info: {handler(newVal, oldVal) {console.log(newVal.username);},// 开启深度监听,只要对象中任何属性变化,都会触发// deep 默认值为 falsedeep: true}}

注意:这里的 newVal 是 info 对象,而不是变化的属性值。

5. 监听对象单个属性的变化

如果只想监听对象中 单个属性 的变化,则可以按照如下的方式定义 watch 侦听器。

watch: {'info.username': {handler(newVal, oldVal) {console.log(newVal);}}}

二、计算属性

计算属性指的是通过一系列运算之后,最终得到一个属性值。这个动态计算出来的属性值可以被模板结构或 methods 方法使用。

所有的计算属性都要定义在 computed 节点之下,计算属性在定义时要定义成方法格式。如下所示:

<!-- <div class="box" :style="{ backgroundColor: `rgb(${r}, ${g}, ${b})` }">{{ `rgb(${r}, ${g}, ${b})` }}</div> --><div class="box" :style="{ backgroundColor: rgb }">{{ rgb }}</div>

var vm = new Vue({el: '#app',data: {r: 0, g: 0, b: 0},computed: {rgb() {return `rgb(${this.r},${this.g},${this.b})`;}}});

两点好处:

计算属性提高了代码的复用。当所依赖数据发生变化(data 中数据变化)时,它会自动重新运算。

三、vue-cli

1. 单页面应用程序

单页面应用程序 (Single Page Application)简称 SPA,指的是一个 Web 网站只有唯一的一个 HTML 页面,所有的功能与交互都在这唯一的一个页面内完成。

如上图所示,整个项目都是通过唯一一个 HTML 页面 index.html 来呈现的,这就叫做单页面应用程序。

2. 什么是 vue-cli

vue-cli 是 Vue.js 开发的标准工具。它简化了程序员基于 webpack 创建工程化 Vue 项目的过程。

vue-cli 官网 是这样介绍的:Vue CLI 致力于将 Vue 生态中的工具基础标准化。它确保了各种构建工具能够基于智能的默认配置即可平稳衔接,这样你可以专注在撰写应用上,而不必花好几天去纠结配置的问题。

3. vue-cli 的安装

vue-cli 是 npm 上的一个 全局包,可以通过 npm 进行安装:

npm install -g @vue/cli

4. vue-cli 的使用

在终端下运行如下的命令,创建指定名称的项目

vue create 项目名称

手动选择要安装的模式,建议初学时选择第三项,可以自定义很多功能。

手动选择要安装哪些功能,建议如下配置(空格:选中/ 取消):

选择 vue 的版本,目前先选择 2.x。

选择 css 预处理器,目前只学过 Less,因此选择 Less 即可。

选择第三方插件配置文件如何放置,默认选择第一项,各种文件配置信息独立放置。

是否将此前是选择作为预设,方便以后不用每次都重复同样配置。项目成功创建完成。

>> 分析一下 vue 项目下的 src 目录的构成

assets 文件夹:存放项目中用到的静态资源文件,例如:css 样式表、图片资源。

components 文件夹:存放封装的、可复用的组件。

main.js:项目的入口文件。整个项目的运行,要先执行 main.js。

App.vue: 项目的根组件。

5. vue 项目的运行流程

在工程化的项目中,vue 要做的事情很单纯:通过 main.js 把 App.vue 渲染到 index.html 的指定区域中。

App.vue 用来编写待渲染的 模板结构index.html 中需要预留一个 el 区域main.js 把 App.vue 渲染到了 index.html 所预留的区域

四、vue 组件

1. vue 中的组件化开发

组件化开发 指的是:根据封装的思想,把页面上 可重用的 UI 结构 封装为组件,从而方便项目的开发和维护。

vue 是一个 支持组件化开发 的前端框架。vue 中规定:组件的后缀名是 .vue。之前接触到的 App.vue 文件本质上就是一个 vue 的组件。

2. vue 组件的三个组成部分

每个 .vue 组件都由 3 部分构成,分别是:

template:组件的模板结构script:组件的 JavaScript 行为style:组件的样式

>> template

vue 规定:每个组件对应的 模板结构,需要定义到<template>节点中。如下:

<!--组件的 UI 结构模板--><template><!--此处定义当前组件的 DOM 结构--></template>

❗❗ 注意:

template是 vue 提供的容器标签,只起到 包裹 性质的作用,它不会被渲染为真正的 DOM 元素template中只能包含 唯一的根节点

>> script

vue 规定:开发者可以在<script>节点中封装组件的 JavaScript 业务逻辑 。如下:

<script>// 默认导出,固定写法export default {data() {return {// return 中定义数据};},// 组件中的方法methods: {},// 组件中的侦听器watch: {},// 组件中的计算属性computed: {},// 组件中的过滤器filters: {},};</script>

❗❗ 注意:

组件相关的 data、methods 等等都需要放在export default {}所导出的对象中。.vue 组件中的 data 必须是一个函数,不能直接指向一个数据对象。否则会导致多个组件实例共用同一份数据的问题。

>> style

组件内的<style>节点是可选的,开发者可以在<style>节点中 编写样式 美化当前组件的 UI 结构。如下:

<!--组件的样式--><style>/* 定义样式 */</style>

>> style 中支持 less 语法,可以这么做:

<style>标签上添加lang="less"属性,即可使用 less 语法编写组件的样式:

<style lang="less">/* 定义 less 语法的样式 */</style>

3. 组件之间的父子关系

>> 使用组件的三个步骤

在 App.vue 文件中进行如下操作,即可将 Left 和 Right 组件嵌套在 App 组件中:

使用 import 语法导入需要的组件使用 components 节点 注册组件以 标签形式 使用刚才注册的组件

其中,各组件关系如下:

4. 私有子组件与全局组件

>> 通过 components 注册的是 私有子组件

例如,在组件 A 的 components 节点下,注册了组件 F。则组件 F 只能用在组件 A 中;不能被用在组件 C 中。

可以看出,如果有一个组件频繁的被用到,就变得很麻烦,需要每次引入。这时,我们可以使用下面所要介绍的 全局组件 。

>> 注册 全局组件

在 vue 项目的 main.js 入口文件中,通过ponent()方法,可以注册全局组件。这样以后每次使用时,不再需要重复注册,一劳永逸。

例如,这里打算将 Count.vue 设为全局组件,可以在 main.js 入口文件中这样设置:

此后,在其他组件中使用到这个全局组件 Count.vue 时,只需写标签<MyCount></MyCount>即可。

5. 组件的 props

props 是组件的 自定义属性,在封装通用组件的时候,合理地使用 props 可以极大的提高组件的复用性。

在 Count.vue 组件中设置自定义属性init

export default {// props 是"自定义属性",允许使用者通过自定义属性,为当前组件指定初始值// 自定义属性可以定义多个,可以取任意合法名称props: ['init'],data() {return {// 数据}},}

当使用到 MyCount 组件(上面的 Count.vue)时,就可以这样定义自定义属性:

<MyCount init="6"></MyCount>

❗❗ 注意:上面的init被赋值了一个字符串"6",而不是数字6。这时,如果你想要的赋值是数字型,可以结合v-bind来使用,写成如下形式:

<MyCount :init="6"></MyCount>

>> 此外,再强调几点 props 使用事项

1. props 是只读的

vue 规定:组件中封装的 自定义属性是只读的,程序员不能直接修改 props 的值,否则会直接报错。

<button @click="init += 1">+1</button>

如上代码,点击按钮使得自定义属性init完成自增时,发现网页给出报错:

要想修改 props 的值,可以 把 props 的值转存到 data 中,因为 data 中的数据都是可读可写的。

data() {return {// 把 props 中的 init 值,转存到 count 上count: this.init,};},

2. props 的其他可选项

在声明自定义属性时,还可以将其指定为 对象形式 而非数组形式,同时指定如下可选项:

default:定义属性的默认值type:定义属性的值类型required:将属性设置为必填项,强制用户必须传递属性的值

props: {init: {// 如果外界使用 Count 组件的时候,没有传递 init 属性,则默认值生效default: 0,// init 的值类型必须是 Number 数字type: Number,// 必填项校验required: true}},

6. 组件之间的样式冲突问题

默认情况下,写在 .vue 组件中的 样式会全局生效,因此很容易造成多个组件之间的样式冲突问题。

导致组件之间样式冲突的根本原因是:

单页面应用程序中,所有组件的 DOM 结构,都是基于唯一的 index.html 页面进行呈现的每个组件中的样式,都会影响整个 index.html 页面中的 DOM 元素

>> 如何解决样式冲突问题呢?

为了提高开发效率和开发体验,vue 为 style 节点 提供了 scoped 属性,从而防止组件之间的样式冲突问题。

<style lang="less" scoped>h3 {color: red;}</style>

而它的原理就是,scoped 属性自动为每个组件分配了唯一的 “ 自定义属性 ”。该组件中的 DOM 标签和 style 样式都应用了这个自定义属性,这样就解决了样式冲突的问题。

>> /deep/ 样式穿透

如果给当前组件的 style 节点添加了 scoped 属性,则当前组件的样式 对其子组件是不生效的。如果想让某些样式对子组件生效,可以使用 /deep/ 深度选择器。

<style>/* 当使用第三方组件库的时候,如果有修改第三方组件默认样式的需求,需要用到 /deep/ *//deep/ h5 {color: pink;}</style>

👍👍 应用场景:通过父组件直接修改子组件样式。一般在引入第三方库时,需要修改第三方库中元素样式时使用,从而避免了查找第三方库源码修改的困难。

如果觉得《Vue「三」—— vue 侦听器 vue 计算属性 vue-cli vue 组件》对你有帮助,请点赞、收藏,并留下你的观点哦!

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。