Vue.js 组件
组件(Component)是 Vue.js 最强大的功能之一。
组件可以扩展 HTML 元素,封装可重用的代码。
组件系统让我们可以用独立可复用的小组件来构建大型应用,几乎任意类型的应用的界面都可以抽象为一个组件树:

注册一个全局组件语法格式如下:
Vue.component(tagName, options)
tagName 为组件名,options 为配置选项。注册后,我们可以使用以下方式来调用组件:
<tagName></tagName>
全局组件
所有实例都能用全局组件。
全局组件实例
注册一个简单的全局组件 runoob,并使用它:
<div id="app">
    <runoob></runoob>
</div>
 
<script>
// 注册
Vue.component('runoob', {
  template: '<h1>自定义组件!</h1>'
})
// 创建根实例
new Vue({
  el: '#app'
})
</script>
尝试一下 »
局部组件
我们也可以在实例选项中注册局部组件,这样组件只能在这个实例中使用:
局部组件实例
注册一个简单的局部组件 runoob,并使用它:
<div id="app">
    <runoob></runoob>
</div>
 
<script>
var Child = {
  template: '<h1>自定义组件!</h1>'
}
 
// 创建根实例
new Vue({
  el: '#app',
  components: {
    // <runoob> 将只在父模板可用
    'runoob': Child
  }
})
</script>
尝试一下 »
Prop
prop 是子组件用来接受父组件传递过来的数据的一个自定义属性。
父组件的数据需要通过 props 把数据传给子组件,子组件需要显式地用 props 选项声明 "prop":
Prop 实例
<div id="app">
    <child message="hello!"></child>
</div>
 
<script>
// 注册
Vue.component('child', {
  // 声明 props
  props: ['message'],
  // 同样也可以在 vm 实例中像 "this.message" 这样使用
  template: '<span>{{ message }}</span>'
})
// 创建根实例
new Vue({
  el: '#app'
})
</script>
尝试一下 »
动态 Prop
类似于用 v-bind 绑定 HTML 特性到一个表达式,也可以用 v-bind 动态绑定 props 的值到父组件的数据中。每当父组件的数据变化时,该变化也会传导给子组件:
Prop 实例
<div id="app">
    <div>
      <input v-model="parentMsg">
      <br>
      <child v-bind:message="parentMsg"></child>
    </div>
</div>
 
<script>
// 注册
Vue.component('child', {
  // 声明 props
  props: ['message'],
  // 同样也可以在 vm 实例中像 "this.message" 这样使用
  template: '<span>{{ message }}</span>'
})
// 创建根实例
new Vue({
  el: '#app',
  data: {
    parentMsg: '父组件内容'
  }
})
</script>
尝试一下 »
以下实例中使用 v-bind 指令将 todo 传到每一个重复的组件中:
Prop 实例
<div id="app">
    <ol>
    <todo-item v-for="item in sites" v-bind:todo="item"></todo-item>
      </ol>
</div>
 
<script>
Vue.component('todo-item', {
  props: ['todo'],
  template: '<li>{{ todo.text }}</li>'
})
new Vue({
  el: '#app',
  data: {
    sites: [
      { text: 'Runoob' },
      { text: 'Google' },
      { text: 'Taobao' }
    ]
  }
})
</script>
尝试一下 »
注意: prop 是单向绑定的:当父组件的属性变化时,将传导给子组件,但是不会反过来。
Prop 验证
组件可以为 props 指定验证要求。
为了定制 prop 的验证方式,你可以为 props 中的值提供一个带有验证需求的对象,而不是一个字符串数组。例如:
Vue.component('my-component', {
  props: {
    // 基础的类型检查 (`null` 和 `undefined` 会通过任何类型验证)
    propA: Number,
    // 多个可能的类型
    propB: [String, Number],
    // 必填的字符串
    propC: {
      type: String,
      required: true
    },
    // 带有默认值的数字
    propD: {
      type: Number,
      default: 100
    },
    // 带有默认值的对象
    propE: {
      type: Object,
      // 对象或数组默认值必须从一个工厂函数获取
      default: function () {
        return { message: 'hello' }
      }
    },
    // 自定义验证函数
    propF: {
      validator: function (value) {
        // 这个值必须匹配下列字符串中的一个
        return ['success', 'warning', 'danger'].indexOf(value) !== -1
      }
    }
  }
})
当 prop 验证失败的时候,(开发环境构建版本的) Vue 将会产生一个控制台的警告。
type 可以是下面原生构造器:
- String
- Number
- Boolean
- Array
- Object
- Date
- Function
- Symbol
type 也可以是一个自定义构造器,使用 instanceof 检测。
 
       
树上的鱼
ggq***7618@163.com
父组件给子组件传值的时候,如果想传入一个变量,写法如下:
// 注册 Vue.component('child', { // 声明 props props: ['message'], // 同样也可以在 vm 实例中像 "this.message" 这样使用 template: '<span>{{ message }}</span>' }) // 创建根实例 new Vue({ el: '#app', data:{ message:"hello", } })尝试一下 »
树上的鱼
ggq***7618@163.com
阿卡坤
404***770@qq.com
子组件通过 $emit 触发父组件的方法时,如果需要传递参数,可在方法名后面加可选参数,参数以逗号隔开。
比如 $emit("FunctionName") 当要传递参数时 :$emit("FunctionName",[arg1,arg2...])。
methods: { incrementHandler: function (v) { if(v==1){ this.counter -= 1 this.$emit('increment',1) }else{ this.counter += 1 this.$emit('increment',2) } } }尝试一下 »
阿卡坤
404***770@qq.com
关关长语
324***7890@qq.com
拓展-如何通过调整组件属性,实现修改组件的显示等内部属性。
使用 Props(全局)
全局定义组件
Vue.component('example1', { props: ['value'], template: '<button v-on:click="incrementHanlder">{{value}}</button>', // data: function () { // return { // count: 0 // } // }, methods: { incrementHanlder: function () { // this.count += 1 this.$emit('incretment') } } }) new Vue({ el: '#div_col', data: { total: 0 }, methods: { incretmentTotal: function () { this.total += 1 } } })尝试一下 »
关关长语
324***7890@qq.com
holiday
597***772@qq.com
你可能在找的系统点击事件的例子。
<div id="app"> <p>点击元素输出元素内容:</p> <ol> <todo-item v-for="item in sites" v-bind:todo="item" @click.native="alert(item.text)"></todo-item> </ol> </div>尝试一下 »
holiday
597***772@qq.com
naivewood
zjx***tchi@163.com
<script src="static/js/vue.js"></script> <div id="app"> <example :propa="'asda'" :propb = "'aasasa'" :propc="'sdf'" :prope="{a:'a'}" :propf="100" ></example> </div> <script type="text/javascript"> Vue.component('example', { props: { // 基础类型检测 (`null` 意思是任何类型都可以) propa: Number, // 多种类型 propb: [String, Number], // 必传且是字符串 propc: { type: String, required: true }, // 数字,有默认值 propd: { type: Number, default: 1000 }, // 数组/对象的默认值应当由一个工厂函数返回 prope: { type: Object, default: function () { return { message: 'hello' } } }, // 自定义验证函数 propf: { type: Number, validator: function (value) { // 这个值必须匹配下列字符串中的一个 return value>0? -1:1 }, defalut:12 } }, template: ` <table border="1px"> <tr> <th>propA</th> <th>propB</th> <th>propC</th> <th>propD</th> <th>propE</th> <th>propF</th> </tr> <tr> <td>{{ propa }}</td> <td>{{ propb }}</td> <td>{{ propc }}</td> <td>{{ propd }}</td> <td>{{ prope }}</td> <td>{{ propf }}</td> </tr> </table>` }) new Vue({ el: "#app" }); </script>尝试一下 »
naivewood
zjx***tchi@163.com
zac
417***302@qq.com
参考地址
这个例子的执行过程注解:
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>Vue 测试实例 - 菜鸟教程(runoob.com)</title> <script src="static/js/vue.min1.js"></script> </head> <body> <div id="app"> <div id="counter-event-example"> // 6. 页面上更新total的值 <p>{{ total }}</p> // 4. 这里的自定义事件再次触发局域方法incrementTotal <button-counter v-on:increment="incrementTotal"></button-counter> <button-counter v-on:increment="incrementTotal"></button-counter> </div> </div> <script> // 1. 注册全局组件 Vue.component('button-counter', { // 2. button绑定点击事件incrementHandler template: '<button v-on:click="incrementHandler">{{ counter }}</button>', data: function () { return { counter: 0 } }, methods: { // 3. 点击事件触发后,再次触发自定义事件increment incrementHandler: function () { this.counter += 1 this.$emit('increment') } }, }) new Vue({ el: '#counter-event-example', data: { total: 0 }, methods: { // 5. 局域方法执行了total+1 incrementTotal: function () { this.total += 1 } } }) </script> </body> </html>zac
417***302@qq.com
参考地址