一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第28天,点击查看活动详情。
watch
当需要监听某个数据是否发生改变,就要用到watch。
基本使用
/*
watch: {
// 只要属性发生了改变,这个函数就会执行
属性: function () {
}
}
*/
watch: {
// 参数1: value 变化后的值
// 参数2: oldValue 变化前的值
msg (value, oldValue) {
console.log('你变了', value, oldValue)
}
}
复杂类型的监听
如果监听的是复杂数据类型,需要深度监听,需要指定deep为true,需要用到监听的完整的写法。
- 默认情况下,watch只能监听到简单类型的数据变化,如果监听的是复杂类型,只会监听地址是否发生改变,不会监听对象内部属性的变化。
- 需要使用监听的完整写法,是一个对象。
watch: {
// friend (value) {
// console.log('你变了', value)
// }
friend: {
// handler 数据发生变化,需要执行的处理程序
// deep: true 如果true,代表深度监听,不仅会监听地址的变化,还会监听对象内部属性的变化
// immediate: 立即 立刻 是否立即监听 默认是false 如果是true,代表页面一加载,会先执行一次处理程序
handler (value) {
console.log('你变了', value)
},
deep: true,
immediate: true
}
},
组件化开发
组件就是一个个可复用的UI模块,一个组件对应一个vue实例 (每个组件都要有一个vue实例来管理)。组件化开发 指的是根据封装的思想,把页面上可重用的部分封装为组件,从而方便项目的开发和维护。
一个页面,可以拆分成一个个组件,一个组件就是一个整体,每个组件可以有自己独立的结构样式和行为。
组件化开发的好处主要体现在以下两方面:
- 提高了前端代码的复用性和灵活性
- 提升了开发效率和后期的可维护性
组件的注册
我们创建使用的是App.vue根组件,这个比较特殊,是最大的一个根组件。而App.vue根组件内,还可以写入一些小组件,而这些组件,要使用,就需要先注册。
注册组件有两种注册方式,全局注册和局部注册两种。
- 被全局注册的组件,可以在任意的组件模板范围中使用 (每个组件都是一个vue实例)。
- 被局部注册的组件,只能在当前注册的组件模板范围内使用。
全局组件
全局注册: 被全局注册的组件,可以在任意的组件模板范围中使用。
-
新建components文件夹,准备三个文件hm-header.vue,hm-main.vue,hm-footer.vue。
-
在main.js中导入。
import HmHeader from './components/hm-header.vue'
import HmMain from './components/hm-main.vue'
import HmFooter from './components/hm-footer.vue'
- 全局注册。
// 全局注册组件
Vue.component('hm-header', HmHeader)
Vue.component('hm-main', HmMain)
Vue.component('hm-footer', HmFooter)
- 使用组件,将注册好的组件当成 html 标签使用。
<template>
<div class="container">
<hm-header></hm-header>
<hm-main></hm-main>
<hm-footer></hm-footer>
</div>
</template>
局部注册
局部注册: 被局部注册的组件,只能在当前注册的组件模板范围内使用。
- 在 App.vue 中导入。
import HmHeader from './components/hm-header.vue'
import HmMain from './components/hm-main.vue'
import HmFooter from './components/hm-footer.vue'
- 局部注册。
export default {
name: 'MyApp',
components: {
'hm-header': HmHeader,
'hm-main': HmMain,
'hm-footer': HmFooter
}
}
- 使用局部注册的组件。
<template>
<div class="container">
<hm-header></hm-header>
<hm-main></hm-main>
<hm-footer></hm-footer>
</div>
</template>
组件名的大小写
在进行组件的注册时,定义组件名的方式有两种:
-
注册使用短横线命名法,例如 hm-header 和 hm-main。
Vue.component('hm-button', HmButton)使用时
<hm-button> </hm-button> -
注册使用大驼峰命名法,例如 HmHeader 和 HmMain。
Vue.component('HmButton', HmButton)使用时
<HmButton> </HmButton>和<hm-button> </hm-button>都可以。
推荐定义组件名时, 用大驼峰命名法, 更加方便
全局注册
app.component('HmButton', HmButton)
局部注册:
components: {
HmHeader,
HmMain,
HmFooter
}
使用时, 推荐遵循html5规范, 小写横杠隔开
<hm-header></hm-header>
<hm-main></hm-main>
<hm-footer></hm-footer>
组件的样式冲突scoped
默认情况下,写在组件中的样式会全局生效,因此很容易造成多个组件之间的样式冲突问题。根本原因是单页应用程序中,所有组件的结构,都是基于唯一的 index.html 页面进行呈现的,组件样式默认会作用到全局,就会影响到整个 index.html 中的 dom 元素。
- 全局样式: 默认组件中的样式会作用到全局。
- 局部样式: 可以给组件加上 scoped 属性, 可以让样式只作用于当前组件。
<style lang="less" scoped>
div {
background-color: pink;
}
</style>
原理:
- 添加scoped后, 会给当前组件中所有元素, 添加上一个自定义属性。
- 添加scoped后, 每个style样式, 也会加上对应的属性选择器。
最终效果: 必须是当前组件的元素, 才会有这个自定义属性, 才会被这个样式作用到。