VUE入门开发

2019/10/14 vue

在进入vue开发的过程中,我们上一节已经探讨了vue入门中的进本语法,标签绑定等。这一节我们具体结合一个案例来理解vue中的组件开发

1,工程结构分析

我们将要创建一个如下图的简单工程

我们将这个模块拆分为如下小块

所以我们在components目录中创建了如下的模块

2,创建模板工程

在选定的工程目录中使用如下命令,进行模板的创建;

vue init webpack vue-demo

关于eslint,test等模块单元,我们暂时先不考虑,直接选择no

cd vue-demo 进入工程目录,进行其他组件的安装 npm install

模板测试:npm run dev

进入浏览器 输入localhost:8080,出现vue logo界面即认为模板创建成功

模板结构如下:

3, 创建项目基本结构

  • 1, 在app.vue标签中引入我们创建好的组件标签
<template>
  <div class="todo-container">
    <div class="todo-wrap">
      <!-- 1,先引入三个组件,具体实现待各个组件自己完成-->
      <!-- <TodoHeader :addTodo="addTodo"/> -->
      <TodoHeader ref="header"/>
      <TodoList :todos = "todos"/>
      <TodoFooter/>
    </div>
  </div>
</template>
  • 2, 在app.vue中引入组件
// 2,引入的组件需要被导入才可以被使用
import PubSub from 'pubsub-js'
import TodoHeader from './components/TodoHeader'
import TodoList from './components/TodoList'
import TodoFooter from './components/TodoFooter'
import storageUtils from './utils/storageUtils'
  • 3, 声明引入的组件,这样我们就可以使用这些组件
// 3, 引入组件之后,需要声明这些组件,模板中才可以使用
  components: {
    TodoHeader,
    TodoList,
    TodoFooter
  }
  • 在各个组件引入各个组件各自的css样式(不展示)

现在我们启动运行 npm run dev 就可以看到我们要做的项目的基本静态页面了

现在我们需要考虑一个问题,就是组件之间如何通信呢,也就是app.vue如何与他们的子组件如何进行互动呢?

4, vue组件间进行通信

vue组件之间的通信有如下5种方式,今天我们会在这里讲述前4中

1) props
2) vue 的自定义事件
3) 消息订阅与发布(: pubsub )
4) slot
5) vuex(后面单独讲)
  • 4.1 props 通信

    • 在app.vue中的TodoList组件中使用如下强制绑定的方式,将数据传递到TodoList组件中
    <TodoList :todos = "todos"/>
    
    • 当然,这个todos是需要在app.vue中定义的数据
    data () {
        return {
          todos: storageUtils.readTodos()  // 从浏览器缓存中获取数据 storageUtils后面再讲
        }
      },
    
    • 在TodoList组件中接收父组件app.vue中传递过来的数据
    <template>
      <ul class="todo-main">
          <TodoItem v-for="(todo,index) in todos" :key="index"
                :todo="todo" :index="index"/>    <!-- todos为app.vue中传递过来的,:todo是要传递到下一个组件的数据,index也是如此-->
      </ul>
    </template>
    
    import TodoItem from './TodoItem'
    export default {
      // 3, 传递过来的数据要进行显示声明. 声明接收标签属性
      props:[
          'todos','deleteTodo'  // 这样的声明可以接收数据,也可以接收方法等之类的数据
      ]
      components: {
          TodoItem
      }
    }
    

    这样我们就通过props的方式将数据从父组件传递到了子组件。

    说明:props只能向子组件传递数据,不能是子组件向父组件传递数据。

  • 4.2 绑定事件监听 进行组件通信

在app.vue中header组件标定一个唯一事件标记

 <TodoHeader ref="header"/>

在app.vue中向这个组件注册函数

mounted(){
    this.$refs.header.$on('addTodo',  this.addTodo)
  },
methods: {
    addTodo (todo) {
        this.todos.unshift(todo)
    }
}

在TodoHeader组件中使用这个声明的函数

 methods: {
      add () {
        ... 
        /*触发自定义事件: addTodo*/
        this.$emit('addTodo', todo)   // 需要使用$emit函数才能调用
        // 清除输入
        this.inputTodo = ''
      }
    }

注意:此方式只用于子组件向父组件发送消息(数据)

问题: 隔代组件或兄弟组件间通信此种方式不合适

  • 4.3 组件间通信,消息订阅与发布(PubSubJS 库)

使用此组件需要安装

安装完毕我们就可以使用该组件了

在app.vue中对外订阅一个函数

mounted(){
    // 订阅消息(deleteTodo)  // 会随时监听这个函数是否有发布新的消息
    PubSub.subscribe('deleteTodo', (msg, index) => {
      this.deleteTodo(index)
    })
  }

定义一个删除的函数

methods: {
    deleteTodo (index) {
        this.todos.splice(index, 1)
      }
}

在ListItem组件中发布一个删除方法

methods: {
       deleteItem () {
        // 发布消息(deleteTodo)
        PubSub.publish('deleteTodo', this.index)
      }

优点: 此方式可实现任意关系组件间通信(数据)

  • 4.4 组件间通信 slot

在app.vue中引入的footer.vue组件中添加slot组件

<TodoFooter>
        <input type="checkbox" v-model="checkAll" slot="checkAll"/>
        <span slot="size">已完成 / 全部</span>
        <button class="btn btn-danger" v-show="completeSize" @click="deleteAllCompleted" slot="delete">清除已完成任务</button>
</TodoFooter>

slot中可以引入方法,或者我们绑定的数据

在footer.vue中使用这些定义的slot组件

<template>
  <div class="todo-footer">
    <label>
      <slot name="checkAll"></slot>
    </label>
    <span>
       <slot name="size"></slot>
    </span>
    <slot name="delete"></slot>
  </div>
</template>

此方式用于父组件向子组件传递标签数据

这样我们整个的vue组件间通信就介绍完毕了。

Search

    Table of Contents