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 相关文章推荐
js中获取事件对象的方法小结
Mar 13 Javascript
用js通过url传参把数据从一个页面传到另一个页面
Sep 01 Javascript
超炫的jquery仿flash导航栏特效
Nov 11 Javascript
angularJS 中input示例分享
Feb 09 Javascript
javascript类型系统——日期Date对象全面了解
Jul 13 Javascript
学习掌握JavaScript中this的使用技巧
Aug 29 Javascript
Angularjs通过指令监听ng-repeat渲染完成后执行脚本的方法
Dec 31 Javascript
利用canvas中toDataURL()将图片转为dataURL(base64)的方法详解
Nov 20 Javascript
javascript中new Array()和var arr=[]用法区别
Dec 01 Javascript
VUE 实现滚动监听 导航栏置顶的方法
Sep 11 Javascript
了解javascript中的Dom操作
May 27 Javascript
Vue登录拦截 登录后继续跳转指定页面的操作
Aug 04 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 数组的合并、拆分、区别取值函数集
2010/02/15 PHP
PHP与以太坊交互详解
2018/08/24 PHP
Jquery动态改变图片IMG的src地址示例
2013/06/25 Javascript
javascript ready和load事件的区别示例介绍
2013/08/30 Javascript
jquery+html5时钟特效代码分享(可设置闹钟并且语音提醒)
2020/03/30 Javascript
Bootstrap3 多个模态对话框无法显示的解决方案
2017/02/23 Javascript
Webpack打包慢问题的完美解决方法
2017/03/16 Javascript
从零开始学习Node.js系列教程之SQLite3和MongoDB用法分析
2017/04/13 Javascript
Vue.js手风琴菜单组件开发实例
2017/05/16 Javascript
Vue.js递归组件构建树形菜单
2017/12/24 Javascript
React从react-router路由上做登陆验证控制的方法
2018/05/10 Javascript
Vue.js单向绑定和双向绑定实例分析
2018/08/14 Javascript
Echart折线图手柄触发事件示例详解
2018/12/16 Javascript
详解基于iview-ui的导航栏路径(面包屑)配置
2019/02/22 Javascript
Vue路由前后端设计总结
2019/08/06 Javascript
使用 JavaScript 创建并下载文件(模拟点击)
2019/10/25 Javascript
[00:34]TI7不朽珍藏III——纯金地穴编织者饰品展示
2017/07/15 DOTA
Python列表推导式的使用方法
2013/11/21 Python
Python日志模块logging简介
2015/04/13 Python
win7上python2.7连接mysql数据库的方法
2017/01/14 Python
利用python获取当前日期前后N天或N月日期的方法示例
2017/07/30 Python
Python下载网络小说实例代码
2018/02/03 Python
Tensorflow实现卷积神经网络用于人脸关键点识别
2018/03/05 Python
图解Python变量与赋值
2018/04/03 Python
对python .txt文件读取及数据处理方法总结
2018/04/23 Python
Python在Matplotlib图中显示中文字体的操作方法
2019/07/29 Python
Python简易版图书管理系统
2019/08/12 Python
Python使用微信itchat接口实现查看自己微信的信息功能详解
2019/08/22 Python
Python日志处理模块logging用法解析
2020/05/19 Python
在 Python 中使用 7zip 备份文件的操作
2020/12/11 Python
个人思想理论学习的自我鉴定
2013/11/30 职场文书
实习老师离校感言
2014/02/03 职场文书
市场拓展计划书
2014/05/03 职场文书
python制作图形界面的2048游戏, 基于tkinter
2021/04/06 Python
swagger如何返回map字段注释
2021/07/03 Java/Android
Python中的socket网络模块介绍
2022/07/23 Python