[关闭]
@zhouyy 2018-05-31T11:33:36.000000Z 字数 6781 阅读 510

组件

vue


参考:https://blog.csdn.net/u012123026/article/details/72460470

组件是可复用的实例

  1. data: function(){
  2. return {
  3. count: 0
  4. }
  5. }

这样每个实例都可以被返回一份独立的数据
否则如果:

  1. data: {
  2. count: 0
  3. }

所有组件都共享了同一份数据,对其中任意组件的操作都会影响到其它组件

注册

Vue.use

  1. import globalComponent from 'globalComponent'
  2. Vue.use(globalComponent)
  3. //一般一次引入所有组件
  1. <template>
  2. <global-component/>
  3. </template>

Vue.component

  1. Vue.component('global-component',{
  2. data:function(){
  3. return {
  4. msg:'this is XXX'
  5. }
  6. },
  7. template:'#global-template'
  8. }
  1. <template id='global-template'>
  2. <div><input v-model='msg'/></div>
  3. </template>

Vue.component方式在很多中小规模的项目中运作的很好,在这些项目里 JavaScript 只被用来加强特定的视图。但当在更复杂的项目中,或者你的前端完全由 JavaScript 驱动的时候,下面这些缺点将变得非常明显:

**单文件组件*方法常用在vue单页应用中。详情看官网:https://cn.vuejs.org/v2/guide/single-file-components.html

  1. <template>
  2. <local-component />
  3. </template>
  4. <script>
  5. import localComponent from 'localComponent'
  6. export default {
  7. components: {
  8. 'local-component': localComponent
  9. }
  10. }
  11. </script>

一般方式

  1. var localComponent = { /* ... */ }
  2. new Vue({
  3. el:'#local'
  4. components: {
  5. 'local-component': localComponent
  6. }
  7. })

Vue.extend

new Vue 是一个实例
vue.extend 组件构造器 需要传入 component 进行注册
vue.component 直接注册组件内部已经自动构造了

  1. <div class="col-xs-12 text-center bg-info">
  2. <your-vue></your-vue>
  3. </div>
  4. <div class="col-xs-12 text-center bg-warning">
  5. <y-o-u-r-v-u-e></y-o-u-r-v-u-e>//局部注册组件对象中的键名 YOURVUE 必须被看作驼峰式命名,而自定义标签必须写作短横分隔式
  6. <hr>
  7. <local-component></local-component>//注册时短横分隔式命名的组件,其自定义标签直接使用组件注册名
  8. </div>
  1. var localComponent =Vue.extend({
  2. data: function() {
  3. return {
  4. msg: '这是组件内部信息',
  5. i: 1
  6. }
  7. },
  8. methods:{
  9. add:function(){
  10. this.i++
  11. }
  12. },
  13. template: '<div>{{ msg }}</div><div>{{ i }}</div><button @click="add">组件内部数据操作</button>'
  14. })
  15. var myVue = Vue.extend({
  16. data: function() {
  17. return {
  18. msg: 'Hello, Vue.js!',//data 选项合并规则:无重复的属性保留,因此使用扩展实例构造器 myVue 构造的 Vue 实例中会有 myVue 扩展实例构造器中的 msg 数据
  19. i: 1,
  20. obj: {
  21. a: 1,
  22. b: 2
  23. }
  24. }
  25. },
  26. methods: {
  27. add: function() {
  28. this.i++
  29. }
  30. },
  31. components: {
  32. YOURVUE: localComponent,
  33. 'local-component': localComponent
  34. }
  35. })
  36. var vm1 = new myVue({
  37. data: {//data 选项,将会与扩展实例构造器 myVue 中 data 工厂函数所返回的数据按一定的规则合并
  38. newMsg: 'Amazing Vue.js',//无重复的属性保留,因此构造的 Vue 实例中也会有 newMsg 数据
  39. i: 100,//同名覆盖,myVue 中 data 工厂函数所返回的数据中 i 的值 1 被 100 覆盖
  40. obj: {
  41. b: 99,
  42. c: 3,
  43. d: 4
  44. }
  45. },
  46. methods: {//合并规则与 data 选项相同,因此最终的 Vue 实例方法中包含 add 和 add2,add 方法的作用是 i 自加 0.5,而不是 myVue 中声明的 i 自加 1
  47. add: function() {
  48. this.i += 0.5
  49. },
  50. add2: function() {
  51. this.i += 2
  52. }
  53. },
  54. components: {
  55. yourVue: localComponent
  56. }
  57. })
  1. <template id="tp1">
  2. <h3>{{name}}</h3>
  3. <div>
  4. Msg:
  5. <input type="text" v-model="msg" />
  6. </div>
  7. <div>The array in child component is: {{propA | json}}.</div>
  8. <div>The type of propB is : {{typeof propB}}</div>
  9. <button @click="changeElements">Click Me First</button>
  10. <button @click="sortElements">Then Click Me</button>
  11. <div v-if="number">The number is: {{number}}</div>
  12. <div v-else>The number is absent</div>
  13. <div>Other numbers: {{numbers | json}}</div>
  14. <div v-if="myNumber">Number object: {{myNumber | json}}</div>
  15. <div v-else>That's all.</div>//使用条件渲染,若 myNumber 有数据,则输出其 JSON 字符串,否则显示 That's all,Vue.js 2.0 中,v-show 后面不再跟 v-else,因此这里只能用 v-if
  16. </template>
  1. function number() {
  2. this.name = 'number'
  3. this.value = 3
  4. }//自定义 number 对象的构造函数
  5. var myComponent = Vue.extend({
  6. props: {
  7. name: {
  8. type: String,
  9. default: 'Component'
  10. },
  11. msg: String,
  12. propA: {
  13. type: Array,
  14. required: true
  15. },
  16. propB: [String, Number],
  17. numbers: {
  18. type: Array,
  19. default: function() {
  20. return [1, 1, 2, 3, 5, 8, 13, 21]
  21. }
  22. },
  23. number: {
  24. type: Number,
  25. validator: function(value) {
  26. return value > 10
  27. }
  28. },
  29. myNumber: number
  30. },
  31. methods: {
  32. changeElements() {
  33. this.propA.push(Math.floor(Math.random() * 100))
  34. },
  35. sortElements() {
  36. this.propA = this.propA.sort((a, b) => a - b)
  37. }
  38. },
  39. template:'#tp1'
  40. })
  41. ```
  42. `
  43. <div class="container" id="app">
  44. <h2>通过 props 传递数据到子组件</h2>
  45. <div class="row">We have an msg: {{parentMsg}}. </div>
  46. <div class="row">
  47. Edit msg:
  48. <input type="text" v-model="parentMsg">
  49. </div>
  50. <div class="row">
  51. And the array in parent component is: {{arrData | json}}
  52. </div>
  53. <my-component :msg="parentMsg" :prop-a="arrData" prop-b="12" :numbers='[1,2,3]' :number="13"></my-component>
  54. //:msg="parentMsg",表示通过数据绑定指令将父组件中的 parentMsg 作为 msg 传入子组件,“:”是“v-bind:”的简写,可用于普通 HTML 属性,也可用于组件的 props;
  55. //:prop-a="arrData",表示通过数据绑定指令将父组件中的 arrData 作为 propA 传入子组件,用于演示数组在子组件中修改后对父组件中数据状态的影响,父子组件中的数据同步变化效果参见视频
  56. //prop-b="12",表示直接传递 12 给 propB,这里的 12 必须看作是字符串 "12",propB声明时已经指定可以是 String 或 Number,因此这里可以传递字符串没毛病
  57. //:numbers="[1,2,3]",使用数据绑定指令将字面量数组 [1,2,3] 传递给 numbers,如果不使用数据绑定,传递的将会是字符串
  58. //:number="13",使用数据绑定指令将字面量数值 13 传递给 number
  59. <my-component name="Another Component" :msg.sync="parentMsg" :prop-a="arrData" :prop-b="12" :my-number="myNumber"></my-component>
  60. //name="Another Component",直接传递 "Another Component" 字符串给 name,和 src、class、style 等普通 HTML 属性类似,不使用数据绑定的 prop-x="XXXX" 传递的都是字符串
  61. //:msg.sync="parentMsg",双向绑定 parentMsg 到 msg,为降低对父组件数据状态的副作用,.sync 修饰符在 Vue.js 2.0 中已废弃,使用 props 向子组件传递数据只能是单向的,并且不鼓励在子组件中修改 prop 的值
  62. //:prop-a="arrData",表示通过数据绑定指令将父组件中的 arrData 作为 propA 传入子组件,用于演示数组在子组件中修改后对父组件中数据状态的影响,注意在 Vue.js 1.0 中,js 中的“驼峰式”标记在 HTML 中用作属性或指令参数……时要转为“羊-肉-串-式”,Vue.js 2.0 中由于引入了 Virtual DOM,在 HTML 中使用“驼峰式”或“羊-肉-串-式”均可
  63. //:prop-b="12",使用数据绑定指令将字面量数值 12 传递给 propB,propB声明时已经指定可以是 String 或 Number,因此这里可以传递数值没毛病
  64. //:my-number="myNumber",使用数据绑定指令将父组件中的 myNumber 对象传递给 myNumber
  65. <my-component name="Yet Another Component" :msg.once="parentMsg" :prop-a="arrData"></my-component>
  66. //:msg.once="parentMsg",使用数据绑定指令将父组件中的 parentMsg 传递给 msg,使用修饰符 once 表示单次绑定,Vue.js 2.0 中 once 修饰符已废弃,可以在组件模板中局部使用新的 v-once 指令代替
  67. </div>
  68. var vm = new Vue({
  69. el: '#app',
  70. data: {
  71. arrData: [4, 27, 3, 12, 5, 9],
  72. parentMsg: 'Hello, Vue.js!',
  73. myNumber: new number()
  74. },
  75. components: {
  76. myComponent: myComponent
  77. }
  78. })

引用方式

你可以作用到Vue.component 这个全局注册方法里, 也可以在任意vue模板里使用组件

  1. var apple = Vue.extend({
  2. ....
  3. })
  4. Vue.component('apple',apple)
  5. 你可以作用到vue实例或者某个组件中的components属性中并在内部使用apple组件
  6. new Vue({
  7. components:{
  8. apple:apple
  9. }
  10. })

Vue.component 你可以创建 ,也可以取组件 例如下

  1. var apple = Vue.component('apple')

初始化

prop

  1. <template>
  2. <div class="blog-post">
  3. <h2>{{post.title}}</h2>
  4. <div v-html="post.content"></div>
  5. <button v-on:click="$emit('enlarge-text')"></button>
  6. Enlarge
  7. </div>
  8. //当模板包含内容不止一个时候,需要包裹一个父元素,解决every comp must have a single root elem的问题
  9. </template>
  10. <script>
  11. export default {
  12. props: ['data'],
  13. data:{
  14. post:[]
  15. }
  16. created:function(){
  17. let data=this.data;
  18. var vm=this
  19. fetch('https;??')
  20. .then(function(response){
  21. return response.json()
  22. })
  23. .then(function(data){
  24. vm.posts=data
  25. })
  26. }
  27. }
  28. </script>
  29. <style>
  30. </style>

向父级触发事件(or 同时抛值),v-on 监听组件事件

可以调用$emit方法并传入事件的名字

  1. <blog-post
  2. v-on:enlarge-text="postFontSize += 0.1"></blog-post>

组件中

  1. <button v-on:click="$emit('enlarge-text',0.1)"></button>

在父级组件监听时可以通过$event访问

  1. <blog-post
  2. v-on:enlarge-text="postFontSize += $event"></blog-post>

或者作为参数传入:

  1. methods:{
  2. onEnlargeText:function(amount){
  3. this.postFontSize+=amount
  4. }
  5. }

在组件上使用v-model

  1. <input v-model="searchtxtx">
  2. //等价于
  3. <input
  4. :value="searchtxt"
  5. v-on:input="searchtxt=$event.target.value">

当用在组件上时:

  1. <custom-input
  2. :value="searchtxt"
  3. v-on:input="searchtxt=$event
  4. ><custom-input>
  5. //则组件内input 需绑定到名为`value`的prop
  6. //input事件被触发时,抛出值
  7. <input
  8. :value="value"
  9. v-on:input="$emit('input',$event.target.value)">

vm.$emit( event, […args] )

参数:

添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注