这里有新鲜出炉的 Vue.js 教程,程序狗速度看过来!
Vue.js 是构建 Web 界面的 JavaScript 库,提供数据驱动的组件,还有简单灵活的 API,使得 MVVM 更简单。
这篇文章主要为大家详细介绍了 vue.js 初学入门教程第二篇, 具有一定的参考价值,感兴趣的小伙伴们可以参考一下
接着上一篇 vue 慢速入门教程学习。
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.phperz.com/article/17/0630/330614.html