Vue2-TodoList案例(初级 后面会进行完善)

news2025/1/20 3:40:11

🥔:觉得累是因为在走上坡路

本案例是初级案例,在下面几节会进行完善——Vue.js

TodoList案例

    • 组件化编码流程(通用)
    • 整体思路
      • 1、分析结构
      • 2、拆html和css
      • 3、初始化列表
      • 4、实现添加列表功能
      • 5、实现勾选功能
      • 6、实现删除功能
      • 7、实现底部统计功能
      • 8、实现全选框的交互
        • (1)每个todo控制全选框
        • (2)全选框控制todo全选或者取消全选:使用点击事件实现。
        • (3)全选框控制todo全选或者取消全选:使用v-model实现。
      • 9、点击右下角按钮删除全部已完成任务
    • 案例完整代码展示
      • 1、App.vue
      • 2、TodolistHeader.vue
      • 3、TodolistList.vue
      • 4、TodolistItem.vue
      • 5、TodolistFooter.vue
    • 总结

组件化编码流程(通用)

  1. 实现静态组件:抽取组件,使用组件实现静态页面效果

  2. 展示动态数据:

    ①数据的类型、名称是什么?

    ②数据保存在哪个组件?

  3. 交互——从绑定事件监听开始

整体思路

TodoList类似于我们手机里的待办事项或者备忘录

请添加图片描述

1、分析结构

确定组件名称TodolistHeader,TodolistList,TodolistItem,TodolistFooter(下文会简写成Header、List、Item、Footer)和个数,还有嵌套关系(TodolistList里面包含TodolistItem,TodolistList和TodolistHello\TodolistFooter为兄弟组件),然后引入相应的组件。

  • 一个命名问题:此处命名不直接用Header、Footer等简单的命名是因为这些命名本身在标签具有特殊的含义(类似于关键字),并且Vue推荐我们使用多单词命名。为了达到和Vue开发者工具里的名字一样,这里使用的“大驼峰”命名(在驼峰命名的基础上首字母大写)。

请添加图片描述

请添加图片描述

2、拆html和css

一般的项目是写好html和css的,我们要把他们拆到相应的组件里,可以先全部放到App.vue中,然后打开开发者工具,观察他们的结构,分别放到对应的组件里面,style标签中加上scoped属性(保证当前样式只在当前组件中使用,防止样式名字不能重复使用)

3、初始化列表

在List中定义一个数组todos存储每个item为对象,然后在List的标签中写<Item></Item>并用v-for遍历数组中的每个对象生成结构,且通过自定义属性todo把每个对象传给子组件Item

在Item中使用props配置项接收(实现父子组件通信),然后input框里的checked绑定todo.done(可以初始化页面)

props配置项不熟悉的可以点击此处复习props

4、实现添加列表功能

上一步我们是在List中定义了todos数组,而用户的输入是在Header中,也就是说我们要在Header中收集数据,然后传给List,但是兄弟组件如何通信?全局事件总线、消息订阅与发布、Vuex都可以,但是现在还没学。

之前我们学的props配置项,可以实现父组件给子组件传数据(父组件里写子组件标签并配置属性,子组件使用props接收),现在我们想实现兄弟组件HeaderList的通信,可以借助App这个共同的父亲。

(1)把List中的数据todos定义在App里,然后传给List一份(通过props接收,由于是直接传到vc上,模板不会报错)。
(2)在App组件中定义一个函数,函数里面写个参数

	addTodo(x) {
            //借助这个函数,拿到Header中用户输入的东西
            this.todos.unshift(x);
       }

(3)把这个函数传给HeaderHeaderprops接收一下,然后在Header中调用这个函数,把用户的输入传给这个函数

const todoObj = { id: nanoid(), title: this.title, done: false };
this.addTodo(todoObj);

(4)由于addTodo是定义在App上的,所以App就直接拿到了函数的参数,然后就可以直接添加在todos中,这样的话todos改变,模板重新解析,传给Listtodos也改变,List模板重新解析,v-for一遍历,页面就多了一个。

5、实现勾选功能

选中:done=true,不选中:done=false。思路:简单来说就是让App拿到要修改的数据的id,找到这个数据然后把done属性取反。

我们先在App组件里定义一个函数,用来接收当前操作对象的id,然后函数里的逻辑是找到这个id,然后done属性取反(记住,数据源在哪里,修改数据的方法就写在哪里

changeTodo(id) {
            this.todos.forEach((todo) => {
                if (todo.id === id) todo.done = !todo.done;
            })
        }

然后把changeTodo这个函数通过标签和props传给List,再传给Item
然后在Item组件里定义一个函数handleChange,用来获取当前操作的多选框的id

handleChange(id) {
            // 不能像下面这样直接修改props的数据,数据源在哪里,我们就去哪里改
            // 如下代码也能实现功能,但是不建议这么写,理由就是不能直接改props传来的东西
            // this.todo.done = !this.todo.done;   
            //不报错是因为,改的不是整个对象(对象的地址),地址没变就不会报错

            //通知App要修改的数据的id是哪个
            this.changeTodo(id);
        }

handleChange函数通过点击事件来触发,实参就是当前input节点的todo的id

<input type="checkbox" :checked="todo.done" @click="handleChange(todo.id)" />

当然,这个勾选功能不用这么绕来绕去也可以实现,比如我直接在handleChange

this.todo.done = !this.todo.done;   

又或者我用v-model,一行代码就搞定了,不用在App再定义函数,然后传来传去

<input type="checkbox" v-model="todo.done" />

但是不建议这么写,理由就是不能直接改props传来的东西,记住,数据源在哪里,修改数据的方法就配置在哪里,千万记住props是只读的,如果改它,就会改源数据,这样所有用到数据的组件都会受到影响。

6、实现删除功能

和上面的类似,也是需要传递函数,不能动props。
首先App定义一个删除函数

deleteTodo(id) {
            this.todos = this.todos.filter((todo) => {
                return todo.id !== id;
            })
            // this.todos = this.todos.filter(todo => todo.id !== id);
        }

把这个函数传给List,再传给Item
Item中的按钮来个点击事件

<button class="btn btn-danger" @click="handleDelete(todo.id)">删除</button>

把当前input的这个id传给App,调用App中的deleteTodo函数让App去操作

handleDelete(id) {
    if (confirm('确定要删除吗?'))  //点确定是true,取消是false
        this.deleteTodo(id);
}

7、实现底部统计功能

(1)App中的todos数据传给Footer一份
(2)全部比较简单,直接插值语法读数组todos的长度就行。已完成这里可以用计算属性

<span>已完成{{ doneTotal }}</span> / 全部{{ todos.length }}

(3)计算属性这里有多种实现方式:

写法1:forEach遍历

let count = 0;
this.todos.forEach(todo => {
    if (todo.done) count++;
});
return count;

写法2:for of遍历

let count = 0;
//for in 拿到的是数组的索引,for of才能拿到元素
for (let todo of this.todos) {
    if (todo.done === true)
        count++;
}
return count;

写法3:filter过滤

let count = this.todos.filter(todo => todo.done)
return count.length;

写法4:ES6的reduce

  • 对reduce不熟悉的可以点击此处复习reduce(点击目录里的数组核心方法即可)
const count = this.todos.reduce((pre, todo) => {
    return pre + (todo.done ? 1 : 0)
}, 0);
return count;
//return this.todos.reduce((pre, todo) => pre + (todo.done ? 1 : 0), 0);

8、实现全选框的交互

(1)每个todo控制全选框

当已完成和全部相等且不等于0时,勾选全选框,写在计算属性中

<input type="checkbox" :checked="isAll" " />
isAll(){
  return this.total === this.doneTotal && this.total !== 0;
  }

如果全部是0个,就隐藏Footer(用v-show实现)

(2)全选框控制todo全选或者取消全选:使用点击事件实现。

App中定义一个函数,用来接收Footer中全选框的状态值,然后把每个数据的done值都改成和全选框的状态值一样(选择or不选择)

checkAllTodos(isDone) {
            this.todos.forEach(todo => todo.done = isDone);
        },

Footer的全选框中,加入点击事件并定义一个函数

<input type="checkbox" :checked="isAll" @click="handleCheckAll" />

在函数中调用App中的函数,把状态传过去

handleCheckAll(e) {
            // this.checkAllTodos(!this.isAll);  
            this.checkAllTodos(e.target.checked);  //直接拿dom的值比较合适
        },

(3)全选框控制todo全选或者取消全选:使用v-model实现。

第一步一样,在App中定义一个函数,用来接收Footer中全选框的状态值,然后把每个数据的done值都改成和全选框的状态值一样(选择or不选择)

checkAllTodos(isDone) {
            this.todos.forEach(todo => todo.done = isDone);
        },

在Footer的全选框中,加入v-model(没有value绑定的是checked)绑定isAll计算属性

<input type="checkbox" v-model="isAll" />

isAll中加入setter,把每个更新的值传给App中的函数。这样就不用再另外定义methods了,只用计算属性就能搞定:item影响全选框(getter读isAll)全选框影响item(setter改isAll)两种情况

isAll: {
            get() {
                return this.total === this.doneTotal && this.total !== 0;
            },
            set(val) {
                this.checkAllTodos(val);
            }
        },

9、点击右下角按钮删除全部已完成任务

App中定义一个方法并传给Footer

//5.删除已完成任务
clearAllTodo() {
      this.todos = this.todos.filter((todo) => {
        return !todo.done
      })
    },

Footer中调用这个方法

<button class="btn btn-danger" @click="clearAll">清除已完成任务</button>
clearAll() {
      this.clearAllTodo()//点击调用App里边的方法,把所有true删掉
    },

案例完整代码展示

1、App.vue

<template>
  <div id="root">
    <div class="todo-container">
      <div class="todo-wrap">
        <TodolistHeader :addTodo="addTodo" />
        <TodolistList
          :todos="todos"
          :changeTodo="changeTodo"
          :deleteTodo="deleteTodo"
        />
        <TodolistFooter
          :todos="todos"
          :checkAllTodo="checkAllTodo"
          :clearAllTodo="clearAllTodo"
        />
      </div>
    </div>
  </div>
</template>

<script>
import TodolistHeader from './components/TodolistHeader.vue'
import TodolistFooter from './components/TodolistFooter.vue'
import TodolistList from './components/TodolistList.vue'
export default {
  name: 'App',
  components: { TodolistHeader, TodolistFooter, TodolistList },
  data() {
    return {
      todos: [
        //通过App把todos传给List
        //id不用数值是因为数值是有尽头的,而字符串没有尽头
        { id: '001', title: '吃饭', done: true },
        { id: '002', title: '睡觉', done: true },
        { id: '003', title: '打豆豆', done: true },
      ],
    }
  },
  //记住,数据源在哪里,修改数据的方法就配置在哪里
  //最好不要在任何子组件中修改父组件的数据
  methods: {
    //1.添加一个todo
    addTodo(todoObj) {
      //借助这个函数,拿到Header中用户输入的东西
      this.todos.unshift(todoObj)
    },
    //2.勾选or取消勾选一个todo
    changeTodo(id) {
      this.todos.forEach((todo) => {
        if (todo.id === id) todo.done = !todo.done
      })
    },
    //3.删除一个todo
    deleteTodo(id) {
      this.todos = this.todos.filter((todo) => {
        return todo.id !== id
      })
    },
    //4.全选or取消全选,其他子框同步
    checkAllTodo(done) {
      this.todos.forEach((todo) => {
        todo.done = done
      })
    },
    //5.删除已完成任务
    clearAllTodo() {
      this.todos = this.todos.filter((todo) => {
        return !todo.done
      })
    },
  },
}
</script>

<style>
/*base*/
body {
  background: #fff;
}

.btn {
  display: inline-block;
  padding: 4px 12px;
  margin-bottom: 0;
  font-size: 14px;
  line-height: 20px;
  text-align: center;
  vertical-align: middle;
  cursor: pointer;
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.2),
    0 1px 2px rgba(0, 0, 0, 0.05);
  border-radius: 4px;
}

.btn-danger {
  color: #fff;
  background-color: #da4f49;
  border: 1px solid #bd362f;
}

.btn-danger:hover {
  color: #fff;
  background-color: #bd362f;
}

.btn:focus {
  outline: none;
}

.todo-container {
  width: 600px;
  margin: 0 auto;
}
.todo-container .todo-wrap {
  padding: 10px;
  border: 1px solid #ddd;
  border-radius: 5px;
}
</style>

2、TodolistHeader.vue

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

<script>
import { nanoid } from 'nanoid'
export default {
  name: 'TodolistHeader',
  data() {
    return {
      title: '',
    }
  },
  props: ['addTodo'],
  methods: {
    // 输入内容按回车添加一个事件
    add() {
      //1.校验数据
      if (!this.title.trim()) return alert('输入不能为空')
      //2.将用户的输入包装成一个todo对象
      const todoObj = { id: nanoid(), title: this.title, done: false }
      //3.借助App里的函数,把用户的输入从Header传给App里面的todos 然后再通过App把todos传给List,用这种捷径(借助App)就巧妙地实现了Header和List的兄弟组件通信
      this.addTodo(todoObj)
      this.title = '' //4.输入完回车输入框变为空
    },
  },
}
</script>

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

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

3、TodolistList.vue

<template>
  <ul class="todo-main">
    <TodolistItem
      v-for="todoObj in todos"
      :key="todoObj.id"
      :todo="todoObj"
      :changeTodo="changeTodo"
      :deleteTodo="deleteTodo"
    />
  </ul>
</template>

<script>
import TodolistItem from './TodolistItem.vue'
export default {
  name: 'TodolistList',
  components: { TodolistItem },
  props: ['todos', 'changeTodo', 'deleteTodo'],
}
</script>

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

.todo-empty {
  height: 40px;
  line-height: 40px;
  border: 1px solid #ddd;
  border-radius: 2px;
  padding-left: 5px;
  margin-top: 10px;
}
</style>

4、TodolistItem.vue

<template>
  <li>
    <label>
      <input
        type="checkbox"
        :checked="todo.done"
        @change="handleChange(todo.id)"
      />
      <!-- 如下代码也能实现功能,但是不建议这么写,理由就是不能直接改props传来的东西 -->
      <!-- <input type="checkbox" v-model="todo.done" /> -->
      <span>{{ todo.title }}</span>
    </label>
    <button class="btn btn-danger" @click="handleDelete(todo.id)">删除</button>
  </li>
</template>

<script>
export default {
  name: 'TodolistItem',
  //声明接收todo对象
  props: ['todo', 'changeTodo', 'deleteTodo'],
  methods: {
    handleChange(id) {
      // 不能像下面这样直接修改props的数据,数据源在哪里,我们就去哪里改
      // 如下代码也能实现功能,但是不建议这么写,理由就是不能直接改props传来的东西
      // this.todo.done = !this.todo.done;
      //不报错是因为,改的不是整个对象(对象的地址),地址没变就不会报错

      //通知App要修改的数据的id是哪个
      this.changeTodo(id)
    },
    handleDelete(id) {
      //confirm点确定是true,取消是false
      if (confirm('确定删除这个事项吗?')) this.deleteTodo(id)
    },
  },
}
</script>

<style scoped>
/*item*/
li {
  list-style: none;
  height: 36px;
  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: -1px;
}

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

li:before {
  content: initial;
}

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

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

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

5、TodolistFooter.vue

<template>
  <!-- 这里total如果显示是0(false)就隐藏(v-show)-->
  <div class="todo-footer" v-show="total">
    <label>
      <input type="checkbox" :checked="isAll" @change="checkAll" />
    </label>
    <span>
      <span>已完成{{ doneTotal }}</span> / 全部{{ total }}
    </span>
    <button class="btn btn-danger" @click="clearAll">清除已完成任务</button>
  </div>
</template>

<script>
export default {
  name: 'TodolistFooter',
  props: ['todos', 'checkAllTodo', 'clearAllTodo'],
  computed: {
    total() {
      return this.todos.length
    },
    doneTotal() {
      return this.todos.reduce(
        (pre, current) => pre + (current.done ? 1 : 0),
        0
      )
    },
    isAll() {
      return this.doneTotal === this.total && this.total > 0
    },
  },
  methods: {
    checkAll(e) {
      this.checkAllTodo(e.target.checked)
    },
    clearAll() {
      this.clearAllTodo() //点击调用App里边的方法,把所有为true的删掉
    },
  },
}
</script>

<style scoped>
/*footer*/
.todo-footer {
  height: 40px;
  line-height: 40px;
  padding-left: 6px;
  margin-top: 5px;
}

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

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

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

总结

1.组件化编码流程:
(1)拆分静态组件:组件要按照功能点拆分,命名不要与html元素冲突。
(2)实现动态组件:考虑好数据的存放位置,数据是一个组件在用,还是一些组件在用:

  • 一个组件在用:放在组件自身即可。
  • 一些组件在用:放在他们共同的父组件上(状态提升)。

(3)实现交互:从绑定事件开始。

2.props适用于:
(1).父组件 ==> 子组件 通信
(2).子组件 ==> 父组件 通信(要求父先给子一个函数)

3.使用v-model时要切记
v-model绑定的值不能是props传过来的值,因为props是不可以修改的!

4.关于props
props传过来的若是对象类型的值,修改对象中的属性时Vue不会报错,但不推荐这样做。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/895778.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

前端:运用html+css+jquery.js实现截图游戏

前端:运用htmlcssjquery.js实现截图游戏 1. 前言2. 实现原理3. 参考代码和运行结果 1. 前言 最近在刷手机视频时&#xff0c;总是能刷到一个这样的视频&#xff0c;视频上是一个截图游戏&#xff0c;当图片上的某个片段正好在图片的正确位置时&#xff0c;暂停视频&#xff0c;…

C++ 面向对象三大特性——多态

✅<1>主页&#xff1a;我的代码爱吃辣 &#x1f4c3;<2>知识讲解&#xff1a;C 继承 ☂️<3>开发环境&#xff1a;Visual Studio 2022 &#x1f4ac;<4>前言&#xff1a;面向对象三大特性的&#xff0c;封装&#xff0c;继承&#xff0c;多态&#xff…

最强自动化测试框架Playwright(34)CDPSession

在 Playwright 中&#xff0c;CDPSession 类是用于与浏览器的 Chrome DevTools Protocol (CDP) 会话进行交互的对象。CDP 是与Chromium浏览器通信的底层协议&#xff0c;它提供了许多与浏览器进行交互和控制的功能。 CDPSession 类提供了执行底层 CDP 命令的方法&#xff0c;并…

设计模式之适配器模式(Adapter)的C++实现

1、适配器模式的提出 在软件功能开发中&#xff0c;由于使用环境的改变&#xff0c;之前一些类的旧接口放在新环境的功能模块中不再适用。如何使旧接口能适用于新的环境&#xff1f;适配器可以解决此类问题。适配器模式&#xff1a;通过增加一个适配器类&#xff0c;在适配器接…

Flink安装与使用

1.安装准备工作 下载flink Apache Flink: 下载 解压 [dodahost166 bigdata]$ tar -zxvf flink-1.12.0-bin-scala_2.11.tgz 2.Flinnk的standalone模式安装 2.1修改配置文件并启动 修改&#xff0c;好像使用默认的就可以了 [dodahost166 conf]$ more flink-conf.yaml 启动 …

角色入门02----动画蓝图

使用UE4的小白人动画&#xff0c;首先将它动画资产重定向。先ue4转ue5小银人&#xff0c;在把转换后的动画ue5转ue4给这个低模人物就动画就不会很鬼畜。 进入动画创建混合空间1D,这相当于可以组合很多动画 在跑步的混合空间里设置横坐标为Speed&#xff0c;最大值为400&#xf…

DataWhale 机器学习夏令营第三期

DataWhale 机器学习夏令营第二期 学习记录一 (2023.08.18)1.赛题理解2.缺失值分析3. 简单特征提取4. 数据可视化离散变量离散变量分布分析 DataWhale 机器学习夏令营第三期 ——用户新增预测挑战赛 学习记录一 (2023.08.18) 已跑通baseline&#xff0c;换为lightgbm基线&#…

Springboot 实践(8)springboot集成Oauth2.0授权包,对接spring security接口

此文之前&#xff0c;项目已经添加了数据库DAO服务接口、资源访问目录、以及数据访问的html页面&#xff0c;同时项目集成了spring security&#xff0c;并替换了登录授权页面&#xff1b;但是&#xff0c;系统用户存储代码之中&#xff0c;而且只注册了admin和user两个用户。在…

记一次项目内存优化--内存泄漏

需求–内存泄漏优化&#xff0c;PSS有所下降&#xff0c; OOM率减少 主要是与某个版本作基准进行对比&#xff08;一般是最新版本的前一个版本作原数据&#xff09;&#xff0c;优化后&#xff0c;PSS有所下降&#xff0c;线上OOM率减少&#xff08;Bugly版本对比&#xff09;…

网工内推 | 数通工程师,有运营商工作经验优先

01 国育产教融合教育科技&#xff08;海南&#xff09;有限公司 招聘岗位&#xff1a;通信工程师 职责描述&#xff1a; 1、负责锐捷4/5G皮基站产品的工程交付工作&#xff0c;包括现场勘测、硬件督导、开通调测、测试优化等技术交付工作&#xff1b; 2、负责锐捷4/5G皮基站网…

【探索Linux】—— 强大的命令行工具 P.5(yum工具、git 命令行提交代码)

阅读导航 前言一、软件包管理器 yum1.yum的概念yum的基本指令使用例子 二、git 命令行提交代码总结温馨提示 前言 前面我们讲了C语言的基础知识&#xff0c;也了解了一些数据结构&#xff0c;并且讲了有关C的一些知识&#xff0c;也学习了一些Linux的基本操作&#xff0c;也了…

I2S/PCM board-level 约束及同步(latencyskewbitsync)

I2S/PCM是典型的低速串口&#xff0c;在两个方向上分别有两组信号&#xff0c;我们已soc为视角分为soc-adif和外设audio-codec。 那么adif输入&#xff1a; sclk_i, ws_i, sdi 当然并不是三个输入信号同时有效&#xff0c;只有adif RX slave时&#xff0c;三个输入都会有效…

贷款公司精准获客,快速找到目标客户,直击获客高点!

目前&#xff0c;运营商的大数据技术正在逐步发展壮大&#xff0c;并已广泛应用于各个行业。运营商大数据市场有待发展的潜在行业发展趋势难以预料&#xff0c;整体能源规模达数万亿元。运营商大数据与三家网络运营商进行了深度战略合作&#xff0c;利用移动电信运营商的大数据…

使用coloc 进行 QTL 共定位Colocalization

GWAS找到显著信号位点后&#xff0c;需要解释显著信号位点如何影响表型。 常见的一个解释方法是共定位分析。 主流的共定位分析包括&#xff1a; 1&#xff09;GWAS和eQTL共定位&#xff1b; 2&#xff09;GWAS和sQTL共定位&#xff1b; 3&#xff09;GWAS和meQTL共定位&am…

上一个说软件测试简单的,已经被面试官问emo了···

现在已经过了 ”不会但我会学“ 就能感动面试官的时代&#xff0c;随着供需关系的变化&#xff0c;不论是对于面试官还是面试者&#xff0c;面试的成本越来越高。为了筛选到更优秀的程序员&#xff0c;面试官们可谓是绞尽了脑汁&#xff0c;”面试造火箭&#xff0c;工作拧螺丝…

PS丢失d3dcompiler_47.dll文件怎么办(附详细修复方法)

我们在安装PS等软件的时候&#xff0c;有可能安装完之后出现以下问题&#xff08;特别是win10或者win11系统&#xff09; 错误&#xff1a; 打开PS的时候出现这个错误&#xff1a;无法启动此程序&#xff0c;因为计算机中丢失D3DCOMPILER_47.dll。尝试重新安装该程序以解决此问…

03-微信小程序常用组件-视图容器组件

微信小程序组件-视图容器 文章目录 视图容器view 视图容器案例代码 swiper 滑块视图容器案例代码indicator-color 微信小程序包含了六大组件&#xff1a; 视图容器、 基础内容、 导航、 表单、 互动和 导航。这些组件可以通过WXML和WXSS进行布局和样式设置&#xff0c;从…

CFD特性FPmarkets澳福认为了解这11种足够了

CFD在交易中很重要&#xff0c;但CFD特性很多投资者不了解&#xff0c;FPmarkets澳福认为了解这11种足够了&#xff1a; 1. 投资者通过标的资产价格价值的变化获利&#xff0c;而不拥有标的资产。 2. 差价合约交易没有固定的到期日。 3. 与期货交易类似&#xff0c;差价合约交易…

海外问卷脚本机器人哪里哪里有?是真的吗?

大家好&#xff0c;我是橙河老师&#xff0c;今天讲一讲海外问卷项目能不能用脚本操作&#xff1f; 最近没怎么写文章&#xff0c;确实比较忙。我本人每天至少要面对5-10个客户咨询项目&#xff0c;每隔一段时间&#xff0c;都会有人问我&#xff1a;操作海外问卷有没有脚本&a…

文字点选验证码识别(上)-YOLO位置识别

声明 本文以教学为基准、本文提供的可操作性不得用于任何商业用途和违法违规场景。 本人对任何原因在使用本人中提供的代码和策略时可能对用户自己或他人造成的任何形式的损失和伤害不承担责任。 如有侵权,请联系我进行删除。 文章中没有代码,只有过程思路,请大家谨慎订阅。…