首页 > 编程 > JavaScript > 正文

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

2019-11-19 19:02:41
字体:
来源:转载
供稿:网友

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

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持武林网。

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

  《vue.js权威指南》

发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表