我是靠谱客的博主 端庄小甜瓜,最近开发中收集的这篇文章主要介绍Vue+Webpack打造todo应用(慕课学习笔记)实现的布局图实现出来的效果项目结构步骤 学习笔记:参考链接,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

这门课在慕课网是免费的,但有部分包已被弃用需要用其他包代替,详细见官网。我还不想看官网,所以先放着吧。

关于模块打包的课程可以重刷

【仅个人记录,还不完整。暂时没有参考意义哦】

别人的项目源码、我的项目源码

实现的布局图

MockPlus还不会用,随便弄的

实现出来的效果

线上效果

项目结构

步骤

1、编写app.vue

根据布局图可以写出大概的框架

<template>
    <div id="app">
        <div id="cover"></div> <!-- 背景 -->
        <Header></Header>
        <Todo></Todo>
        <Footer></Footer>
    </div>
</template>

<script>
import Header from './todo/header.vue'
import Footer from './todo/footer.jsx'
import Todo from './todo/todo.vue'

export default {
    components:{
        Header,
        Todo,
        Footer
    }
}
</script>
<style lang="stylus" scoped>
 /* 这里就不贴啦,详细的见源代码叭 */
</style>

另外,header.vue 和 footer.vue都很简单,主要讲todo.vue

2、todo.vue

todo组件由input(输入框)、item组件 和 tabs组件组成。
item组件:显示todo的项目。而数据todo是由todo.vue里传去的(父组件到子组件),因此会用到绑定属性。
tabs组件:由布局图可知。

todo组件先实现input:

<!-- todo.vue -->
<template>
  <section class="real-app">
    <input
      type="text"
      class="add-input"
      autofocus="autofocus"
      placeholder="接下去要做什么?"
      @keyup.enter="addTodo"
    />
  </section>
</template>

<script>
export default {
  methods: {
    addTodo() {}
  }
};
</script>

3、item.vue 

item.vue实现"1条todo项目的显示",用到props将数据todo(是一个对象) 从父组件(todo.vue)传到子组件(item.vue)。而且,item还有一个功能是删除,由于数据在父组件里,因此要用到emit(数据从子组件传到父组件),即写一个触发事件 this.$emit('del', this.todo.id) ,将数据(this.todo.id)从子组件传到父组件,再在父组件里删除相应的数据。
item.vue里用到了v-model="todo.completed",这个双向绑定是将item组件的todo.completed与todo组件的todo.completed绑在一起。
item.vue还用到了:class,因为想实现“当复选框为checked时,增加一条删除线表示已完成”的效果,所以会有两种不同的状态:勾选和未勾选,因此class属于动态属性,动态属性需要绑定。

<!-- item.vue -->
<template>
  <div :class="['todo-item', todo.completed ? 'completed' : '']">
    <input type="checkbox" class="toggle" v-model="todo.completed" />
    <label>{{todo.content}}</label>
    <button class="destory" @click="deleteTodo"></button>
  </div>
</template>

<script>
export default {
  props: {
    todo: {
      type: Object,
      required: true
    }
  },
  methods: {
    deleteTodo() {
        this.$emit('del', this.todo.id);
    }
  }
};
</script>

<!-- todo.vue -->
<template>
  <section class="real-app">
    <!-- ... -->
    <Item
      v-for="todo in todos" 
      :todo="todo"
      :key="todo.id"
      @del = "deleteTodo"
    />
  </section>
</template>

<script>
import Item from "./item.vue";

let id = 0;

export default {
  data() {
    return {
      todos:[]
    };
  },
  components: {
    Item
  },
  methods: {
    addTodo(e) {
      this.todos.unshift({
        id:id++,
        content:e.target.value.trim(),
        completed:false
      });
      e.target.value = '';
    },
    deleteTodo(id){
      this.todos.splice(this.todos.findIndex(todo => todo.id === id), 1);
    }
  }
};
</script>

findIndex() 方法返回传入一个测试条件(函数)符合条件的数组第一个元素位置。

findIndex() 方法为数组中的每个元素都调用一次函数执行:

  • 当数组中的元素在测试条件时返回 true 时, findIndex() 返回符合条件的元素的索引位置,之后的值不会再调用执行函数。
  • 如果没有符合条件的元素返回 -1

注意: findIndex() 对于空数组,函数是不会执行的。

注意: findIndex() 并没有改变数组的原始值。

4、tabs.vue

filter是父组件传来的属性,表示的是选中的某一个状态(all、actived或completed)。利用filter与三种状态进行对比,会将与filter匹配成功的state增加一个class值:actived(激活),利用动态的class属性  :class
filter如何得到选中的状态值呢?子组件(tabs.vue)将state值通过emit传到父组件(todo.vue)里的filter中。子组件里点击中间的按钮,会直接调用toggleFilter函数,这个函数会调用emit。注意,中间的三个按钮的显示是利用了v-for遍历,在遍历的同时,对每个按钮绑定了click事件。
一个思考:为什么要在顶级组件(todo.vue)里弄一个filter呢?如果是单纯为了改actived样式,直接在tabs组件里就能实现,为什么要通过子组件传给父组件,再由父组件传给子组件这么麻烦呢?(在tabs里直接实现的想法是:在data属性里增加一个变量用来存当前按下的按钮值就好了)

<!-- tabs.vue -->
<template>
    <div class="helper">
        <span class="left"><!-- 左 -->
            <span> {{unFinishTodoLength}} items left</span>
        </span>
        <span class="tabs"><!-- 中 -->
            <span 
                v-for="state in states" 
                :key="state"
                :class="[state, filter === state ? 'actived' : '']"
                @click="toggleFilter(state)"
            >
                {{ state }}
            </span>
        </span>
        <!-- 右 -->
        <span class="clear" @click="clearAllCompleted">Clear completed</span>
    </div>
</template>

<script>
export default {
    props:{
        filter:{
            type:String,
            required:true
        },
        todos:{
            type: Array,
            required:true
        }
    },
    data(){
        return{
            states:['all','active','completed']
        }
    },
    computed:{
        unFinishTodoLength(){
            return this.todos.filter(todo => !todo.completed).length;
        }
    },
    methods:{
        toggleFilter(state){
            this.$emit('toggle', state);
        },
        clearAllCompleted(){
            this.$emit('clearAllCompleted');
        }
    }
}
</script>

<!-- todo.vue -->
<template>
  <section class="real-app">
    <input />
    <Item  />
    <Tabs 
      :filter="filter" 
      :todos="todos"
      @toggle = 'toggleFilter'
      @clearAllCompleted = 'clearAllCompleted'
    />
  </section>
</template>

<script>
import Item from "./item.vue";
import Tabs from "./tabs.vue";
let id = 0;

export default {
  data() {
    return {
      todos:[],
      filter:'all'
    };
  },
  components: {
    Item,
    Tabs
  },
  computed:{
    filteredTodos(){
      if(this.filter === 'all'){
        return this.todos;
      }
      const completed = this.filter === 'completed'; //filter是当前用户选择想看的是哪个。active、completed
      return this.todos.filter(todo => todo.completed === completed);//这个的思路可以细品
    }
  },
  methods: {
    addTodo(e) {
      //...
    },
    deleteTodo(id){
      //...
    },
    toggleFilter(state){
      this.filter = state;
    },
    clearAllCompleted(){
      this.todos = this.todos.filter(todo => !todo.completed);
    }
  }
};
</script>

还有一些零碎的东西,具体就见源代码叭

 学习笔记:

  1. 学习如何工程化比业务开发更重要
  2. 前端价值
    1. 搭建前端工程,如数据缓存
    2. 网络优化,如加快http请求的速度
    3. API定制
    4. nodejs层
  3. 新建项目的步骤
    1. npm init(生成包管理文件package.json)
    2. npm i webpack vue vue-loader(这里没有区分生产环境和开发环境)
    3. 把出现了WARN和peer(第三方依赖)两个单词的文件也进行安装
    4. 新建.gitignore文件让git忽略node_modules文件
  4. 配置Webpack
    1. 热加载:当修改部分代码时只改动对应的功能,而不会刷新界面。好处:不会丢失前面操作的数据
  5. vue的学习
    1. 数据的传递
      1. 数据从父组件传到子组件要用props
      2. 数据从子组件传到父组件要用emit、on
      3. “数据在哪里声明,就在哪里进行操作”
    2. 使用v-for要绑定唯一的key属性,因为循环是一个非常耗时耗资源的操作,指定了key之后,下一次循环如果key值相同,vue是会复用当前的节点,而不会生成一个新的节点。这样可以提高性能
    3. v-bind与v-model还不太清晰
    4. 在交互实现中经常用到数组的filter方法(todo.vue文件)
    5. 实现界面的步骤是先实现基本的界面,比如
      <span>2 items left</span>
      ,再实现交互,比如
      <span>{{unFinishTodoLength}} items left </span>

       

  6. jsx是通过babel编译的,因此课程里有下载babel的操作。
  7. 不管是vue还是react,最后都是解析成render方法,然后进行dom的插入(说法貌似不准确,还需要确定
  8. ChunkHash与hash。使用ChunkHash的话,每个chunk都会有一个不同的hash值。
  9. 打包和优化的课程没怎么听懂,由于课程提到的配置Commons ChunkPlugin都弃用了,自己没有重新配。
    1. 参考链接1,参考链接2,参考链接3,参考链接4
  10. 讲师对前端的看法。链接
    1. 前端开发不仅仅是业务开发,最好学会做方便自己开发的流程(类似于dev-server这样的工具)推荐:Webpack官网
    2. 眼界要放宽:先了解作为一个前端工程要去解决一个什么问题

参考链接

  • webpack打包踩坑之TypeError: Cannot read property 'bindings' of null
  • cross-env使用
  • webpack-dev-server使用方法,看完还不会的来找我~

最后

以上就是端庄小甜瓜为你收集整理的Vue+Webpack打造todo应用(慕课学习笔记)实现的布局图实现出来的效果项目结构步骤 学习笔记:参考链接的全部内容,希望文章能够帮你解决Vue+Webpack打造todo应用(慕课学习笔记)实现的布局图实现出来的效果项目结构步骤 学习笔记:参考链接所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(59)

评论列表共有 0 条评论

立即
投稿
返回
顶部