Blogger Information
Blog 33
fans 0
comment 0
visits 49779
Popular Tutorials
More>
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template
Vue2 组件
Lon
Original
959 people have browsed it

Vue2 组件

了解更多详情请访问 https://cn.vuejs.org/v2/guide/index.html

视频教程 https://www.bilibili.com/video/BV1Zy4y1K7SH

一、组件

组件是一种封装可复用的集合,通过组件化,将更好的完成繁杂的需求

组件化特点,具体如下:
1.拥有唯一性的组件名称,方便调用;
2.以组件名称为 HTML 元素标签形式存在,扩展了 HTML;
3.组件可以复用,且组件与组件之间互不干涉;

Vue中使用组件的三大步骤:
1.定义组件(创建组件)
2.注册组件(分为全局注册和局部注册)
3.使用组件(写组件标签)

二、注册组件

局部注册:在实例选项中注册局部组件,这样组件只能在这个实例中使用
全局注册:所有实例都能用全局组件

  1. <div id="root">
  2. <!-- 第三步:编写组件标签 -->
  3. <hello></hello>
  4. <hr>
  5. <h1>{{msg}}</h1>
  6. <hr>
  7. <!-- 第三步:编写组件标签 -->
  8. <student ></student>
  9. </div>
  10. </body>
  11. <script>
  12. Vue.config.productionTip = false //阻止 vue 在启动时生成生产提示。
  13. //第一步:创建student组件
  14. const student = Vue.extend({
  15. template:`
  16. <div>
  17. <h2>学生姓名:{{studentName}}</h2>
  18. <h2>学生年龄:{{age}}</h2>
  19. </div>
  20. `,
  21. data(){
  22. return{
  23. studentName:'张三',
  24. age:18
  25. }
  26. }
  27. })
  28. //第一步:创建hello组件
  29. const hello = Vue.extend({
  30. template:`
  31. <div>
  32. <h2>你好啊!{{name}}</h2>
  33. </div>
  34. `,
  35. data(){
  36. return{
  37. name:'Tom'
  38. }
  39. }
  40. })
  41. //第二步:全局注册组件
  42. Vue.component('hello',hello)
  43. //创建vm
  44. new Vue({
  45. el:'#root',
  46. data:{
  47. msg:'你好啊!'
  48. },
  49. //第二步,注册组件(局部组件)
  50. components:{
  51. student
  52. }
  53. })
  54. </script>

注意:

1.Vue.extend()是一个基础构造器(全局 API),意图创建一个子类;

2.Vue.component()是注册组件,参数 1 为名称,参数 2 为extend()

3.data必须写成函数,避免组件被复用时,数据存在引用关系。

三、组件的嵌套

组件和组件之间可以嵌套,形成一种父子关系的组件

  1. <div id="root">
  2. </div>
  3. </body>
  4. <script>
  5. Vue.config.productionTip = false
  6. //定义student组件
  7. const student = Vue.extend({
  8. name:'student',
  9. template:`
  10. <div>
  11. <h2>学生姓名:{{name}}</h2>
  12. <h2>学生年龄:{{age}}</h2>
  13. </div>
  14. `,
  15. data(){
  16. return {
  17. name:'张三',
  18. age:18
  19. }
  20. }
  21. })
  22. //定义school组件
  23. const school = Vue.extend({
  24. name:'school',
  25. //嵌套student组件
  26. template:`
  27. <div>
  28. <h2>学生名称:{{name}}</h2>
  29. <h2>学生地址:{{address}}</h2>
  30. <student></student>
  31. </div>
  32. `,
  33. data(){
  34. return{
  35. name:'张三',
  36. address:'北京'
  37. }
  38. },
  39. //注册组件(局部)
  40. components:{
  41. student
  42. }
  43. })
  44. //定义hello组件
  45. const hello = Vue.extend({
  46. template:`<h1>{{msg}}</h1>`,
  47. data(){
  48. return{
  49. msg:'holle vue'
  50. }
  51. }
  52. })
  53. //定义app组件
  54. const app = Vue.extend({
  55. //嵌套school、hello组件
  56. template:`
  57. <div>
  58. <hello></hello>
  59. <school></school>
  60. </div>
  61. `,
  62. //注册组件(局部)
  63. components:{
  64. school,
  65. hello
  66. }
  67. })
  68. new Vue({
  69. template:'<app></app>',
  70. el:"#root",
  71. //注册组件(局部)
  72. components:{app}
  73. })
  74. </script>

四、组件的 props 通信

1.组件的 props

1.组件的父子关系中,当设置一个独立组件时,这个组件就是 new Vue()的子组件;

2.当我们需要通过子组件显示父组件 data 值的时候,需要通过 props 属性传值

  1. <div id="root">
  2. <student text="李四"></student>
  3. //也可以用 v-bind 动态绑定 props 的值到父组件的数据中。每当父组件的数据变化时,该变化也会传导给子组件:
  4. <student v-bind:text="message"></student>
  5. </div>
  6. <script>
  7. //去掉警告
  8. Vue.config.productionTip = false;
  9. //局部组件
  10. const childComponent = Vue.extend({
  11. data() {
  12. // 子组件和父组件都有 message 属性,同时调用并不冲突;顺序也可控;
  13. return {
  14. message : '局部组件'
  15. }
  16. },
  17. //使用传过来的text
  18. template : `
  19. <div>{{text}} {{message}}</div>
  20. `,
  21. // 声明 props
  22. props : ['text']
  23. });
  24. //数据对象
  25. const dataObj = {
  26. message : '张三三',
  27. };
  28. //创建一个Vue对象
  29. //父组件
  30. const root = new Vue({
  31. el : '#root',
  32. data:dataObj,
  33. // data(){
  34. // return{
  35. // message: '张三三',
  36. // }
  37. // },
  38. components : {
  39. 'student' : childComponent
  40. },
  41. });
  42. </script>

2.组件的 props 单向数据流

1.父组件的 data 值更新后通过 props 选项交给子组件进行渲染,反之则不行;

2.这就是单向数据流(单向下行绑定),不能通过子组件来改变父组件的状态;

3.这样做的是为了防止父组件发生改变后,数据流变得难以理解;

4.父组件更新时,子组件所有 props 值也会更新,你不能改变子组件的 props 值

  1. <div id="root">
  2. <html-a v-bind:count="count"></html-a>
  3. </div>
  4. <script>
  5. //去掉警告
  6. Vue.config.productionTip = false;
  7. //局部组件
  8. const childComponent = Vue.extend({
  9. data() {
  10. return {
  11. message : '子组件',
  12. }
  13. },
  14. template : `
  15. <button v-on:click="count++">{{count}}</button>
  16. `,
  17. props : ['count'],
  18. })
  19. //创建一个Vue对象
  20. //父组件
  21. const root = new Vue({
  22. el : '#root',
  23. data : {
  24. count : 5
  25. },
  26. components : {
  27. 'html-a' : childComponent
  28. },
  29. });
  30. </script>

注意:

​ 以上内容,会正确改变了 props 的值,也渲染到视图中,但控制台报错;

​ 意为:不可以直接修改 props 值,可以通过数据或计算属性来解决;

  1. <div id="root">
  2. <html-a v-bind:count="count"></html-a>
  3. </div>
  4. <script>
  5. //去掉警告
  6. Vue.config.productionTip = false;
  7. //局部组件
  8. const childComponent = Vue.extend({
  9. //通过使用 data 数据更改
  10. data() {
  11. return {
  12. message : '子组件',
  13. childCount : this.count
  14. }
  15. },
  16. template : `
  17. <button v-on:click="clickChildCount">{{changedChildCount}}</button>
  18. `,
  19. props : ['count'],
  20. //通过使用计算属性和方法数据更改
  21. computed: {
  22. changedChildCount() {
  23. return this.childCount;
  24. }
  25. },
  26. methods: {
  27. clickChildCount() {
  28. this.childCount++
  29. }
  30. }
  31. })
  32. //创建一个Vue对象
  33. //父组件
  34. const root = new Vue({
  35. el : '#root',
  36. data : {
  37. count : 5
  38. },
  39. components : {
  40. 'html-a' : childComponent
  41. },
  42. });
  43. </script>

3.组件的 props 验证

1.之前props 选项通信采用的是数组方式,其实还有第二种方式:对象;

2.通过对象模式进行传递数据,可以对数据类型进行验证,支持的类似有:

Sting.Number.Boolean.Function.Object.Array.Symbo

  1. <div id="root">
  2. <student name="李四" sex="女" :age="18"></student>
  3. </div>
  4. <script>
  5. //去掉警告
  6. Vue.config.productionTip = false;
  7. //局部组件
  8. const childComponent = Vue.extend({
  9. //通过使用 data 数据更改
  10. data(){
  11. console.log(this)
  12. return{
  13. msg:'我是一个学生',
  14. myAge:this.age
  15. }
  16. },
  17. template : `
  18. <div>
  19. <h1>{{msg}}</h1>
  20. <h2>学生姓名:{{name}}</h2>
  21. <h2>学生性别:{{sex}}</h2>
  22. <h2>学生年龄:{{myAge+1}}</h2>
  23. <button @click="updateAge">尝试修改收到的年龄</button>
  24. </div>
  25. `,
  26. methods: {
  27. updateAge(){
  28. this.myAge++
  29. }
  30. },
  31. //简单声明介绍
  32. // props:['name','age','sex']
  33. //接收的同时对数据进行类型限制
  34. // props:{
  35. // name:String,
  36. // age:Number,
  37. // sex:String
  38. // }
  39. //接收的同时对数据进行类型限制
  40. props:{
  41. name:{
  42. type:String,//name的类型是字符串
  43. required:true,//name是必须要的
  44. },
  45. age:{
  46. type:Number,
  47. default:18//默认值
  48. },
  49. sex:{
  50. type:String,
  51. required:true
  52. }
  53. }
  54. })
  55. //父组件
  56. const root = new Vue({
  57. el : '#root',
  58. data : {
  59. count : 5
  60. },
  61. components : {
  62. 'student' : childComponent
  63. },
  64. });
  65. </script>

五、组件的自定义事件

父组件是使用 props 传递数据给子组件,但如果子组件要把数据传递回去,就需要使用自定义事件!

我们可以使用 v-on 绑定自定义事件, 每个 Vue 实例都实现了事件接口(Events interface),即:

  • 使用 $on(eventName) 监听事件
  • 使用 $emit(eventName) 触发事件

另外,父组件可以在使用子组件的地方直接用 v-on 来监听子组件触发的事件。

  1. <div id="root">
  2. {{message}}
  3. <!-- 通过父组件给子组件绑定一个自定义事件实现:子给父传递数据(第一种写法,使用@或v-on)-->
  4. <html-a v-on:child="parentFn"></html-a>
  5. </div>
  6. <script src="../js/vue.js"></script>
  7. <script>
  8. //去掉警告
  9. Vue.config.productionTip = false;
  10. //子组件
  11. const childComponent = Vue.extend({
  12. data() {
  13. return {
  14. name : 'Mr.Lon'
  15. }
  16. },
  17. template : `
  18. <div>
  19. <button v-on:click="childClick">点我把名字传给父组件</button>
  20. </div>
  21. `,
  22. methods : {
  23. childClick() {
  24. //触发子组件实例身上的child事件
  25. this.$emit('child', this.name)
  26. }
  27. }
  28. })
  29. //父组件
  30. const root = new Vue({
  31. el : '#root',
  32. data : {
  33. message : 'Hello, Vue!'
  34. },
  35. components : {
  36. 'html-a' : childComponent
  37. },
  38. //方法
  39. methods : {
  40. parentFn(name) {
  41. this.message = name;
  42. console.log('子组件传递给父组件!' + name);
  43. }
  44. }
  45. });
  46. </script>
Statement of this Website
The copyright of this blog article belongs to the blogger. Please specify the address when reprinting! If there is any infringement or violation of the law, please contact admin@php.cn Report processing!
All comments Speak rationally on civilized internet, please comply with News Comment Service Agreement
0 comments
Author's latest blog post