前端vue入门(纯代码)07

news/2024/10/29 7:26:55/

07.TodoList案例

在这里插入图片描述

1 拆分组件

一共拆分为4个组件:【因为header和HTML内置的标签<header>重名,故在之前都加了Todo】

  • TodoHeader
  • TodoItem【item是list的子组件】
  • TodoList
  • TodoFooter
2 组件化编码流程
  1. 实现静态组件:抽取组件,只考虑结构和样式,先拆结构再拆样式。

整个TodoList案例的页面结构【html】和样式设置【style】:

TodoList.html文件【还未实现动态交互】

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title><style>body {background: #fff;}.todo-container {width: 600px;/* 上下外边距为0,左右自动,实际效果为左右居中*/margin: 0 auto;}/* 后代选择器(包含选择器),选择到的是todo-container下面的所有后代todo-wrap  */.todo-container .todo-wrap {padding: 10px;border: 1px solid #67dbd1;border-radius: 5px;}/* 头部样式设置 *//* 后代选择器(包含选择器),选择到的是todo-header下面的所有后代input */.todo-header input {width: 560px;height: 28px;font-size: 14px;border: 1px solid #ccc;border-radius: 4px;/* 内边距:上下4px,左右7px */padding: 4px 7px;}/* :focus获得焦点,并设置其新样式:例如:用户单击一个input输入框获取焦点,然后这个input输入框的边框样式就会发生改变,和其他的输入框区别开来,表明已被选中。 */.todo-header input:focus {/* outline 与 border 相似,不同之处在于 outline 在整个元素周围画了一条线;它不能像 border 那样,指定在元素的一个面上设置轮廓,也就是不能单独设置顶部轮廓、右侧轮廓、底部轮廓或左侧轮廓。 */outline: none;/* 定义边框的颜色 */border-color: rgba(82, 168, 236, 0.8);/* boxShadow 属性把一个或多个下拉阴影添加到框上 *//* 设置inset:内部阴影,不设置inset:外部阴影 *//* 【0 0】:不设置X轴与Y轴偏移量 *//* 第三个值【如10px,8px】:设置值阴影模糊半径为15px */box-shadow: inset 0 0 10px rgba(124, 56, 207, 0.075), 0 0 8px rgba(224, 58, 17, 0.6);background-color: bisque;}/*main*/.todo-main {/* 左外边距:0px 【盒子贴着盒子】*/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;}/*item*/li {/* ul无序列表 ol有序列表*//* 列表前面无标记 */list-style: none;/* height定义了一个li盒子的高度 */height: 36px;/* 行高:指的是文字占有的实际高度 */line-height: 36px;/* 当height和line-height相等时,即盒子的高度和行高一样,内容上下居中 */padding: 0 5px;/* 边框底部:1px的实心线 颜色*/border-bottom: 1px solid #c0abc3;}/* 后代选择器(包含选择器),选择到的是li下面的所有后代label */li label {/* 左对齐浮动【元素一旦浮动就会脱离文档流(不占位,漂浮)】 */float: left;/* 鼠标放在label元素上时变成小小手 */cursor: pointer;}li label input {/* 垂直居中 */vertical-align: middle;margin-right: 6px;position: relative;top: -1px;}/* 后代选择器(包含选择器),选择到的是li下面的所有后代button */li button {/* 向右浮动 */float: right;/* 不为被隐藏的对象保留其物理空间,即该对象在页面上彻底消失,通俗来说就是看不见也摸不到。 */display: none;/* 上边距为3px */margin-top: 3px;}li:before {/* initial:它将属性设置为其默认值。 */content: initial;}/* 结构伪类选择器 选择最后一个li元素 */ li:last-child {/* 边框底部没有线 */border-bottom: none;}li:hover{background-color: #ddd;}/* 鼠标移动到该元素上时,将button按钮显示出来 */li:hover button{/*  display:block将元素显示为块级元素 */display: block;}/* 尾部 */.todo-footer {height: 40px;line-height: 40px;padding-left: 6px;margin-top: 5px;}/* 后代选择器:todo-footer里所有的label元素 */.todo-footer label {/* inline元素不会独占一行,多个相邻的行内元素会排列在同一行里,直到一行排列不下,才会新换一行,其宽度随元素的内容而变化 *//* inline-block 的元素既具有 block 元素可以设置宽高的特性,同时又具有 inline 元素默认不换行的特性 */display: inline-block;margin-right: 20px;cursor: pointer;}.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-footer label input {position: relative;top: -1px;vertical-align: middle;margin-right: 5px;}.todo-footer button {float: right;margin-top: 5px;}</style>
</head><body><div id="root"><div class="todo-container"><div class="todo-wrap"><!-- 头部 --><div class="todo-header"><input type="text" placeholder="请输入你的任务名称,按回车键确认"/></div><ul class="todo-main"><li><label><input type="checkbox"/><span>练功夫</span></label><button class="btn btn-danger">删除</button></li><li><label><input type="checkbox"/><span>睡觉</span></label><button class="btn btn-danger">删除</button></li>          <li><label><input type="checkbox"/><span>打豆豆</span></label><button class="btn btn-danger">删除</button></li></ul><!-- 尾部 --><div class="todo-footer"><label><input type="checkbox"/></label><span><span>已完成:0</span> / 全部:3</span><button class="btn btn-danger">清除已完成任务</button></div></div></div></div>
</body></html>

静态页面展示:

在这里插入图片描述

  1. 展示动态数据

前期知识准备:

  • <input type="checkbox" :checked="false"/> 【false:input框不勾选】

  • <input type="checkbox" :checked="true"/>【true:input框勾选】

  • <input type="text" @keyup.enter="add"/>【键盘按键事件:按下回车按键,调用add()方法】

  • event.target是会返回触发事件触发的源头元素。【这个源头元素指的是,当我点击子元素,虽然父元素的点击事件也会被触发(冒泡机制),但子元素才是事件的源头元素。】

<input type="text" placeholder="请输入你的任务名称,按回车键确认" @keyup.enter="add"/>
export default {methods: {add(e){console.log(e.target.value);//e.target拿到的是事件触发的源头input元素节点//e.target.value:拿到input框里输入的数据}},
};
  • v-model:收集的就是输入框里的value值

  • 生成全球唯一的ID:uuid

  • nanoid【是uuid的精简版】:安装指令----npm i nanoid

  • 问题一: 把数据添加到list中,由于obj数据是在list中,添加的数据在myHeader中,属于兄弟关系,所以要做调整:把list的数据交给APP,myHeader添加的数据交给APP即可

  • 补充:data,props,methods,computed里面的数据都可以在vc或者vm上访问到。

  • trim() 方法:用于删除字符串的头尾空白符,空白符包括:空格、制表符 tab、换行符等其他空白符等

  • 给勾选框添加一个@change事件,只要勾选状态发生改变,就会调用函数【带参数】handleCheck(todo.id),并给该回调函数传了一个参数todo.id,即勾选状态发生改变的勾选框的ID

<input type="checkbox"  @change="handleCheck(todo.id)"/>
  • 注意:props中:父给子组件传数据【非函数】;子组件给父组件传递数据【必须是函数、方法】

  • 注意:props是只读的,vue底层会检测你对props的修改,如果进行了修改,控制台会报错,必须修改,就复制一份到data中,通过data去修改数据。

  • confirm()函数用于提供确认功能,它首先显示给定的message参数所包含的信息,并提供两个可选择的回答“ok”和“cancel”,然后等待用户选择其中的一个。如果用户选择“ok”则返回true;否则,如若选择“cancel”则返回false。

  • @ 是 v-on: 的简写形式

  • filter()方法的使用:返回数组,包含了符合条件的所有元素。如果没有符合条件的元素则返回空数组

  • computed与methods实现相比,内部有缓存机制(复用),效率更高,调试方便

  • computed计算属性【比如:A】:第一次读取A属性时,就调用了getter,第2,3,4次读取A,就不会调用getter了

  • js中和数组有关的一个计数方法:reduce()

    reduce(A,B) 方法会遍历数组的每一项,他接收两个参数:

    • 第一个参数A:每次遍历都会调用的函数,而这个函数有接收四个参数,分别是:前一个值、当前项、项目的索引和数组对象,而这个函数的返回值,回传给下一次遍历时,执行的这个方法的第一个参数。
    • 第二个参数B:归并基础的初始值
data:{todos:[{id:'001',title:'练功夫',done:true},{id:'002',title:'睡觉',done:false},{id:'003',title:'打豆豆',done:true}],
},
computed:{
doneTotal(){//此处使用reduce方法做条件统计const x = this.todos.reduce(// todo:遍历数组todos中的每一个元素// 比如:数组遍历时,把数组todos中的每一个元素分别赋值给todo【包含id='001'】(pre,todo)=>{console.log('@',pre,todo)return pre + (todo.done ? 1 : 0)},0)//这个0:统计的初始值==》reduce(第一个参数,第二个参数:0)return x},
}
//简写
doneTotal(){return this.todos.reduce((pre,todo)=>pre + (todo.done ? 1 : 0),0)
}
  • Array.forEach():forEach到底会不会改变原数组Array?

  • 总结:

  1. 组件化编码流程:

    ​ (1).拆分静态组件:组件要按照功能点拆分,命名不要与html元素冲突。

    ​ (2).实现动态组件:考虑好数据的存放位置,数据是一个组件在用,还是一些组件在用:

    ​ 1).一个组件在用:放在组件自身即可。

    ​ 2). 一些组件在用:放在他们共同的父组件上(状态提升)。

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

  2. props适用于:

    ​ (1).父组件 ==> 子组件 通信

    ​ (2).子组件 ==> 父组件 通信(要求父先给子一个函数)

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

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

App.vue文件

<template><div id="root"><div class="todo-container"><div class="todo-wrap"><!-- 给每个组件添加多个不同的交互方法 --><!-- 把App组件里的方法addTodo()传给TodoHeader组件【也需要用props去接受】 --><TodoHeader :addTodo="addTodo"/><TodoList :todos="todos":checkTodo="checkTodo":deleteTodo="deleteTodo"/><TodoFooter:todos="todos":checkAllTodo="checkAllTodo":clearAllTodo="clearAllTodo"/></div></div></div>
</template><script>
//引入App的子组件
import TodoHeader from './components/TodoHeader'
import TodoFooter from './components/TodoFooter'
import TodoList from './components/TodoList'export default {name:'App',components: { TodoHeader,TodoFooter,TodoList },data() {return {//由于todos是TodoHeader组件和TodoFooter组件都在使用,所以放在App中(状态提升)todos:[{id:'001',title:'练功夫',done:true},{id:'002',title:'睡觉',done:false},{id:'003',title:'打豆豆',done:true}],}},methods: {//添加一个todoaddTodo(todoObj){// 在数组的开头添加一个数据this.todos.unshift(todoObj)},//勾选or取消勾选一个todocheckTodo(id){this.todos.forEach((todo) => {if(todo.id === id) todo.done = !todo.done})},// 删除一个todo// deleteTodo里面的id指的是:点击事件对应的iddeleteTodo(id){// todo:this.todos这个数组的每一个元素this.todos=this.todos.filter((todo)=>{return todo.id != id})},//全选or取消全选checkAllTodo(done){this.todos.forEach(todo => todo.done = done)},// 清除所有已经完成的todoclearAllTodo(){this.todos= this.todos.filter(todo =>{return todo.done == false// 或者换成 return !todo.done})},},}
</script><!-- style没有scoped属性:【全局样式】 -->
<!-- style有scoped属性:样式设置只在本组件里起作用【局部样式】 -->
<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;/* 上下外边距为0,左右自动,实际效果为左右居中*/margin: 0 auto;}/* 后代选择器(包含选择器),选择到的是todo-container下面的所有后代todo-wrap  */.todo-container .todo-wrap {padding: 10px;border: 1px solid #67dbd1;border-radius: 5px;}
</style>

TodoHeader.vue文件

<template><div class="todo-header"><!-- @keyup.enter="add" :按下回车按键,调用add方法 --><input type="text" placeholder="请输入你的任务名称,按回车键确认" @keyup.enter="add" v-model="title"/></div>
</template><script>
// 引入nanoid库生成ID号
import { nanoid } from 'nanoid'
export default {name: 'TodoHeader',//接收从App组件【父组件】传递过来的addTodo方法props:['addTodo'],data() {return {title: '',}},methods: {add(){// 如果输入框里为空,就跳过下面的代码,并弹窗if (!this.title.trim()) return alert('请输入值')//将用户的输入包装成一个todo对象const todoObj={id:nanoid(),title:this.title,done:false}//通知App组件去添加一个todo对象this.addTodo(todoObj)//清空输入this.title = ''}},
};
</script><style scoped>/* 头部样式设置 *//* 后代选择器(包含选择器),选择到的是todo-header下面的所有后代input */.todo-header input {width: 560px;height: 28px;font-size: 14px;border: 1px solid #ccc;border-radius: 4px;/* 内边距:上下4px,左右7px */padding: 4px 7px;}/* :focus获得焦点,并设置其新样式:例如:用户单击一个input输入框获取焦点,然后这个input输入框的边框样式就会发生改变,和其他的输入框区别开来,表明已被选中。 */.todo-header input:focus {/* outline 与 border 相似,不同之处在于 outline 在整个元素周围画了一条线;它不能像 border 那样,指定在元素的一个面上设置轮廓,也就是不能单独设置顶部轮廓、右侧轮廓、底部轮廓或左侧轮廓。 */outline: none;/* 定义边框的颜色 */border-color: rgba(82, 168, 236, 0.8);/* boxShadow 属性把一个或多个下拉阴影添加到框上 *//* 设置inset:内部阴影,不设置inset:外部阴影 *//* 【0 0】:不设置X轴与Y轴偏移量 *//* 第三个值【如10px,8px】:设置值阴影模糊半径为15px */box-shadow: inset 0 0 10px rgba(124, 56, 207, 0.075), 0 0 8px rgba(224, 58, 17, 0.6);background-color: bisque;}
</style>

TodoList.vue

<template><ul class="todo-main"><TodoItem v-for="todoObj in todos" :key="todoObj.id" :todo="todoObj":checkTodo="checkTodo":deleteTodo="deleteTodo"/></ul>
</template><script>
import TodoItem from './TodoItem'
export default {name: 'TodoList',components:{TodoItem},//声明接收App传递过来的数据,其中todos是自己用的,checkTodo和deleteTodo是给子组件TodoItem用的props: ['todos','checkTodo','deleteTodo']
};
</script><style scoped>/*main*/.todo-main {/* 左外边距:0px 【盒子贴着盒子】*/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>

TodoItem.vue

<template><li><label><input type="checkbox" :checked="todo.done"@change="handleCheck(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: 'TodoItem',// 声明接受从别的组件中的todoObj对象,todo、checkTodo、deleteTodoprops: ['todo','checkTodo','deleteTodo'],methods: {//勾选or取消勾选【别弄混了:这里的id其实就是上面change事件中的todo.id】handleCheck(id){//change事件触发后,通知App组件将对应的todo对象的done值取反this.checkTodo(id)},//删除handleDelete(id){if (confirm('Are you sure you want to delete?')) {//点击事件触发后通知App组件将对应的todo对象删除this.deleteTodo(id)}}},
};
</script><style scoped>/*item*/li {/* ul无序列表 ol有序列表*//* 列表前面无标记 */list-style: none;/* height定义了一个li盒子的高度 */height: 36px;/* 行高:指的是文字占有的实际高度 */line-height: 36px;/* 当height和line-height相等时,即盒子的高度和行高一样,内容上下居中 */padding: 0 5px;/* 边框底部:1px的实心线 颜色*/border-bottom: 1px solid #c0abc3;}/* 后代选择器(包含选择器),选择到的是li下面的所有后代label */li label {/* 左对齐浮动【元素一旦浮动就会脱离文档流(不占位,漂浮)】 */float: left;/* 鼠标放在label元素上时变成小小手 */cursor: pointer;}li label input {/* 垂直居中 */vertical-align: middle;margin-right: 6px;position: relative;top: -1px;}/* 后代选择器(包含选择器),选择到的是li下面的所有后代button */li button {/* 向右浮动 */float: right;/* 不为被隐藏的对象保留其物理空间,即该对象在页面上彻底消失,通俗来说就是看不见也摸不到。 */display: none;/* 上边距为3px */margin-top: 3px;}li:before {/* initial:它将属性设置为其默认值。 */content: initial;}/* 结构伪类选择器 选择最后一个li元素 */ li:last-child {/* 边框底部没有线 */border-bottom: none;}li:hover{background-color: #ddd;}/* 鼠标移动到该元素上时,将button按钮显示出来 */li:hover button{/*  display:block将元素显示为块级元素 */display: block;}
</style>

TodoFooter.vue

<template><div class="todo-footer" v-show="total"><label><!-- <input type="checkbox" :checked="isAll" @change="checkAll"/> 可以用下面这行代码代替--><!--对于type="checkbox",v-model绑定的就是一个布尔值,isAll为false or true  --><input type="checkbox" v-model="isAll"/></label><span><span>已完成{{ doneTotal }}</span> / 全部{{ total }}</span><button class="btn btn-danger" @click="clearAllDone">清除已完成任务</button></div>
</template><script>
export default {name: 'TodoFooter',props: ['todos','checkAllTodo','clearAllTodo'],computed:{//总数total(){return this.todos.length},// 已完成数doneTotal(){//此处使用reduce方法做条件统计/* return this.todos.reduce(// todo:遍历数组todos中的每一个元素// 比如:数组遍历时,把数组todos中的每一个元素分别赋值给todo【包含id='001'】(pre,todo)=>{// console.log('@',pre,todo)return pre + (todo.done ? 1 : 0)},0) *///简写return this.todos.reduce((pre,todo)=>pre + (todo.done ? 1 : 0),0)},//控制全选框/*    isAll(){//计算属性简写:isAll属性,只能被读取,不能被修改return this.total === this.doneTotal && this.total>0} */isAll:{//get有什么作用?当有人读取isAll时,get就会被调用,且返回值就作为isAll的值//get什么时候调用?1.初次读取isAll时。2.所依赖的数据发生变化时。get(){//全选框是否勾选  【&&:且】return this.total === this.doneTotal && this.total>0},//set什么时候调用? 当isAll被修改时。// value就是:v-model绑定的值false【未勾选】 or true【勾选】set(value){console.log(value)this.checkAllTodo(value)}},},methods: {
/*     checkAll(e){console.log(e.target.checked);// 拿到的是全选或者全不选的布尔值this.checkAllTodo(e.target.checked)} */// 清空所有已完成clearAllDone(){this.clearAllTodo()}},
};
</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>

http://www.ppmy.cn/news/383086.html

相关文章

2010最新网络语言

⒈别以为你长着一张西门庆的脸&#xff0c;就可以追求姐&#xff0c;姐不是潘金莲。 ⒉你知道男人这一生最痛苦的事情是什么吗&#xff1f;“是没媳妇”。&#xff1b;那你知道男人更痛苦的事情是什么吗&#xff1f;“有媳妇&#xff0c;跟别人跑了”。 ⒊本人待售&#xff1…

QQ游戏外挂

之前改过一个QQ找茬和QQ连连看的辅助&#xff0c;原来的程序比较笨&#xff0c;要用鼠标点了才能激活&#xff0c;我就改成快捷键激活了&#xff0c;还把界面改了&#xff0c;总算是能用。 看了QQ找茬的源代码&#xff0c;发现是对显示屏上的像素点进行分析&#xff0c;也就上…

【外挂编程】外挂编程技术揭秘(一)

引言&#xff1a; 本人并不是这方面专业的人员&#xff0c;我是一名PHP/Golang工程师。写这个主题&#xff0c;源自于我的“初心”。在最初我没有接触技术的时候&#xff0c;那会我是个网虫&#xff0c;刚开始也学习一些黑客相关的知识&#xff0c;当用到一些工具时&#…

用python做了一个 qq炫舞 机器人

2个晚上的时间&#xff0c;累计大约有6个多小时吧&#xff0c;用 python 实现了一个 qq炫舞 的机器人。 qq炫舞这个游戏就是很多年前比较流行的&#xff0c;出现 一排上下左右&#xff0c;在规定时间内正确输入&#xff0c;然后再在关键点狠拍空格键的那种游戏。 媳妇最近去了…

Love ya 三三小说 炫舞爱情 ⑦

第六十一章 开了游戏 &#xfffd;、铉楠っ‰真的依言所说 动也不动 站一边看 萧忆情无奈的叹口气 果然自己惹的祸还得自己整理呀 萧忆情开端尽力斗争啊 固然说技巧不错吧 但是也不能太轻敌 &#xfffd;、铉楠っ‰原来在一边看着 结果看到比分 有点吃惊 &#xfffd;、铉楠っ‰…

《浅析QQ炫舞6开挂》 研究了一晚上

最近一直卡在用win32汇编hook NtOpenProcess函数这 主要是语言掌握的不够好 今天终于找到了个可能能解决目前问题的文章 与君共享 http://bbs.pediy.com/showthread.php?t116205&highlightVC 标 题: 【原创】浅析QQ炫舞6开挂【请求邀请码】作 者: YangCoCol时 间: 2010-…

服务器 python cant open file_QQ炫舞转服系统-QQ炫舞官方网站-腾讯游戏

QQ炫舞转服须知 我们会在你开始转服操作前进行QQ安全中心的安全验证&#xff0c;这会进一步提升账号安全性。如果你曾经将你的账号信息告知其他人员&#xff0c;这可能会对你的账号造成损失。如果你还未绑定QQ安全中心&#xff0c;请前往QQ安全中心或下载QQ安全中心APP来完成绑…

[分享]浅析QQ炫舞6开挂

[原创]浅析QQ炫舞6开挂 转载&#xff1a;https://bbs.pediy.com/thread-116205.htm 偶去年在网上看到有一些“大牛”代练QQ炫舞&#xff0c;还上传了视频&#xff0c;个人感觉挺酷的&#xff0c;他用的是六开挂&#xff0c;售价还不菲&#xff08;200RMB&#xff09;&#xf…