【Vue案例】使用Vue实现doList任务队列

效果图


文件关系图


1.Vue.config.js

const { defineConfig } = require('@vue/cli-service')
module.exports = defineConfig({
  transpileDependencies: true,
  lintOnSave:false
})

Vue.js项目的配置文件。使用@vue/cli-service模块中的defineConfig方法定义配置对象

配置项:

  1. transpileDependencies:true:表示在构建过程中对依赖进行转译,确保项目的兼容性。默认情况下,Babel只会对Vue CLI创建的项目自身代码进行转译,而不会对依赖的第三方库进行转译;

  2. lintOnSave:false:表示在保存文件时,是否启用ESLint进行代码检查。设置为false后保存文件不会触发ESLint的检查;


2. main.js

import Vue from 'vue'
import App from './App.vue'

Vue.config.productionTip = false

new Vue({
  render: h => h(App),
}).$mount('#app')

Vue.js应用程序的入口文件

  • 导入Vue.js模块,并赋值给变量Vue;

  • 从当前目录导入App.vue文件,并赋值给变量App;

  1. Vue.config.productionTip=false:禁用生产模式下的一些提示信息;

  2. new Vue():创建一个Vue实例,将App组件作为根组件进行渲染。在render函数中使用箭头函数的简写语法将h(createElement)参数传递进去,并返回了App组件的渲染结果;

  3. $mount('#app')将Vue实例挂载到HTML中具有id="app"的元素上,并显示在页面上;


3. App.vue

3.1.template

<template>
  <div id="App">
    <MyHeader :addTodo="addTodo"></MyHeader>
    <MyList :deleteTodo="deleteTodo" :checkTodo="checkTodo" :todos="todos"></MyList>
    <MyFooter :todos="todos" :checkAllTodo="checkAllTodo" :clearAllTodo="clearAllTodo"></MyFooter>
  </div>
</template>

App.vue的template部分的描述

  1. 定义一个idAppdiv块级元素;

  2. 使用自定义组件MyHeader传递一个属性addTodoaddTodo属性指向父组件中的一个方法addTodo,实现子组件向父组件传递数据的功能;

  3. 使用自定义组件MyList传递三个属性deleteTodocheckTodotodos,这些属性指向父组件中的三个方法和一个数据,实现子组件向父组件传递数据和方法的功能;

  4. 使用自定义组件MyFooter传递三个属性todoscheckAllTodoclearAllTodo,这些属性指向子组件中的一个数据和两个方法,实现子组件向父组件传递数据和方法的功能;

3.2.script

<script>
import MyHeader from "@/components/MyHeader.vue";
import MyList from "@/components/MyList.vue";
import MyFooter from "@/components/MyFooter.vue";

export default {
  name: 'App',
  data(){
    return{
      todos:[
        {id:'001',title:'测试数据A',done:false},
        {id:'002',title:'测试数据B',done:false},
        {id:"003",title:'测试数据C',done:false}
      ]
    }
  },
  methods:{
    //添加任务
    addTodo(todoObj){

      this.todos.unshift(todoObj);
      console.log("addTodo("+todoObj+")");
    },
    //勾选或者取消一个任务
    checkTodo(id){
      this.todos.forEach(item =>{
        if(item.id == id){
          item.done = !item.done;
          console.log("checkTodo("+id+"):"+item.done!=item.done);
          return;
        }
      })
    },
    deleteTodo(id){
      this.todos = this.todos.filter(item =>{
        console.log("deleteTodo("+id+"):"+item.id !=id);
        return item.id !=id;
      })
    },
    checkAllTodo(done){
      console.log("checkAllTodo("+done+")");
      this.todos.forEach(item=> item.done =done);
    },
    clearAllTodo(){
      console.log("clearAllTodo():"+ this.todos.filter(item => !item.done));
      this.todos = this.todos.filter(item => !item.done);
    }
  },
  components: {MyFooter, MyList, MyHeader}
}
</script>

App.vue的script部分的表述

  1. 使用import引入MyHeaderMyListMyFooter三个自定义组件;

  2. 通过export default导入当前Vue组件的配置;

  3. components属性是一个对象,包含了三个键值对,对应引入的三个自定义组件:MyFooterMyListMyHeader;

  • name属性用于指定当前组件的名称;

  • data方法返回一个对象,对象中有一个todos的属性,包含了三个任务对象;每个任务对象都有id:任务的唯一标识,title:标题,done:完成状态;

  • addTodo方法用于向任务列表中添加一个新的任务对象,通过unshift方法将任务对象插入到todos数组的开头;

  • checkTodo方法用于勾选或取消一个任务,通过遍历todos数组找到对应的任务,并修改done属性的值;

  • deleteTodo方法用于删除一个任务,通过使用filter方法过滤掉要删除的任务,并重新赋值给todos数组;

  • checkAllTodo方法用于全选或取消全选任务,遍历todos数组将所有任务的done属性设置为传入的值;

  • clearAllTodo方法用于清楚所有已完成的任务,通过使用filter方法过滤掉已完成的任务,并重新赋值给todos数组;

3.3.style

<style>
h2{
  color: orange;
}
</style>

4. MyHeader.vue

4.1.template

<template>
  <div class="header">
    <input type="text" v-model="title"@keydown.enter="add" placeholder="请输入任务名称,按回车"/>
  </div>
</template>

MyHeader.vue的template部分的描述

  1. 定义一个包含输入框<input>元素的<div>块级元素;

  2. 使用v-model绑定title属性;

  3. 使用@keydown.enter="add"监听键盘的Enter事件,触发时调用add方法;

4.2.script

<script>
import {nanoid} from "nanoid";
export default {
  name: "MyHeader",
  props:['addTodo'],
  data(){
    return{
      title:''
    }
  },
  methods:{
    add(){
      let todoObj ={id:nanoid(),title:this.title,done:false};
      console.log("MyHeader:add():"+todoObj);
      this.addTodo(todoObj);
      this.title ='';
    }
  }
}
</script>

MyHeader.vue的script部分的描述

  1. 导入nanoid函数;

  2. 通过export default导入当前Vue组件的配置;

  • 定义名为MyHeader的组件;

  • 使用props属性声明一个名为addTodo的prop菜鸟教程对prop的描述

  • data方法中初始化一个名为title的属性;

  • 定义一个名为add的方法,在用户按下Enter键时会创建一个包含输入内容的todo对象,然后通过addTodoprop将该对象传递给父组件,最后清空输入框内容;

4.3.style

<style scoped>
.header input {
  width: 560px;
  height: 28px;
  font-size: 14px;
  border: 1px solid #ccc;
  border-radius: 4px;
  padding: 4px 7px;
}

.header input:focus {
  outline: none;
  border-color: rgba(82, 168, 236, 0.8);
  box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075), 0 0 8px rgba(82, 168, 236, 0.6);
}
</style>

5. MyItem.vue

5.1.template

<template>
  <li>
    <label>
      <input type="checkbox" @click="handleCheck(todo.id)" :checked="todo.done"/>
      <span>{{todo.title}}</span>
    </label>
    <button class="btn" @click="handleDelete(todo.id,todo.title)">删除</button>
  </li>
</template>

MyItem.vue的template部分的描述

  1. 定义一个type属性为checkbox的复选框输入类型的input元素;

  2. 通过@click事件监听器绑定一个handleCheck(todo.id)的点击事件处理函数,复选框被点击时触发;

  3. :checked用于动态绑定复选框的选中状态;

  4. 绑定todo.done属性根据todo对象的done属性确定是否选中复选框;

  5. 定义一个button元素,通过@click事件监听器绑定一个;handleDelete(todo.id,todo.title)点击事件处理函数,当按钮被点击时会触发,并传递todo.idtodo.title作为参数;

5.2.script

<script>
export default {
  name: "MyItem",
  props:['todo',"checkTodo",'deleteTodo'],
  methods: {
    handleCheck(id) {
      console.log("MyItem:handleCheck("+id+")");
      this.checkTodo(id);
    },
    handleDelete(id, title) {
      if (confirm("确定删除" + title + "任务吗?")) {
        console.log("MyItem:handleDelete("+id,title+")");
        this.deleteTodo(id);
      }
    }
  }
}
</script>

MyItem.vue的scirpt部分的描述

  1. 通过export default导入当前Vue组件的配置;

  • name属性用于指定当前组件的名称;

  • props属性是一个数组,数组中的字符串元素代表了父组件可以通过这些属性向当前组件传递数据或方法;

  • handleCheck方法接受一个参数id,使用this.checkTodo调用父组件传递过来的checkTodo方法,并将id作为参数传递;

  • hendleDelete方法接受两个参数idtitle,通过弹窗confirm确认是否删除,如果确认,则调用this.deleteTodo(id)方法,this.deleteTodo(id)调用父组件传递过来的deleteTodo方法,并将id作为参数传递;

5.3.style

<style scoped>
li {
  list-style: none;
  height: 36px;
  width: 560px;
  line-height: 36px;
  padding: 0 5px;
  border-bottom: 1px solid #ddd;
}

li label {
  float: left;
  cursor: pointer;
}

li label li input {
  vertical-align: middle;
  margin-right: 6px;
//position: relative; //top: -1;
}

li button {
  float: right;
  display: none;
  margin-top: 5px;
}

li:before {
  cursor: inherit;
}

li:last-child {
  border-bottom: none;
}

li:hover {
  background-color: #eee;
}

li:hover button {
  display: block;
}
</style>

6. MyList.vue

6.1.template

<template>
  <ul class="main">
    <MyItem v-for="t in todos" :key="t.id"
            :todo="t"
            :checkTodo="checkTodo"
            :deleteTodo="deleteTodo"
    />
  </ul>
</template>

MyList.vue的template部分的描述

  1. 定义一个ul元素;

  2. 使用v-for遍历名为todos的数组,数组中的每个元素都会生成一个MyItem组件的实例;

  3. :key用来设置每个生产实例的唯一标识,这里使用每个todo对象的id属性;

  4. 通过:todo属性将遍历到的todo对象传递给子组件;

  5. :checkTodo:deleteTodo属性传递两个函数checkTododeleteTodo用于处理点击事件;

6.2.script

<script>
import MyItem from "@/components/MyItem.vue";

export default {
  name: "MyList",
  props: ['todos', "checkTodo",'deleteTodo'],
  components: {MyItem}
}
</script>

MyList.vue的script部分的描述

  1. 使用ES6的模块导入语法导入名为MyItem的组件;

  2. 通过export default导入当前Vue组件的配置;

  • name属性用于指定当前组件的名称;

  • props属性是一个数组,数组中的字符串元素代表了父组件通过这些属性名向当前组件传递数据或方法;

  • components属性代表将MyItem组件注册为当前组件的局部组件;

6.3.style

<style scoped>
.main {
  width: 570px;
  margin-left: 0px;
  border: 1px solid #ddd;
  border-radius: 2px;
  padding: 0px;
}
</style>

7. MyFooter.vue

7.1.template

<template>
  <div class="footer" v-show="true">
    <label>
      <input type="checkbox" v-model="isAll"/>
      全选
    </label>
    <span>
      <span>已完成{{doneTotal}}</span>/全部{{total}}
    </span>
    <button @click="clearAll">删除已完成任务</button>
  </div>
</template>

MyFooter.vue的template部分的描述

  1. v-show将一个classfooterdiv块元素始终显示在页面上;

  2. type属性为checkbox的复选框用v-model绑定在isAll属性,表示是否全部选中;

  3. 使用插值表达式{{}}动态显示doneTotaltotal变量的值;

  4. 定义<button>元素,通过@click事件监听器绑定一个clearAll点击事件处理函数,当按钮被点击时会触发;

7.2.script

<script>
export default {
  name: "MyFooter",
  props:['todos','checkAllTodo','clearAllTodo'],
  computed:{
    doneTotal(){
      console.log("MyFooter:doTotal():"+this.todos.reduce((pre,todo) =>pre + (todo.done ? 1:0),0));
      return this.todos.reduce((pre,todo) =>pre + (todo.done ? 1:0),0);
    },
    total(){
      console.log("MyFooter:total():"+this.todos.length);
      return this.todos.length;
    },
    isAll:{
      get(){
        console.log("MyFooter:isAll:get():"+this.total===this.doneTotal && this.total >0);
        return this.total === this.doneTotal && this.total >0;
      },
      set(value){
        console.log("MyFooter:isAll:set("+value+"):"+this.checkAllTodo(value));
        this.checkAllTodo(value);
      }
    }
  },
  methods:{
    clearAll(){
      console.log("MyFooter:clearAll():"+this.clearAllTodo);
      this.clearAllTodo();
    }
  }
}
</script>

MyFooter.vue的script部分的描述

  1. 通过export default导入当前Vue组件的配置;

  • name属性用来指定当前组件的名称;

  • props属性是一个数组,数组中的字符串元素代表了父组件可以通过这些属性向当前组件传递数据或方法;

  • doneTotal计算已完成任务的数量,使用reduce方法遍历todos数组并统计done属性为true的元素数量;

  • total计算总任务的数量,直接返回todos数组的长度;

  • isAll计算用于控制全选复选框的状态。通过get函数和set函数实现对全选状态的监听和修改;

  • clearAll方法用于清除所有已完成任务,当触发清除按钮时会调用父组件传递过来的clearAllTodo方法;

7.3.style

<style scoped>

.footer {
  width: 570px;
  height: 40px;
  line-height: 40px;
  padding-left: 7px;
  margin-top: 5px;
}

.footer label {
  display: inline-block;
  margin-right: 20px;
  cursor: pointer;
}

.footer label input {
//position: relative; vertical-align: middle; margin-right: 5px;
}

.footer button {
  float: right;
  margin-top: 5px;
}
</style>

时贰肆年壹月捌日凌晨

  • 17
    点赞
  • 24
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
### 回答1: 可以使用Vue路由来实现tab栏切换,具体步骤如下: 1. 在Vue组件中引入Vue Router,例如: ``` import Vue from 'vue' import Router from 'vue-router' Vue.use(Router) ``` 2. 定义路由,这里以两个tab页为例: ``` const router = new Router({ routes: [ { path: '/', name: 'Tab1', component: Tab1 }, { path: '/tab2', name: 'Tab2', component: Tab2 } ] }) ``` 3. 在模板中使用路由切换: ``` <template> <div> <ul> <li @click="switchTab('/')">Tab1</li> <li @click="switchTab('/tab2')">Tab2</li> </ul> <!-- 根据路由切换显示的组件 --> <router-view></router-view> </div> </template> <script> export default { methods: { switchTab(path) { this.$router.push({ path }) } } } </script> ``` 这样,在点击tab时就会触发路由切换,显示对应的组件。 ### 回答2: Vue是一种流行的JavaScript框架,它可以帮助我们快速构建响应式的Web应用程序。Vue路由是Vue.js框架的一部分,它允许我们通过切换URL来渲染不同的组件。在这篇文章中,我们将使用Vue路由实现一个tab栏的切换案例。 首先,我们需要创建一个Vue应用程序,包括Vue.jsVue路由。我们可以使用Vue CLI来初始化项目。然后安装Vue路由:`npm install vue-router --save`。在Vue组件中使用vue-router非常简单,我们只需要在Vue组件中导入vue-router,创建路由对象,以及定义每个路由的配置。让我们看一个示例: ``` <template> <div> <nav> <ul> <li><router-link to="/home">Home</router-link></li> <li><router-link to="/about">About</router-link></li> <li><router-link to="/contact">Contact</router-link></li> </ul> </nav> <router-view></router-view> </div> </template> <script> import Vue from 'vue' import VueRouter from 'vue-router' import Home from './Home.vue' import About from './About.vue' import Contact from './Contact.vue' Vue.use(VueRouter) const routes = [ { path: '/home', component: Home }, { path: '/about', component: About }, { path: '/contact', component: Contact } ] const router = new VueRouter({ routes }) export default { router } </script> ``` 在这个例子中,我们创建了一个Vue组件,包括一个nav标签和一个router-view标签。我们使用`<router-link>`标签创建3个不同的路由,分别是“/home”,“/about”,“/contact”。`<router-view>`标签充当路由的出口点。我们还导入了3个不同的组件,分别对应每个路由。在Vue导出对象时,我们将路由对象添加到实例中。 tab栏的实现方式应该比上面的示例更简单。我们可以使用Boostrap或Material Design Lite等CSS框架来创建tab栏,然后将每个选项卡链接到不同的路由。在Vue组件中,我们可以使用CSS框架提供的样式和属性来实现选项卡。以下是一个例子: ``` <template> <div> <ul class="nav nav-tabs"> <li class="nav-item"> <router-link to="/home" class="nav-link">Home</router-link> </li> <li class="nav-item"> <router-link to="/about" class="nav-link">About</router-link> </li> <li class="nav-item"> <router-link to="/contact" class="nav-link">Contact</router-link> </li> </ul> <router-view></router-view> </div> </template> <script> import Vue from 'vue' import VueRouter from 'vue-router' import Home from './Home.vue' import About from './About.vue' import Contact from './Contact.vue' Vue.use(VueRouter) const routes = [ { path: '/home', component: Home }, { path: '/about', component: About }, { path: '/contact', component: Contact } ] const router = new VueRouter({ routes }) export default { router } </script> ``` 在这个例子中,我们使用Boostrap的CSS样式创建了tab栏。我们将vue-router链接添加到每个选项卡中,每个链接都有不同的路由路径。当用户单击选项卡中的链接时,Vue路由将选择正确的组件来渲染在`<router-view>`标签中。 总结一下,在Vue的路由例子中实现tab切换并不复杂。我们只需要在Vue组件中导入vue-router,创建路由对象,定义每个路由配置,以及使用CSS框架来创建tab栏,就可以实现一个多页签的切换功能。 ### 回答3: Vue路由是Vue.js官方提供的一个路由管理器,它可以实现前端路由的跳转,使我们可以更好地管理前端路由。在实现tab栏切换案例中,我们可以使用Vue路由来控制各个选项之间的切换跳转。下面我将介绍一下如何使用Vue路由实现tab栏切换案例。 首先,我们需要安装Vue-router插件,使用命令:npm install vue-router --save。 其次,我们需要在Vue的main.js中引入路由,实例化VueRouter并挂载到Vue上。代码如下: ``` import Vue from 'vue' import VueRouter from 'vue-router' import App from './App.vue' import Home from './components/Home.vue' import About from './components/About.vue' Vue.use(VueRouter) const routes = [ { path: '/', component: Home }, { path: '/about', component: About } ] const router = new VueRouter({ routes }) new Vue({ el: '#app', router, render: h => h(App) }) ``` 这段代码中,我们定义了两个路由,一个是’/’,代表首页;另一个是’/about’,代表关于我们页面。然后实例化了VueRouter,把我们定义的路由传进去,在Vue实例中把VueRouter挂载上。 接着,在模板中,我们可以使用router-link组件来实现tab栏的按钮。router-link是Vue-router提供的组件,可以用来渲染带有路由功能的链接。代码如下: ``` <template> <div id="app"> <ul> <router-link to="/">首页</router-link> <router-link to="/about">关于我们</router-link> </ul> <router-view></router-view> </div> </template> ``` 在这段代码中,我们在一个UL标签中使用了两个router-link标签,分别代表首页和关于我们。to属性指定了路由路径,可以通过点击这个router-link标签进行跳转。 最后,我们需要在组件中定义这两个路由对应的页面内容。我们创建了两个名为Home和About的组件,代码如下: ``` <template> <div> <p>{{ message }}</p> </div> </template> <script> export default { data() { return { message: '这是首页' } } } </script> ``` 和About.vue组件 ``` <template> <div> <p>{{ message }}</p> </div> </template> <script> export default { data() { return { message: '这是关于我们' } } } </script> ``` 这两个组件用来渲染页面内容。当我们点击router-link标签时,页面会自动跳转到对应的路由下,并渲染出相应的组件内容。 到此,我们就成功地实现了tab栏切换案例使用Vue路由来实现轻松简单。通过Vue-router,我们可以很轻松地实现前端路由功能,使我们的前端开发变得更加灵活和高效。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值