Vue 框架基础4-组件思想和组件通信

创建组件

1. 组件系统是 Vue 的另一个重要概念,因为它是一种抽象,允许我们使用小型、独立和通常可复用的组件构建大型应用。仔细想想,几乎任意类型的应用界面都可以抽象为一个组件树:
在这里插入图片描述
2. 定义组件选项

const options = {
  template: '模板-视图的结构(布局)',
  data() {
    return {}
  },
  methods: {},
  computed: {},
  components: {},
}

注意:

  • template 中定义的结构,必须使用单个根元素包裹
  • data 必须是函数结构,在函数体内部返回一个普通对象
  • 为什么 data 要是函数?

(1).组件是可被复用的,当创建同一个组件的不同实例时,如果 data 是普通对象,则不同的实例引用到的是同一个 data 对象,当任意一个实例中对 data 数据进行更新时,其它实例都会受影响,通常这与实际业务不符。

(2).定义成函数,则创建各组件实例时,会调用 data 函数生成组件实例自身私有用到的对象数据,各组件实例间数据是独立的,互不受影响。

3. 注册组件:

  • 注册全局组件 Vue.component(name, options)
 <script src="/Vue框架的初步了解/libs/vue.js"></script>//引入Vue框架文件
    <script>
        /* TodoHeader */
        Vue.component('todo-header', {//这是全局组件TodoHeader 
            template: `
              <h3>组件渲染的内容。。。</h3>
             `,
        })
  • 注册局部组件 components: {name: componentOptions}
           /* TodoList */
        Vue.component('todo-list', {//这是全局组件TodoList 
            template: `
            <ul v-if="true">
              <todo-item v-for="n in 4"></todo-item>
            </ul>
            <div v-else>
              代办事项列表为空,请添加代办事项!
            </div>
             `,
            components: { //局部组件注册 toto-item
                'todo-item': {
                    template: `
                 <li>
                    <input type="checkbox" />
                    <span>代办事项内容</span>
                    <button>删除</button>
                </li>
                 `,
                },
            },
        })

**4.**渲染主键

  <div id="app">
       <todo-header></todo-header>// 刚才注册的组件名,采用短横线命名规范 

       <todo-input></todo-input>

       <todo-list></todo-list>

       <todo-footer></todo-footer>
    </div>
    
        /* 注册的组件 */
    
      /* APP */ 
        new Vue({
            el:'#app',
           
        })

注意:
在使用自定义组件名作为标签名称使用时,要完整书写独立的结束标签,标签名称应该使用短横线命名的规范。

父子件通信

  • 父组件传数据给子组件:利用属性(props)的方式传递数据。
    (1).子组件定义时,在选项中使用 props 定义组件可接收的属性。
components: {
               son: {
                   template: `
                    <div>
                       <span>这是子组件内容:{{ name }} - {{ sex }} - {{ phone }}</span><br> 
                       //标签里接收 (props) 属性传递来的数据
                       <button @click="handleClick">像父组件传递数据</button>
                    </div>
                   `,
                //    props: ['name' , 'sex' ,'phone'],//声明组件可接收的属性名称
                props: {// 声明组件及可接收的属性名极其校验规则
                    name: String,
                    sex: {
                        type: String,
                        default: '男',
                    },
                    phone: {
                        type: String,
                        required: true,
                    }
                },

(2).父组件中使用到子组件(标签)时,在标签内部书写需要传递给子组件的数据(是 name=value 键值对格式的属性)。

 Vue.component('father',{
           template: `
           <div>
             <span>这个是父组件内容</span>
             // 在条用的子组件标签内部书写传递给子组件的数据
             <son name="小明" sex="男" :phone="phone"></son>
             </div>
           `,
  • 子传父:利用事件方式传递数据。
    (1).父组件中使用到子组件标签时,利用 v-on 注册一个自定义的事件监听,通常引用在父组件中定义的 methods 方法去处理接收到的数据。
  Vue.component('father',{
           template: `
           <div>
             <span>这个是父组件内容</span>
        <!-- <son name="小明" sex="男" :phone="phone"></son> -->
             <son name="小明"
              :phone="phone"
              @receive="handleReceive"
              ></son>
             </div>
           `,
           data() {
              return {
                  phone: '123456789',
              }
           },
           methods: {
            handleReceive(data) {
                console.log('这是父组件中用于接收数据的方法:',data);
               
            }
           },

(2).在子组件中需要传递数据时,调用 this.$emit(eventName(上面自定义事件名), data(向父组件传递的数据)) 触发在父组件中绑定的自定义事件并传递数据即可($emit() 的第二个参数是需要传递给父组件的数据)

 components: {
               son: {
                   template: `
                    <div>
                       <span>这是子组件内容:{{ name }} - {{ sex }} - {{ phone }}</span><br> 
                       <button @click="handleClick">像父组件传递数据</button>
                    </div>
                   `,
                //    props: ['name' , 'sex' ,'phone'],//声明组件可接收的属性名称
                props: {// 声明组件及可接收的属性名极其校验规则
                    name: String,
                    sex: {
                        type: String,
                        default: '男',
                    },
                    phone: {
                        type: String,
                        required: true,
                    }
                },
                methods: {
                    handleClick() {
                        console.log('传送数据');
                         // 调用(触发)在父组件中绑定的事件,像父组件传递数据。
                         this.$emit('receive',{code: 200,data: {uuserInfo: {name: '张三',age: 18}}})
                    },
                }

跨组件层级组件通信

  • 转换为父子关系
  • event-bus(事件总线):
    (1).借助 Vue 实例中的 $on()$emit() 方法来实现:首先创建一个全局的 Vue 实例对象(bus)
 //创建一个 Vue 实例对象,用于在组件间进行通信(不传递选项对象参数)
    // const eventBus = new Vue()

    //向 Vue.prototype 原型中添加一个自定得 $bus 属性
    //在所有得 Vue 实例及组件实例中,都可以使用 this.$bus
    //来访问到这个属性得值
     Vue.prototype.$bus = new Vue()

(2).在需要接收数据的组件中,利用 bus 来注册事件监听(绑定自定义事件)

    methods: {
        // 处理添加代办事项
        handIeAddTodoTiem(title) {
          this.todos.push({
            id: Math.random(),
            title,
            completed: false,
          })
        },
        // 删除代办事项
        removeIodoItem(id) {
          this.todos = this.todos.filter(todo => todo.id !== id)
        }
      },
      created() { // 这是一个生命周期得钩子函数
        // 当前组件(App)会接收数据,调用 eventBus.$on() 绑定事件
        // eventBus.$on('remove', this.removeIodoItem)
           this.$bus.$on('remove', this.removeIodoItem)
           // remove (为自定义事件) removeIodoItem (事件处理函数)
      }

(3).在需要传递数据的组件中,利用 bus 来触发事件并传递数据。

  // 在需要传递数据的组件中,利用 `bus` 来触发事件并传递数据。
 methods: {
            handleRemove() {
              // eventBus.$emit('remove', this.item.id)
              this.$bus.$emit('remove', this.item.id)
            }
          }
  • vuex
  • 5
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值