共计 3463 个字符,预计需要花费 9 分钟才能阅读完成。
watch
侦听器
watch
侦听器允许开发者监视数据的变化,从而针对数据的变化做特定的操作
const vm = new Vue({
el: '#app',
data: {
username: ''
},
watch: {
// 监听 username 的变化
// newVal 是 “变化后的新值”,oldVal 是 “变化之前的旧值”
username(newVal, oldVal) {
console.log(newVal, oldVal)
}
}
})
immediate
选项
默认情况下,组件在初次加载完毕后不会调用 watch
侦听器,如果想让 watch
侦听器立即被调用,则需要使用 immediate
选项:
watch: {
// 定义对象格式的侦听器
username: {
// handler 是固定写法,表示当前 username 的值变化时,自动调用 handler 处理函数
handler(newVal, oldVal) {
if(newVal === '') return
axios({
method: 'GET',
url: 'https://www.escook.cn/api/finduser/' + newVal,
data: {}
}).then(res => {
console.log(res)
console.log(res.data.message)
})
},
// 表示页面初次渲染好之后,就立即触发当前的 watch 侦听器
immediate: true
}
}
deep
选项
如果 watch
侦听的是一个对象,如果对象中的属性发生了变化,则无法被监听到,此时需要使用 deep
选项:
const vm = new Vue({
el: '#app',
data: {
info: {
username: 'admin'
}
},
watch: {
info: {
handler(newVal) {
console.log(newVal)
},
deep: true
}
}
})
监听对象单个属性变化
如果只想监听对象中单个属性的变化,则可以按照以下方式定义 watch
侦听器:
const vm = new Vue({
el: '#app',
data: {
info: {
username: 'admin'
}
},
watch: {
'info.username': {
handler(newVal) {
console.log(newVal)
}
}
}
})
计算属性
计算属性指的是通过一系列运算之后,最终得到一个属性值
这个动态计算出来的属性值可以被模板结构或 methods
方法使用:
const vm = new Vue({
el: '#app',
data: {
r: 0,
g: 0,
b: 0
},
computed:{
rgb() {
return `rgb(${this.r}, ${this.g}, ${this,b})`
}
},
methods: {
show() {
console.log(this.rgb)
}
}
})
计算属性特点:
虽然计算属性在声明的时候被定义为方法,但是计算属性的本质是一个属性
计算属性会缓存计算的结果,只有计算属性依赖数据变化时才会重新进行运算
vue-cli
vue-cli
是 Vue.js 开发的标准工具,它简化了程序员基于 webpack
创建工程化的 Vue 项目的过程
单页面应用程序
单页面应用程序(Single Page Application)简称 SPA,顾名思义,指的是一个 Web 网站中只有唯一的一个 HTML 页面,所有的功能与交互都在这唯一的一个页面内完成
安装和使用 vue-cli
vue-cli
是 npm 上的一个全局包
npm install -g @vue/cli
基于 vue-cli
快速生成工程化的 Vue 项目
vue create 项目名称
Vue 项目中 src 目录的构成
assets
文件夹:存放项目中用到的静态资源文件,例如:css、图片资源components
文件夹:程序员封装的、可复用的组件,都有放到 components 目录下main.js
是项目的入口文件,整个项目的运行,要先执行 main.jsApp.vue
是项目的跟组件
Vue 项目的运行流程
在工程化的项目中,vue 要做的事情很单纯:通过 main.js 把 App.vue 渲染到 index.html 指定区域中
其中
- App.vue 用来编写待渲染的模板解构
- index.html 中需要预留一个 el 区域
- main.js 把 App.vue 渲染到了 index.html 所预留的区域中
vue 组件
vue 是一个支持组件化开发的前端框架
vue 中规定:组件后缀名是 .vue,之前接触到的 App.vue 文件本质上就是一个 vue 组件
vue 组件的三个组成部分
- template -> 组件的模板结构
- script -> 组件的 Javascript 行为
- style -> 组件的样式
组件之间的父子关系
- 组件在被封装好之后,彼此之间是相互独立的,不存在父子关系
- 在使用组件的时候,根据彼此的嵌套关系,形成了父子关系、兄弟关系
使用组件的三个步骤
- 使用
import
语法导入需要的组件 - 使用
components
节点注册组件 - 以标签形式使用刚才注册的组件
通过 components
注册的是私有子组件
在组件 A 的components 节点下,注册了组件 F
则组件 F 只能用在组件 A 中,不能被用在组件 C 中
注册全局组件
在 vue 项目中的 main.js
入口文件,通过 Vue.component()
方法,可以注册全局组件:
// 导入需要全局注册的组件
import Count from '@/components/Count.vue'
// 参数1:字符串格式,表示组件的 “注册名称”
// 参数2:需要被全局注册的那个组件
Vue.component('MyCount', Count)
组件 props
props
是组件的自定义属性,在封装通用组件的时候,合理的使用 props 可以极大的提高组件的复用性
export default {
// 组件的自定义属性
props: ['自定义属性A', '自定义属性B', '其他自定义属性...'],
// 组件的私有数据
data() {
return { }
}
}
props
是只读的
vue 规定组件中封装的自定义属性是只读的,程序员不能直接修改 props
的值,否则会直接报错
想要修改 props
的值,可以把props
的值转存到 data 中,因为 data 中的数据是可读可写的
props: ['init'],
data() {
// 把 this.init 的值转存到 count
count: this.init
}
props
的 default
默认值
在声明自定义属性时,可以通过 default
来定义属性的默认值:
export default {
props: {
init: {
// 用 default 属性定义属性的默认值
default: 0
}
}
}
props
的 tyep
类型
在声明自定义属性时,可以通过 type 来定义属性的值类型:
export default {
props: {
init: {
// 用 default 属性定义属性的默认值
default: 0,
// 用 type 属性定义的值类型
// 如果传递过来的值不符合此类型,则会在终端报错
tyep: Number
}
}
}
props
的 required
必填项
在声明自定义属性时,可以通过 required
选项,将属性设置为必填项,强制用户必须传递属性的值:
export default {
props: {
init: {
// init 的默认值
default: 0,
// 值类型为 Number 数字
tyep: Number,
// 必须项校验
required: true
}
}
}
组件之间样式冲突问题
默认情况下,写 .vue 组件中的样式会全局生效,因此很容易造成多个组件之间的样式冲突问题,导致组件之间样式冲突的原因是:
- 单页面应用程序中,所有组件的 DOM 结构,都是基于唯一的 index.html 页面进行呈现的
- 每个组件中的样式,都会影响整个 index.html 页面的 DOM 元素
style
节点的 scoped
属性
为了提高开发效率和开发体验,vue 为 style 节点提供了 scoped
属性,从而防止组件之间的样式冲突问题:
<style lang="less" secped>
</style>
/deep/
样式穿透
如果当前组件的 style 节点添加了 scoped 属性,则当前组件的样式对其子组件是不生效的,如果想让某些样式对子组件生效,可以使用 /deep/
深度选择器
<style lang="less" secped>
.title {
color: skyblue; // 不加 /deep/ 时,生成的选择器格式为 .title[data-v-3c83f0b7]
}
/deep/ .title {
color: skyblue; // 加上 /deep/ 时,生成的选择器格式为 [data-v-3c83f0b7] .title
}
</style>