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 相关文章推荐
关于IFRAME 自适应高度的研究
Jul 20 Javascript
javascript下有关dom以及xml节点访问兼容问题
Nov 26 Javascript
如何制作浮动广告 JavaScript制作浮动广告代码
Dec 30 Javascript
Ajax异步提交表单数据的说明及方法实例
Jun 22 Javascript
JS模拟Dialog弹出浮动框效果代码
Oct 16 Javascript
基于Javascript实现返回顶部按钮
Feb 29 Javascript
JavaScript中Form表单技术汇总(推荐)
Jun 26 Javascript
Node.js实现文件上传
Jul 05 Javascript
JS创建Tag标签的方法详解
Jun 09 Javascript
vue实现搜索功能
May 28 Javascript
Vue自定义组件双向绑定实现原理及方法详解
Sep 03 Javascript
详解VUE中的插值( Interpolation)语法
Oct 18 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 array_pop()数组函数将数组最后一个单元弹出(出栈)
2011/07/12 PHP
php实现查询百度google收录情况(示例代码)
2013/08/02 PHP
PHP中trim()函数简单使用指南
2015/04/16 PHP
为你总结一些php系统类函数
2015/10/21 PHP
自制PHP框架之路由与控制器
2017/05/07 PHP
使用TextRange获取输入框中光标的位置的代码
2007/03/08 Javascript
js创建表单元素并使用submit进行提交
2014/08/14 Javascript
JavaScript中的toUTCString()方法使用详解
2015/06/12 Javascript
浅谈setTimeout 与 setInterval
2015/06/23 Javascript
JavaScript中的this关键字使用详解
2015/08/14 Javascript
jQuery实现鼠标悬停背景翻转的黑色导航菜单代码
2015/09/14 Javascript
基于JavaScript实现生成名片、链接等二维码
2015/09/20 Javascript
js 获取当前web应用的上下文路径实现方法
2016/08/19 Javascript
给easyui datebox扩展一个清空的实例
2016/11/09 Javascript
Angular.js中ng-if、ng-show和ng-hide的区别介绍
2017/01/20 Javascript
详解vue-cli 接口代理配置
2017/12/13 Javascript
JavaScript常用数学函数用法示例
2018/05/14 Javascript
vue填坑之webpack run build 静态资源找不到的解决方法
2018/09/03 Javascript
JS桶排序的简单理解与实现方法示例
2019/11/25 Javascript
js通过canvas生成图片缩略图
2020/10/02 Javascript
vue iview 隐藏Table组件里的某一列操作
2020/11/13 Javascript
python根据开头和结尾字符串获取中间字符串的方法
2015/03/26 Python
浅析Python中的join()方法的使用
2015/05/19 Python
Python实现截屏的函数
2015/07/26 Python
python开发之list操作实例分析
2016/02/22 Python
Python使用QRCode模块生成二维码实例详解
2017/06/14 Python
浅谈Tensorflow模型的保存与恢复加载
2018/04/26 Python
python 在某.py文件中调用其他.py内的函数的方法
2019/06/25 Python
django基于存储在前端的token用户认证解析
2019/08/06 Python
Python3 把一个列表按指定数目分成多个列表的方式
2019/12/25 Python
FORZIERI澳大利亚站:全球顶级奢华配饰精品店
2016/12/31 全球购物
Bath & Body Works阿联酋:在线购买沐浴和身体用品
2021/02/27 全球购物
班级学习计划书
2014/04/27 职场文书
公司收款委托书范本
2014/09/20 职场文书
售后服务质量承诺书
2015/04/29 职场文书
学术会议领导致辞
2015/07/29 职场文书