vue.js初学入门教程(2)


Posted in Javascript onNovember 07, 2016

接着上一篇vue慢速入门教程学习。

4.组件使用基础

什么是组件?组件可以理解为可重用的自定义HTML。
可以使用一堆组件来构造大型应用,任意类型的应用界面都可以抽象为一个组件树:

vue.js初学入门教程(2)

可以把组件代码按照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.js初学入门教程(2)

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>

vue.js初学入门教程(2)

其中,子组件只能在父组件的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>

vue.js初学入门教程(2)

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>

vue.js初学入门教程(2)

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里面输入哈哈的时候:

vue.js初学入门教程(2)

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>

上面这段设置了名字双向,年龄单向:

vue.js初学入门教程(2)

以下是一个大神的综合示例:

<!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>

vue.js初学入门教程(2)

可以检索:

vue.js初学入门教程(2)

其中,{{ 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 将拒绝在子组件上设置此值,如果使用的是开发版本会抛出一条警告。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

参考:Vue.js——60分钟组件快速入门(上篇)

《vue.js权威指南》

Javascript 相关文章推荐
基于Jquery的$.cookie()实现跨越页面tabs导航实现代码
Mar 03 Javascript
jquery图片放大功能简单实现
Aug 01 Javascript
深入剖析JavaScript:Object类型
May 10 Javascript
Bootstrap CSS布局之表单
Dec 17 Javascript
node.js将MongoDB数据同步到MySQL的步骤
Dec 10 Javascript
JavaScript 中使用 Generator的方法
Dec 29 Javascript
vue2中使用sass并配置全局的sass样式变量的方法
Sep 04 Javascript
JavaScript数据结构与算法之二叉树实现查找最小值、最大值、给定值算法示例
Mar 01 Javascript
vue改变循环遍历后的数据实例
Nov 07 Javascript
一篇文章带你浅入webpack的DLL优化打包
Feb 20 Javascript
详解Javascript实践中的命令模式
May 05 Javascript
React中的Context应用场景分析
Jun 11 Javascript
AngularJS递归指令实现Tree View效果示例
Nov 07 #Javascript
基于Bootstrap仿淘宝分页控件实现代码
Nov 07 #Javascript
浅谈移动端之js touch事件 手势滑动事件
Nov 07 #Javascript
jquery获取table指定行和列的数据方法(当前选中行、列)
Nov 07 #Javascript
AngularJS实现Input格式化的方法
Nov 07 #Javascript
AngularJS自定义插件实现网站用户引导功能示例
Nov 07 #Javascript
webpack常用配置项配置文件介绍
Nov 07 #Javascript
You might like
一步一步学习PHP(8) php 数组
2010/03/05 PHP
php替换超长文本中的特殊字符的函数代码
2012/05/22 PHP
探讨php中防止SQL注入最好的方法是什么
2013/06/10 PHP
PHP入门之常量简介和系统常量
2014/05/12 PHP
PHP比较运算符的详细介绍
2015/09/29 PHP
PHP在弹框中获取foreach中遍历的id值并传递给地址栏
2017/06/13 PHP
jquery 框架使用教程 AJAX篇
2009/10/11 Javascript
javascript利用初始化数据装配模版的实现代码
2010/11/17 Javascript
查看图片(前进后退)功能实现js代码
2013/04/24 Javascript
AngularJS基础 ng-copy 指令实例代码
2016/08/01 Javascript
原生js实现水平方向无缝滚动
2017/01/10 Javascript
微信小程序之页面拦截器的示例代码
2017/09/07 Javascript
js定时器实现倒计时效果
2017/11/05 Javascript
vue实现图片滚动的示例代码(类似走马灯效果)
2018/03/03 Javascript
JS中间件设计模式的深入探讨与实例分析
2020/04/11 Javascript
JavaScript 空间坐标的使用
2020/08/19 Javascript
JS指定音频audio在某个时间点进行播放
2020/11/28 Javascript
python 获取本机ip地址的两个方法
2013/02/25 Python
在Python中使用PIL模块对图片进行高斯模糊处理的教程
2015/05/05 Python
Python将图片转换为字符画的方法
2020/06/16 Python
python验证码识别教程之滑动验证码
2018/06/04 Python
Django实现简单网页弹出警告代码
2019/11/15 Python
Python实现隐马尔可夫模型的前向后向算法的示例代码
2019/12/31 Python
Python调用钉钉自定义机器人的实现
2020/01/03 Python
Tensorflow中tf.ConfigProto()的用法详解
2020/02/06 Python
django中的数据库迁移的实现
2020/03/16 Python
Html5 语法与规则简要概述
2014/07/29 HTML / CSS
AHAVA美国官方网站:死海海泥护肤品牌
2016/10/18 全球购物
俄罗斯花园种植材料批发和零售网上商店:Беккер
2019/07/22 全球购物
小学教师岗位职责
2013/11/25 职场文书
自立自强的名人事例
2014/02/10 职场文书
《跨越海峡的生命桥》教学反思
2014/02/24 职场文书
捐款倡议书格式范文
2014/05/14 职场文书
Python基于百度AI实现抓取表情包
2021/06/27 Python
改造DE1103三步曲
2022/04/07 无线电
Meta增速拉垮,元宇宙难当重任
2022/04/29 数码科技