十四天学会Vue——Vue核心(理论+实战)(第一天)上篇

!!!声明必看:由于本篇开始就写了Vue,内容过多,本篇部分内容还有待完善,小编先去将连续更新的js高阶第四天完成~本篇部分待完善内容明日更新

一、Vue核心(上篇)

热身tops:选取开发模式
在这里插入图片描述

①用于开发模式 我们只需要知道 我们是开发模式,开发模式他会跟你提示代码出现错误的地方以及出错原因,而生产模式比较简洁。
②用于生产模式

1.1 new Vue()实例

了解Vue:Vue 构造函数是 vue.js 框架中用于创建 Vue 实例的核心部分,而 vue.js 框架则是一个包含了这个构造函数以及许多其他功能和工具的完整系统。注:后半句话不太理解,先这样,后面理解后会更新 !

(1)关于vue实例

  1. 想让Vue工作,就必须创建一个Vue实例,且要传入一个配置对象;创建vue实例语法:new Vue({ 配置对象 })
  2. 配置对象包含很多配置项,也就是属性或者方法,常见的如:data,el,methods等。
  3. root容器里的代码依然符合html规范,只不过混入了一些特殊的Vue语法;如插值语法
  4. root容器里的代码被称为【Vue模板】
    <!-- 准备好一个容器 --><div id="root"><!-- 插值语法 --><h1>hello,{{name}}</h1></div><script type="text/javascript">//死记硬背:开发的时候写着这个就好了  减少不必要的提示Vue.config.productionTip = false<!-- 创建vue实例 -->new Vue({el: '#root', //el用于指定当前vue实例为哪个容器服务,值通常为css选择器字符串data: { //data用于存储数据,数据供el所指定的容器去使用,值通常是对象name: '哈哈哈'}})</script>

1.2 模板语法

Vue模板语法两大类:插值语法 指令语法

(1).插值语法

功能:可以解析标签体的内容(标签是html标签)
语法:{{xxxx}} xxxx是js表达式 可以直接读取data中的所有属性(意味着即使是data中的方法,也可以直接将方法属性插入到模版中,将结果直接返回);如果data出现多个相同名字的属性,使用多层,需要用点来引用

  <div id="root"><h1>插值语法</h1><h3>你好,{{name}}</h3></div><script>Vue.config.productionTip = falsenew Vue({el: ' #root',data: {name: 'jack'}}) </script>

讲一下vue模版中的JS表达式
vue模版可以直接访问js表达式,这意味着即使是name属性也可是直接访问JS表达式,相当于将name当对象来用

区分js表达式和js代码(语句)在 Vue 的模板中,可以使用 JavaScript 表达式,但不能直接添加 JavaScript 代码块(如
if语句、for循环等)。

因为Vue 的模板是声明式的,意味着你告诉 Vue 你想要什么,而不是如何得到它。

***js表达式 和 js代码(语句)区分***1.表达式:一个表达式会产生一个值,可以放在任何一个需要值的地方:(1). a(2). a+b(3). demo(1)(4). x === y ? 'a' : 'b'2.js代码(语句)(1). if(){}(2). for(){}
<!-- 准备好一个容器 --><div id="root"><!-- 13:03 --><!-- 函数调用表达式 --><h1>hello,{{name.toUpperCase()}},{{address}},{{Date.now()}}</h1></div>

(2).指令语法

 Vue中指令语法通常是 v-
功能:用于解析标签(包括:标签属性(也就是可以直接对标签属性进行操作)、标签体内容、绑定事件、、、)。
即:不再像插值语法局限标签体内容,可以直接利用data中的数据对标签属性值进行赋值,属性值还可以加上js表达式或者变量;重新给标签设置属性(注意:在data数据中设置好属性和属性值)

意思是当我使用V-bind指令时,实际上是将html属性的值给绑定在vue实例对象某个数据属性上,这样当vue实例该数据属性的值发生变化,html属性的值也相应发生变化

    <div id="root"><!--v-bind:缩写为: -->//这里的x实际上是重新给标签设置属性(注意:在data数据中设置好属性和属性值)<a v-bind:href='url' :x="hello">{{school.name}}</a><!-- <a :href='school.url.toUpperCase()' :x="school.hello">{{school.name}}</a> --></div><script>Vue.config.productionTip = falsenew Vue({el: ' #root',data: {name: 'jack',// 两个相同属性,不能在同一层school: {name: '百度',url: 'https://www.baidu.com/',hello: '你好'}}}) </script>
 单项数据绑定:<input type="text" v-bind:value="name"><br>

在这里插入图片描述

双向数据绑定:<input type="text" v-model:value="name"><br>

在这里插入图片描述
单向双向绑定案例一起写:

<!-- 准备一个容器 --><div id="root">单项数据绑定:<input type="text" v-bind:value="name"><br>双向数据绑定:<input type="text" v-model:value="name"><br><!-- 简写:单项数据绑定:<input type="text" :value="name"><br>双向数据绑定:<input type="text" v-model="name"> --><!-- v-model只能应用在表单元素(输入类元素)上 --><!-- <h2 v-bind:x="name">你好啊</h2> --></div><script type="text/javascript">Vue.config.productionTip = falsenew Vue({el: "#root",data: {name: '哈哈哈'}})</script>

就会有神奇的化学反应:这里用abc代指。那就是只要b发生改变,a、c都会紧接着改变,大家会觉得奇怪,c发生改变是因为双向绑定特性,但是a为什么改变,这是因为b发生改变,因为双向绑定,c发生改变;c发生改变,因为c、a之间有单项绑定,c改变,所以a改变。
在这里插入图片描述

1.4 el与data的两种写法

 <script type="text/javascript">Vue.config.productionTip = false //阻止 vue 在启动时生成生产提示。const vm = new Vue({// el: '#root',//指定容器 第一种写法// 函数式  第二种写法的简写式:// data () {//     return {//         name: '哈哈哈哈'//     }// }// 使用普通函数// data: function () {//     return {//         name: '哈哈哈'//     }// }// 第二种写法的简写式:使用箭头函数// 箭头函数在vue实例中一般不要添加 因为需要将this指向vue实例  而不是其他data: () => {console.log('@@@', this) //此处的thisreturn {name: '哈哈哈'}}})// 指定容器  挂载式vm.$mount('#root')</script>

1.5 Vue中的MVVM

Vue是基于MVVM构成的
M模型 对应data中的数据
V视图:模板    DOM:vue模版经过解析形成的页面从而形成dom结构  所以模版也是页面结构
VM  视图模型 Vue实例对象  
VM:Vue实例对象  

实例对象vm的由来:通过Viewmodel 可以实现视图与数据的交互 而且通过vue实例可以获得viewmodel 所以叫vm
Vue中MVVM之间的关系:
在这里插入图片描述
这样:实例对象vm对象中的数据经过数据绑定就绑定在页面上的DOM上面了
DOM结构经过监听就返回到数据中了
数据经过数据绑定形成页面上的dom的页面结构
反映在代码上:
在这里插入图片描述
有下面的案例可以知道:

data中的属性经过vue内部一系列sao操作,可以显示vue实例对象中;而vue实例对象中的所有属性直接间接都可以被展示在页面视图中。

 <!-- 容器  视图 V --><div id="root"><h1>学校名称:{{name}}</h1><h1>学校地址:{{address}}</h1><h1>{{$options}}</h1></div><script type="text/javascript">Vue.config.productionTip = false //阻止 vue 在启动时生成生产提示。// Vue实例 vmconst vm = new Vue({el: '#root',// 数据 Mdata: {name: '尚硅谷',address: '北京',a: 1}})console.log(vm);

在这里插入图片描述

1.6 回顾Object.defineProperty方法

<script>let number = 20let person = {name: '张三',sex: '男',// age: number}// 访问age属性 默认会调用此函数//getter 函数在尝试读取 age 属性的值时会被调用,而 setter 函数在尝试设置 age 属性的值时//会被调用。 定义对象中的新属性Object.defineProperty(person, 'age', {// value: 18,// enumerable: true, //控制属性是否可以枚举// writable: true,  //控制属性是否可以被修改 默认值是false// configurable: true, //控制属性是否可以被删除  默认值是falseget () {console.log('有人读取age属性了')return number},set (value) {console.log('有人修改了age属性,且是', value)number = value}})// console.log(Object.keys(person));// for in遍历对象// for (let key in person) {//     console.log('@', person[key])// }// console.log(person);</script>

1.7 数据代理

 // 数据代理:通过一个对象代理对另一个对象中属性的操作(读 / 写)let obj = { x: 100 }let obj2 = { y: 200 }//对A对象的访问实现对B对象的访问Object.defineProperty(obj2, 'x', {get () {return obj.x}, set (value) {obj.x = value}})

在这里插入图片描述
在这里插入图片描述
页面的数据发生改变:
一旦data中的数据发生改变,那么页面中用到该数据的地方也会自动更新
在这里插入图片描述
数据代理总结:

1.Vue中的数据代理:
通过vm对象来代理data对象中属性的操作(读/写)
2.Vue中数据代理的好处:
更加方便的操作data中的数据
3.基本原理:
通过Object.defineProperty()把data对象中所有属性添加到vm上。
为每一个添加到vm上的属性,都指定一个getter/setter。
在getter/setter内部去操作(读/写)data中对应的属性。

1.8 事件处理

(1)事件的基本使用

在这里插入图片描述

  1. 回调函数中传参 要加上(),并且不要忘记event,便于获取event.target.innerHTML,$event
  2. vm中showinfo方法和data数据的区别是showinfo不进行数据代理,为什么?——(1)顾名思义,showinfo是函数,是方法,通过别人调用他来工作的,写完是不改变的,只需要等着被调用;但是data中的数据name是数据,如果从hi1,改变为hi2,需要数据代理更好地改变数据。(2)其实showinfo放在data中也可以被调用(以下将showinfo2放在data中),但是用到了getter和setter,因为方法只会被调用,不会被更改,这样就错误滴使用了数据代理。
    在这里插入图片描述
 const vm = new Vue({el: '#root',data: {name: '北京',showInfo2 (number, event) {  //所有被vue管理的函数最好写成普通函数alert('同学你好2')console.log(number, event)// console.log(event.target.innerText)// console.log(this) //此处的this是vm}},//配置项methods: {showInfo1 (event) {  //所有被vue管理的函数最好写成普通函数alert('同学你好1')// console.log(event.target.innerText)// console.log(this) //此处的this是vm}}});
  1. 总结:事件的基本使用:
    1.使用v-on:xxx 或 @xxx 绑定事件,其中xxx是事件名;
    2.事件的回调需要配置在methods对象中,最终会在vm上;
    3.methods中配置的函数,不要用箭头函数!否则this就不是vm了;
    4.methods中配置的函数,都是被Vue所管理的函数,this的指向是vm 或 组件实例对象;
    5.@click=“demo” 和 @click=“demo($event)” 效果一致,但后者可以传参;

(2)事件修饰符

注意:stopPropagation() 方法的作用就是阻止事件在捕获和冒泡阶段的进一步传播。也就是说,当你调用一个事件对象(通常通过事件处理函数中的 event 参数获取)的 stopPropagation() 方法时,该事件将不会继续传播到 DOM 树中的其他节点。
preventDefault 阻止默认行为
capture js事件流 捕获阶段+冒泡阶段 触发box2传2 先捕获在冒泡 捕获阶段 外=》内 冒泡阶段由内岛外 开始执行 捕获阶段就开始处理
self 不加上 则可以有两次冒泡并且是一样的 加了self相当于组织了冒泡阶段
passive 事件的默认行为立即执行 无需等待事件回调执行完毕 感觉用的地方太少 不了解了!!!最后还是写了解决哈哈哈哈
这里使用到了@scroll 滚动条滚动
@wheel 滚轮滚动 对这个有用 不加passive 需要限制性回调函数 那么回调函数执行for循环之后才能完成滚动条的滚动 但我自己实际上实践的时候 其实并没有完全执行完or循环才滚动条滚动 而是一会儿就滚懂了
并且在使用@scroll 无论for循环多大 滚动条都会直接滚动 这也说明passive并不是什么事件都用得上的 在某些特定事件

  <!-- passive  事件的默认行为立即执行  无需等待事件回调执行完毕 --><!-- 滚动条的滚动  鼠标轮的滚动 --><ul @wheel.passive="demo" class="list"><li>1</li><li>2</li><li>3</li><li>4</li></ul>
demo () {// console.log('@')for (let i = 0; i < 100000; i++) {console.log('#')}console.log('累坏了')}

键盘事件

1.Vue中常用的按键别名:
回车 => enter
删除 => delete (捕获“删除”和“退格”键)
退出 => esc
空格 => space
换行 => tab (特殊,必须配合keydown去使用)
上 => up
下 => down
左 => left
右 => right
2.Vue未提供别名的按键,可以使用按键原始的key值去绑定,但注意要转为kebab-case(短横线命名)

			3.系统修饰键(用法特殊):ctrl、alt、shift、meta(1).配合keyup使用:按下修饰键的同时,再按下其他键,随后释放其他键,事件才被触发。(2).配合keydown使用:正常触发事件。4.也可以使用keyCode去指定具体的按键(不推荐)5.Vue.config.keyCodes.自定义键名 = 键码,可以去定制按键别名

1.8 计算属性

姓名案例——插值语法实现
缺点:实现都需要在vue模板中实现,vue官网说的是Vue 的模板是声明式的,意味着你告诉 Vue 你想要什么,而不是如何得到它。要求vue模版中尽量语法简洁,所以不适合在这里面那实现很多方法

 <div id="root">姓:<input type="text" v-model="firstName"></br></br>名:<input type="text" v-model="lastName"></br></br><!-- vue模版中的语句应该尽量简化   此时如果还要让填进去的字母有小写变成大写,还需要继续添加代码,太复杂了-->姓名:<span>{{firstName.slice(0,3)}}-{{lastName}}</span></div><script type="text/javascript">new Vue({el: '#root',data: {firstName: '张',lastName: '三'}})

姓名案例——methods实现

先说一下:插值语法与指令语法加()与不加()的区别
在这里插入图片描述
在这里插入图片描述

重点理解:数据一变化vue模板就会重新解析,自然里面的方法也会重新调用一下fullName,所以全名也会随着变化

 <div id="root">姓:<input type="text" v-model="firstName"></br></br>名:<input type="text" v-model="lastName"></br></br>全名: <span>{{fullName()}}</span><!-- <button @click="fullName()">点我</button> --></div><script type="text/javascript">Vue.config.productionTip = false //阻止 vue 在启动时生成生产提示。new Vue({el: '#root',data: {firstName: '张',lastName: '三'},methods: {fullName () {console.log('数据一变化vue模板就会重新解析,自然里面的方法也会重新调用一下fullName')return this.firstName + '-' + this.lastName}}});</script>

在这里插入图片描述
计算属性

<!DOCTYPE html>
<html lang="zh-CN"><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><meta http-equiv="X-UA-Compatible" content="ie=edge"><title>Document</title><script src="../../js/vue.js"></script>
</head><body><div id="root">姓:<input type="text" v-model="firstName"><br><br>名:<input type="text" v-model="lastName"><br><br>全名:<span>{{fullName}}</span><br><br>全名:<span>{{fullName}}</span><br><br>全名:<span>{{fullName}}</span><br><br>全名:<span>{{fullName}}</span><br><br>全名:<span>{{fullName}}</span></div><script type="text/javascript">Vue.config.productionTip = false //阻止 vue 在启动时生成生产提示。const vm = new Vue({el: '#root',data: {firstName: '张',lastName: '三'},computed: {// fullName: {//     // get的作用:当有人读取fullName时,get就会被调用且返回值就作为fullName的值//     //get什么时候被调用?1.初次读取fullName时  2.所依赖的数据发生变化时//     // 这里提到一个缓存,也就是所赐调用  只有在初次调用的时候才起效果  vu'e会将返回值保存起来 并且起名fullName  与methods方法不同//     get () {//         console.log('get被调用了')//         // console.log(this)//         return this.firstName + '-' + this.lastName//     },//set什么时候被调用?当fullName被修改时//     set (value) {//         console.log('set', value)//         // 在每个分隔符处将字符串分割为子串  并返回为数组//         const arr = value.split('-')//         this.firstName = arr[0]//         this.lastName = arr[1]//     }// }// 只考虑读取 不考虑修改  简写// fullName: function () {//     console.log('get被调用了')//     return this.firstName + '-' + this.lastName// }fullName () {return this.firstName + '-' + this.lastName}}});</script>
</body></html>

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

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

相关文章

vue3+electron+typescript 项目安装、打包、多平台踩坑记录

环境说明 这里的测试如果没有其他特别说明的&#xff0c;就是在win10/i7环境&#xff0c;64位 创建项目 vite官方是直接支持创建electron项目的&#xff0c;所以&#xff0c;这里就简单很多了。我们已经不需要向开始那样自己去慢慢搭建 yarn create vite这里使用yarn创建&a…

外企也半夜发布上线吗?

0 别把问题想得太复杂 如果有灰度发布的能力&#xff0c;最好白天发布&#xff1b;如果没有灰度发布&#xff0c;只能在半夜发布。 即使有灰度发布能力&#xff0c;也不要沾沾自喜&#xff0c;好好反思一下你们的灰度发布是否真的经得起考验&#xff0c;还是仅仅是装装样子。…

golang创建式设计模式---工厂模式

创建式设计模式—工厂模式 目录导航 创建式设计模式---工厂模式1)什么是工厂模式2)使用场景3)实现方式4)实践案例5)优缺点分析 1)什么是工厂模式 工厂模式(Factory Method Pattern)是一种设计模式&#xff0c;旨在创建对象时&#xff0c;将对象的创建与使用进行分离。通过定义…

深度学习中的多GPU训练(Pytorch 20)

一 多GPU训练 下面详细介绍如何从零开始并行地训练网络&#xff0c;这里需要运用小批量随机梯度下降算法。后面我还讲介绍如何使用高级API并行训练网络。 我们从一个简单的计算机视觉问题和一个稍稍过时的网络开始。这个网络有多个卷积层和汇聚层&#xff0c;最后可能 有几个…

picamera配opencv做发现移动物体后录像50秒

本来是想配合上一篇写的测距传感器数据打开摄像头录制个50秒实时画面&#xff0c;后来这个测距传感器&#xff08;因为我是歪用&#xff0c;用来识别范围内的移动物体&#xff09;给的数据&#xff0c;false alarming还是太高了。于是想到使用本人之前深恶痛绝的opencv来试一试…

【编译原理--- 汇编、编译、解释系统】

汇编、编译、解释系统 1.编译方式和解释方式 程序种类是否生成目标程序是否参与程序的运行过程程序执行速度可移植性编译程序生成不参与快差解释程序不生成参与慢好 编译方式过程&#xff1a;词法分析、语法分析、语义分析、&#xff08;中间代码生成、代码优化、&#xff0…

如何解决mfc110udll丢失的问题,7个方法可解决mfc110udll丢失

mfc110u.dll是一个动态链接库文件&#xff0c;属于Microsoft Visual C 2012 Redistributable Package的一部分。它是Microsoft Foundation Classes (MFC) 库的一个版本&#xff0c;专门用于支持基于MFC开发的应用程序运行。MFC是一个用于Windows操作系统上使用C进行本机应用程序…

VS+QT连接mysql

1.将mysql安装目录中的库文件拷贝到qt的bin目录下&#xff0c;windows下拷贝dll后缀&#xff0c;linux拷贝lib后缀 2.在qt模块中添加sql模块 或者在.pri文件中加上 QT sql 3.代码连接数据库 #include <QtSql>QSqlDatabase DB; DB QSqlDatabase::addDatabase(&…

反弹shell详细易懂讲解,看这一篇就够了

文章目录 反弹shell详细易懂讲解&#xff0c;看这一篇就够了一: 基础shell知识什么是shell&#xff0c;bash与shell的区别?通俗解释类型功能常见命令 二: 什么是反弹shell三: 反弹shell类型bash反弹shellNetcat 一句话反弹curl反弹shell正确姿势 wget方式反弹awk反弹 Shellsoc…

车载电子电器架构 —— 应用软件开发(下)

车载电子电器架构 —— 应用软件开发(下) 我是穿拖鞋的汉子,魔都中坚持长期主义的汽车电子工程师。 老规矩,分享一段喜欢的文字,避免自己成为高知识低文化的工程师: 屏蔽力是信息过载时代一个人的特殊竞争力,任何消耗你的人和事,多看一眼都是你的不对。非必要不费力证…

WWW 2024最佳论文|大型语言模型的机制设计

【摘要】我们研究拍卖机制以支持人工智能生成内容的新兴格式。我们特别研究如何以激励兼容的方式聚合多个法学硕士。在这个问题中&#xff0c;每个代理对随机生成的内容的偏好被描述/编码为 LLM。一个关键动机是为人工智能生成的广告创意设计一种拍卖格式&#xff0c;以结合不同…

《计算机网络微课堂》1-4 计算机网络的定义和分类

本节课我们介绍计算机网络的定义和分类。 首先来看计算机网络的定义&#xff1a;计算机网络的精确定义并未统一&#xff0c;换句话说&#xff0c;全世界没有一个对计算机网络的公认的唯一定义。 这里我们给出一个计算机网络的最简单定义&#xff0c;即计算机网络是一些互相连接…

【LeetCode刷题】滑动窗口思想解决:最大连续1的个数 III、将x减到0的最小操作数

【LeetCode刷题】Day 8 题目1&#xff1a;1004.最大连续1的个数 III思路分析&#xff1a;思路1&#xff1a;暴力枚举zero计数器思路2&#xff1a;滑动窗口zero计数器 题目2&#xff1a;1658. 将x减到0的最小操作数思路分析&#xff1a;思路1&#xff1a;暴力枚举思路2&#xff…

联邦学习(一)

世界第一本“联邦学习”专著——《联邦学习》。作者阅读数书籍《联邦学习实战》。 1.联邦学习概述 在构件全局模型时,其效果与数据被整合在一起进行集中式训练的效果几乎一致,这便是联邦学习提出的动机和核心思想。 核心理念:数据不动模型动,数据可用不可见。 传统训练范式…

Linux|ubuntu22.04安装CUDA最新完整教程

文章目录 一、安装前准备工作查看GPU和型号查看GCC版本*下载gcc12 *检查驱动 二、安装CUDA Toolkit*安装驱动 三、安装后的工作必要操作推荐的操作开启守护进程模式删除本地下载安装包 四、验证删除CUDA常见问题及解决方案还需要安装cuDNN吗&#xff1f;nvcc: No such file or …

贪心-AcWing 1522. 排成最小的数字-XMUOJ石板序列

题目 思路 getline() 是 C 标准库中的一个函数&#xff0c;用于从输入流中读取一行文本&#xff0c;并将其存储为字符串。它可以从标准输入、文件流、字符串流等不同类型的输入流中读取数据。C中istringstream、ostringstream、stringstream详细介绍和使用_c istringstream-CS…

C++之std::is_trivially_copyable(平凡可复制类型检测)

目录 1.C基础回顾 1.1.平凡类型 1.2.平凡可复制类型 1.3.标准布局类型 2.std::is_trivially_copyable 2.1.定义 2.2.使用 2.3.总结 1.C基础回顾 在C11中&#xff0c;平凡类型&#xff08;Trivial Type&#xff09;、平凡可复制类型&#xff08;TrivialCopyable&#x…

Python语言基础学习(下)

目录 一、顺序语句 二、条件语句 (1) if (2) if - else (3) if - elif - else 缩进和代码块 空语句 pass 三、循环语句 while 循环 for 循环 continue break 四、函数 创建函数 调用函数 函数返回 函数变量 函数递归 关键字参数 五、列表和元组 创建列表 …

Windows、Linux下,基于QT的打包方法

整理这篇文档的意义在于&#xff1a;自己走了很多弯路&#xff0c;淋过雨所以想为别人撑伞&#xff0c;也方便回顾&#xff0c;仅供参考 ps: 第一次做Windows下打包&#xff0c;用了2小时&#xff0c;第二次20秒第一次做Linux(ubuntu)下打包&#xff0c;用了8小时&#xff0c;…

不拍视频,不直播怎么在视频号卖货赚钱?开一个它就好了!

大家好&#xff0c;我是电商糖果 视频号这两年看着抖音卖货的热度越来越高&#xff0c;也想挤进电商圈。 于是它模仿抖音推出了自己的电商平台——视频号小店。 只要商家入驻视频号小店&#xff0c;就可以在视频号售卖商品。 具体怎么操作呢&#xff0c;需要拍视频&#xf…