Vue.js 组件
Posted shi_zi_183
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Vue.js 组件相关的知识,希望对你有一定的参考价值。
Vue.js 组件
组件是Vue.js最推崇的,也是最强大的功能之一,核心目标是为了可重用性高,减少重复性的开发。我们可以把组件代码按照template、style、script的拆分方式,放置到对应的.vue文件中。
Vue.js的组件可以理解为预先定义好行为的ViewModel类。一个组件可以预定义很多选型,但最核心的是以下几个:
- 模板 —— 模板生命力数据和最终展现给用户的DOM之间的映射关系。
- 初始数据 —— 一个组件的初始数据状态。对于可复用的组件来说,通常是私有的状态。
- 接受的外部参数 —— 组件之间通过参数来进行数据的传递和共享。参数默认是单向绑定(由上至下),但也可以显示声明为双向绑定。
- 方法 —— 对数据的改动操作一般都在组建的方法内进行。可以通过v-on 指令将用户输入事件和组件方法进行绑定。
- 生命周期钩子函数 —— 一个组件会触发多个生命周期钩子函数,比如created、attached、destroyed等。在这些钩子函数中,我们可以封装一些自定义的逻辑。和传统的MVC相比,这可以理解为Controller的逻辑被分散到了这些钩子函数中。
基础
注册
1、全局注册
Vue.component('didi-component',DIDIComponent)
如上所示,第一个参数是注册组件的名称;第二个参数是组件的构造参数,它可以是Function,也可以是Object。
- Function —— DIDIComponent可以是用Vue.extend()创建的一个组件构造器。
var MyComponent = Vue.extend(
// 选项..
)
- Object —— DIDIComponent传入选项对象,Vue.js在背后自动调用Vue.extend()。
// 在一个步骤中扩展与注册
Vue.component('didi-component',
template: '<div>A custom component!</div>'
)
组件在注册之后,便可以在父实例的模块中以自定义元素<didi-component>
的形式使用。要确保在初始化根实例之前注册了组件。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
</head>
<body>
<div id="example">
<didi-component></didi-component>
</div>
</body>
<script>
Vue.component('didi-component',
template: '<div>A custom component!</div>'
)
new Vue(
el: '#example'
)
</script>
</html>
注: 组件的模板替换了自定义元素,自定义元素的作用只是作为一个挂载点。可以用实例选项replace决定是否替换自定义元素。
2、局部注册
不需要每个组件都全局注册,可以让组件只能用在其他组件内。我们可以用实例选项components注册。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
</head>
<body>
<div id="example">
<didi-component></didi-component>
</div>
</body>
<script>
var Child = Vue.extend(
template: '<div>i am child!</div>',
replace: true
)
var Parent = Vue.extend(
template: '<div><p>i am parent</p><br><child></child></div>',
components:
// <didi-component>只能用在父组件模板内
'child': Child
)
// 创建根实例
new Vue(
el: '#example',
components:
'didi-component': Parent
)
</script>
</html>
注:如果你在模板中尝试写了多个跟元素时,Vue 会显示一个错误,并解释道 every component must have a single root element (每个组件必须只有一个根元素)。你可以将模板的内容包裹在一个父元素内,来修复这个问题。
数据传递
总结下来,Vue.js 组件之间有三种数据传递方式:
- props
- 组件通信
- slot
1、props
"props"是组件数据的一个字段,期望从父组件传下来数据。因为组件实例的作用域是孤立的,这意味着不能并且不应该在子组件的模板内直接引用父组件的数据,所以子组件需要显式地用props选项来获取父组件的数据。props选项可以是字面量,也可以是表达式,还可以绑定修饰符。
1)字面量语法
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
</head>
<body>
<div id="example">
<child msg="hello"></child>
</div>
</body>
<script>
Vue.component('child',
// 声明props
props: ['msg'],
// prop可以用在模板内
// 可以用`this.msg`设置
template: '<span>msg,DDFE!</span>'
)
new Vue(
el: '#example'
)
</script>
</html>
HTML特征不区分大小写。名字形式为camelCase的props用作特性时,需要转换为kebab-case形式(短横线隔开)。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
</head>
<body>
<div id="example">
<child my-component="hello!"></child>
</div>
</body>
<script>
var myComponent = Vue.extend(
props: ['myComponent'],
template: '<span>myComponent,DDFE!</span>'
)
Vue.component('child',myComponent)
new Vue(
el: '#example'
)
</script>
</html>
2)动态语法
类似于用v-bind将HTML特性绑定到一个表达式,我们也可以用v-bind将动态props绑定到父组件的语法。每当父组件的数据变化时,该变化也会传到给子组件
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
</head>
<body>
<div id="example">
<didi-props></didi-props>
</div>
</body>
<script>
var Child = Vue.extend(
// 声明props
props: ['didiProps'],
template: '<div>didiProps DDFE!</div>'
)
var Parent = Vue.extend(
template: '<div><p>i am parent</p><br/><child :didi-props="hello"></child></child></div>',
data: function()
return 'hello':'hello,'
,
components:
// <child>只能用在父组件模板内
'child': Child
)
// 创建根实例
new Vue(
el: '#example',
components:
'didi-props': Parent
)
</script>
</html>
3)prop验证
组件可以为props指定验证要求。当组件给其他人使用时,可以确保其他人正确地使用组件。此时prop的值是一个对象。
Vue.component('my-component',
props:
// 基础的类型检查 (`null` 和 `undefined` 会通过任何类型验证)
propA: Number,
// 多个可能的类型
propB: [String, Number],
// 必填的字符串
propC:
type: String,
required: true
,
// 带有默认值的数字
propD:
type: Number,
default: 100
,
// 带有默认值的对象
propE:
type: Object,
// 对象或数组默认值必须从一个工厂函数获取
default: function ()
return message: 'hello'
,
// 自定义验证函数
propF:
validator: function (value)
// 这个值必须匹配下列字符串中的一个
return ['success', 'warning', 'danger'].indexOf(value) !== -1
)
type 可以是下列原生构造函数中的一个:
- String
- Number
- Boolean
- Array
- Object
- Date
- Function
- Symbol
额外的,type 还可以是一个自定义的构造函数,并且通过 instanceof 来进行检查确认。
2、组件通信
尽管子组件可以用this.$parent
访问它的父组件,父组件有一个数组this.$children
,包含它所有的子元素,根实例的后代可以用this.$root
访问根实例,不过子组件应当避免直接依赖父组件的数据,尽管显式地使用props传递数据。另外,在子组件中修改父组件地状态是非常糟糕地做法,因为: - 父组件与子组件紧密地耦合
- 只看父组件,很难理解父组件的状态,因为它可能被任意子组件修改!在理想情况下,只有组件自己能修改其状态。
因为作用域是有层次的,所以我们可以在作用域链上传递事件。通常来说,选择事件传递方法,一个好的经验规则就是:查看触发事件的作用域。 - $on() —— 监听事件
- $emit() —— 把事件沿着作用域向上派送
以上是关于Vue.js 组件的主要内容,如果未能解决你的问题,请参考以下文章