vue.js慢速入门(2)
4.组件使用基础
- 什么是组件?组件可以理解为可重用的自定义HTML。
- 可以使用一堆组件来构造大型应用,任意类型的应用界面都可以抽象为一个组件树:
- 可以把组件代码按照template、style、script的拆分方式,放置到对应的.vue文件中。
- 组件预定义选项中最核心的几个:
模板(template)、初始数据(data)、接受的外部参数(props)、方法(methods)、生命周期钩子函数(lifecycle hooks)。
4.1 基本步骤
使用组件首先需要创建构造器:
var MyComponent = Vue.extend({
// 选项...
})
要把这个构造器用作组件,需要用 Vue.component(tag, constructor) 注册 :
// 全局注册组件,tag 为 my-component
Vue.component('my-component', MyComponent)
然后使用:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title></title>
</head>
<body>
<div id="xxx">
<my-component></my-component>
</div>
</body>
<script src="js/vue.js"></script>
<script>
var myComponent = Vue.extend({
template: '<p>9898不得了!</p>'
});
Vue.component('my-component', myComponent);
new Vue({
el: '#xxx'
});
</script>
</html>
其中,
- Vue.component('my-component', MyComponent)这种是全局注册,第一个参数是注册组件的名称,第二个参数是组件的构造函数;
- 选项对象的template属性用于定义组件要渲染的HTML;
- 组件的模板替换了自定义元素,自定义元素的作用只是作为一个挂载点。组件挂载在vue实例上才会生效。
- 对于自定义标签名字,Vue.js 不强制要求遵循 W3C 规则(小写,并且包含一个短杠),为了避免不必要的事端尽管遵循这个规则。
4.2 局部注册
用实例选项 components 注册:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title></title>
</head>
<body>
<div id="xxx">
<my-component></my-component>
</div>
</body>
<script src="js/vue.js"></script>
<script>
var myComponent = Vue.extend({
template: '<p>9898不得了!</p>'
});
// Vue.component('my-component', myComponent);
new Vue({
el: '#xxx',
components: {
'my-component': myComponent
}
});
</script>
</html>
也可以在组件中定义并使用其他组件:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title></title>
</head>
<body>
<div id="example">
<xx-component></xx-component>
</div>
</body>
<script src="js/vue.js"></script>
<script>
var Child = Vue.extend({
template: '<div>i am zai</div>',
replace: true
})
var Parent = Vue.extend({
template: '<p>i am baba</p><br/><wa></wa>',
components: {
// <xx-component>只能用在父组件模板内
'wa': Child
}
})
// 创建根实例
new Vue({
el: '#example',
components: {
'xx-component': Parent
}
})
</script>
</html>
其中,子组件只能在父组件的template中使用。
另外,有简化的写法,Vue在背后会自动地调用Vue.extend():
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title></title>
</head>
<body>
<div id="xxx">
<my-component-continue></my-component-continue>
</div>
</body>
<script src="js/vue.js"></script>
<script>
// 局部注册的简化写法
var vm2 = new Vue({
el: '#xxx',
components: {
'my-component': {
template: '<div>9898不得了!</div>'
},
'my-component-continue': {
template: '<div>粮食大丰收!</div>'
}
}
})
</script>
</html>
4.3 组件选项问题
在定义组件的选项时,data和el选项必须使用函数。
如果data选项指向某个对象,这意味着所有的组件实例共用一个data。
所以应当使用一个函数作为 data 选项,让这个函数返回一个新对象:
Vue.component('my-component', { data: function(){ return {a : 1} } })
同理,el 选项用在 Vue.extend() 中时也须是一个函数。
5.数据传递
Vue.js组件之间有三种数据传递方式:
- props
- 组件通信
- slot
5.1 props
“props”是组件数据的一个字段,期望从父组件传下来数据。因为组件实例的作用域是孤立的,所以子组件需要显式地用props选项来获取父组件的数据。
Props选项可以是字面量、表达式、绑定修饰符。
5.1.1 字面量
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title></title>
</head>
<body>
<child msg="hello!"></child>
<script src="js/vue.js" type="text/javascript" charset="utf-8"></script>
<script type="text/javascript">
Vue.component('child', {
// 声明 props
props: ['msg'],
// prop 可以用在模板内
// 可以用 `this.msg` 设置
template: '<span>{{ msg }}你困吗</span>'
})
new Vue({
el: 'body'
})
</script>
</body>
</html>
HTML 特性不区分大小写。名字形式为 camelCase 的 prop 用作特性时,需要转为 kebab-case(短横线隔开):
Vue.component('child', {
// camelCase in JavaScript
props: ['myMessage'],
template: '<span>{{ myMessage }}</span>'
})
<!-- kebab-case in HTML -->
<child my-message="hello!"></child>
5.1.2 动态
类似于用 v-bind 绑定 HTML 特性到一个表达式,也可以用 v-bind 绑定动态 Props 到父组件的数据。每当父组件的数据变化时,也会传导给子组件。比如酱:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title></title>
</head>
<body>
<div>
<input v-model="parentMsg">
<br>
<child :my-message="parentMsg"></child>
</div>
<script src="js/vue.js" type="text/javascript" charset="utf-8"></script>
<script type="text/javascript">
Vue.component('child', {
props: ['myMessage'],
template: '<span>{{ myMessage }}你困吗</span>'
})
new Vue({
el: 'body',
data:{
parentMsg:''
}
})
</script>
</body>
</html>
当我在input里面输入哈哈的时候:
5.1.3 绑定类型
可以使用绑定修饰符:
- .sync,双向绑定
- .once,单次绑定
<!-- 默认为单向绑定 -->
<child :msg="parentMsg"></child> <!-- 双向绑定 -->
<child :msg.sync="parentMsg"></child> <!-- 单次绑定 -->
<child :msg.once="parentMsg"></child>
prop 默认是单向绑定:当父组件的属性变化时,将传导给子组件,但是反过来不会。
不过需要注意的是:如果 prop 是一个对象或数组,是按引用传递。在子组件内修改它会影响父组件的状态,不管是使用哪种绑定类型。
示例:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title></title>
</head>
<body>
<div id="app"> <table>
<tr>
<th colspan="3">父组件数据</td>
</tr>
<tr>
<td>name</td>
<td>{{ name }}</td>
<td><input type="text" v-model="name" /></td>
</tr>
<tr>
<td>age</td>
<td>{{ age }}</td>
<td><input type="text" v-model="age" /></td>
</tr>
</table> <my-component v-bind:my-name.sync="name" v-bind:my-age="age"></my-component>
</div> <template id="myComponent">
<table>
<tr>
<th colspan="3">子组件数据</td>
</tr>
<tr>
<td>my name</td>
<td>{{ myName }}</td>
<td><input type="text" v-model="myName" /></td>
</tr>
<tr>
<td>my age</td>
<td>{{ myAge }}</td>
<td><input type="text" v-model="myAge" /></td>
</tr>
</table>
</template>
<script src="js/vue.js"></script>
<script>
var vm = new Vue({
el: '#app',
data: {
name: 'k',
age: 24
},
components: {
'my-component': {
template: '#myComponent',
props: ['myName', 'myAge']
}
}
})
</script>
</body>
</html>
上面这段设置了名字双向,年龄单向:
以下是一个大神的综合示例:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title></title>
</head>
<body>
<div id="app"> <table>
<tr>
<th colspan="3">父组件数据</td>
</tr>
<tr>
<td>name</td>
<td>{{ name }}</td>
<td><input type="text" v-model="name" /></td>
</tr>
<tr>
<td>age</td>
<td>{{ age }}</td>
<td><input type="text" v-model="age" /></td>
</tr>
</table> <my-component v-bind:my-name.sync="name" v-bind:my-age="age"></my-component>
</div> <template id="myComponent">
<table>
<tr>
<th colspan="3">子组件数据</td>
</tr>
<tr>
<td>my name</td>
<td>{{ myName }}</td>
<td><input type="text" v-model="myName" /></td>
</tr>
<tr>
<td>my age</td>
<td>{{ myAge }}</td>
<td><input type="text" v-model="myAge" /></td>
</tr>
</table>
</template>
<script src="js/vue.js"></script>
<script>
var vm = new Vue({
el: '#app',
data: {
name: 'k',
age: 24
},
components: {
'my-component': {
template: '#myComponent',
props: ['myName', 'myAge']
}
}
})
</script>
</body>
</html>
可以检索:
其中,
{{ col | capitalize}}
过滤,首字母大写。
<tr v-for="entry in data | filterBy filterKey"> <td v-for="col in columns"> {{entry[col]}} </td> </tr>
过滤搜索关键词;
双循环,tr循环data条数,4行,entry表示每行;td循环columns数量,3列,col表示每列,entry[col]取具体数据。
props: { data: Array, columns: Array, filterKey: String }
验证:父组件传递过来的data和columns必须是Array类型,filterKey必须是字符串类型。
验证要求示例:
Vue.component('example', {
props: {
// 基础类型检测 (`null` 意思是任何类型都可以)
propA: Number,
// 多种类型 (1.0.21+)
propM: [String, Number],
// 必需且是字符串
propB: {
type: String,
required: true
},
// 数字,有默认值
propC: {
type: Number,
default: 100
},
// 对象/数组的默认值应当由一个函数返回
propD: {
type: Object,
default: function () {
return { msg: 'hello' }
}
},
// 指定这个 prop 为双向绑定
// 如果绑定类型不对将抛出一条警告
propE: {
twoWay: true
},
// 自定义验证函数
propF: {
validator: function (value) {
return value > 10
}
},
// 转换函数(1.0.12 新增)
// 在设置值之前转换值
propG: {
coerce: function (val) {
return val + '' // 将值转换为字符串
}
},
propH: {
coerce: function (val) {
return JSON.parse(val) // 将 JSON 字符串转换为对象
}
}
}
})
Stringtype 可以是下面原生构造器:
- Number
- Boolean
- Function
- Object
- Array
type 也可以是一个自定义构造器,使用 instanceof 检测。
当 prop 验证失败时,Vue 将拒绝在子组件上设置此值,如果使用的是开发版本会抛出一条警告。
参考:http://www.cnblogs.com/keepfool/p/5625583.html
《vue.js权威指南》
vue.js慢速入门(2)的更多相关文章
- vue.js慢速入门(1)
0.MVVM 什么是MVVM?就是Model-View-ViewModel. ViewModel是Vue.js的核心,它是一个Vue实例. 不太懂也没关系,慢慢就懂了. 1.基础示例 代码: < ...
- Vue (一) --- vue.js的快速入门使用
=-----------------------------------把现在的工作做好,才能幻想将来的事情,专注于眼前的事情,对于尚未发生的事情而陷入无休止的忧虑之中,对事情毫无帮助,反而为自己凭添 ...
- Vue.js的从入门到放弃进击录(一)
感谢我们项目组给机会,让我学了Vue.js,打开新世界大门...哈哈哈,也没有那么夸张,不过学下来确实觉得入门还是蛮容易的.我大概前前后后学了有一个月的样子,一开始只是比较急着可以写东西出来,后来因为 ...
- vue.js学习之入门实例
之前一直看过vue.js官网api,但是很少实践,这里抽出时间谢了个入门级的demo,记录下一些知识点,防止后续踩坑,牵扯到的的知识点:vue.vue-cli.vue-router.webpack等. ...
- vue.js自定义指令入门
Vue.js 允许你注册自定义指令,实质上是让你教 Vue 一些新技巧:怎样将数据的变化映射到 DOM 的行为.你可以使用Vue.directive(id, definition)的方法传入指令id和 ...
- 一款简单而不失强大的前端框架——【Vue.js的详细入门教程①】
↓— Vue.js框架魅力 —↓ 前言 Vue.js 是一个构建数据驱动的 web 界面的渐进式框架.Vue.js 的目标是通过尽可能简单的 API 实现响应的数据绑定和组合的视图组件.V ...
- Vue.js—组件快速入门以及实例应用
上次我们学习了Vue.js的基础,并且通过综合的小实例进一步的熟悉了Vue.js的基础应用.今天我们就继续讲讲Vue.js的组件,更加深入的了解Vue,js的使用.首先我们先了解一下什么是Vue.js ...
- Vue.js 基础快速入门
Vue.js是一个JavaScript MVVM库,它是以数据驱动和组件化的思想构建的.Vue.js提供了简洁.易于理解的API,使得我们能够快速地上手并使用Vue.js 如果之前已经习惯了用jQue ...
- Vue.js——十分钟入门Vuex
一. 什么是Vuex? Vuex Vuex是一个专门为Vue.js应用程序开发的状态管理模式, 它采用集中式存储管理所有组件的公共状态, 并以相应的规则保证状态以一种可预测的方式发生变化. Vue ...
随机推荐
- 基于jquery的图片懒加载js
function lazyload(option){ var settings={ defObj:null, defHeight: }; settings=$.extend(settings,opti ...
- GO语言练习:组合的用法
1.代码 2.运行 1.代码 package main import "fmt" type Base struct { Name string } func (base * Bas ...
- About_MySQL Select--来自copy_03
MySQL Select 查询分类 单表查询:简单查询 多表查询:连接查询 联合查询:多个查询结果汇总 查询的组成 投影查询:挑选要显示的字段 select array1,array2,... f ...
- [LintCode] Move Zeroes 移动零
Given an array nums, write a function to move all 0's to the end of it while maintaining the relativ ...
- [转] - bashrc与profile的区别
bashrc与profile的区别 要搞清bashrc与profile的区别,首先要弄明白什么是交互式shell和非交互式shell,什么是login shell 和non-login shell. ...
- Js变量定义——fn里 var与不var的区别
js运行时内置了一个Global对象. 这个Global对象跟运行环境有关.在浏览器运行环境中.Global就是window对象.在nodejs中.Global对象是global对象. 当你在浏览器环 ...
- c# 集合及特殊集合
1.ArrayList集合 习题:输入人数,输入分数,存到集合里面,之后再读取出来,求平均分,排序打印. 2.Stack 集合 3.Queue 队列集合 每日一语:脚跟立定以后,你必须拿你的力量 ...
- Web前端开发基础 第四课(CSS小技巧)
水平居中设置-行内元素 我们在实际工作中常会遇到需要设置水平居中场景,今天我们就来看看怎么设置水平居中的. 如果被设置元素为文本.图片等行内元素时,水平居中是通过给父元素设置 text-align:c ...
- 未能加载文件或程序集“Newtonsoft.Json, Version=4.0.0.0, Culture=neutral, PublicKeyToken=30a [问题点数:40分,结帖人u010259408]
未能加载文件或程序集“Newtonsoft.Json, Version=4.0.0.0, Culture=neutral, PublicKeyToken=30a [问题点数:40分,结帖人u01025 ...
- Linux下动态库(.so)和静态库(.a) 的区别
静态库在程序编译时会被连接到目标代码中,程序运行时将不再需要该静态库.编译之后程序文件大,但加载快,隔离性也好.动态库在程序编译时并不会被连接到目标代码中,而是在程序运行是才被载入,因此在程序运行时还 ...