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

一、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>

在这里插入图片描述
这里的双向数据绑定:绑定的就是inout框中value值,通过双向绑定,来实现模版视图和data中数据的交互

双向数据绑定:<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/diannao/17886.shtml

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

相关文章

数据库语法树优化

目录 一、σ、π、⋈ 1.选择σ 2.投影π 3.连接⋈ 二、 构建语法树 ① 解读sql语句 ② 写出关系代数表达式 ③ 画出语法树 三、优化语法树 四、练习 语法树优化方法 一、σ、π、⋈ 1.选择σ 选择就是在关系R中选择满足给定条件的诸元组。 通过条件SdeptIS选择出系别…

基于香橙派搭建家庭网盘

一、概述 家庭网盘是一种用于家庭用户的在线存储和文件共享服务。它允许家庭成员在云端存储、同步和分享照片、视频、文档等文件&#xff0c;方便快捷地访问和管理个人和家庭数据。家庭网盘通常提供安全可靠的数据存储和备份功能&#xff0c;保障用户数据的安全性。此外&#x…

一文解决弹窗交互设计难题,轻松上手

弹窗交互的分类 我们每天所说的弹出窗口是一个非常笼统的概念。我们习惯性地称所有的对话框、浮层和提示条为弹出窗口。事实上&#xff0c;弹出窗口可以分为两种类型&#xff1a;模态弹出框和非模态弹出框。在 UI 在设计中&#xff0c;当它迫使用户与之交互时&#xff0c;我们…

【算法】【二叉树,DFS,哈希集合,分类讨论】力扣1110. 删点成林

1110. 删点成林 文章目录 【算法】力扣【二叉树&#xff0c;DFS&#xff0c;哈希集合&#xff0c;分类讨论】1110. 删点成林题目描述示例 1&#xff1a;示例 2&#xff1a; 输入输出示例解释思路解析核心思想算法步骤复杂度分析 代码实现总结 【算法】力扣【二叉树&#xff0c…

ElasticSearch - 删除已经设置的认证密码(7.x)

文章目录 Pre版本号 7.x操作步骤检查当前Elasticsearch安全配置停止Elasticsearch服务修改Elasticsearch配置文件删除密码重启Elasticsearch服务验证配置 小结 Pre Elasticsearch - Configuring security in Elasticsearch 开启用户名和密码访问 版本号 7.x ES7.x 操作步骤 …

马斯克xAI融资60亿美元,宣布打造世界第一超算中心,10万张H100GPU

昨天&#xff0c;埃隆马斯克的xAI初创公司宣布获得60亿美元的巨额融资&#xff0c;主要用于打造一台巨大的超级计算机&#xff0c;马斯克称之为“超级计算工厂”。 从创立OpenAI到如今的xAI&#xff0c;技术和算力的发展历经了几个时代&#xff0c;但似乎马斯克的吸金能力一直…

代码随想录算法训练营day21|530.二叉搜索树的最小绝对值差、501.二叉搜索树中的众数、236.二叉树的最近公共祖先

二叉搜索树的最小绝对值差 递归法 首先需考虑这是一个二叉搜索树&#xff0c;在中序遍历后的结果为从小到大的一个序列&#xff0c;寻找二叉搜索树的最小绝对值差&#xff0c;只需比较一个节点与之后的差值即可。在遍历的过程中&#xff0c;我们需要一个节点保存前节点…

短道速滑短视频:四川京之华锦信息技术公司

短道速滑短视频&#xff1a;冰雪激情的视觉盛宴 随着冬奥会的热度不断攀升&#xff0c;短道速滑作为其中一项紧张刺激、充满观赏性的运动&#xff0c;受到了越来越多人的关注。而在社交媒体和短视频平台的助力下&#xff0c;短道速滑短视频成为了人们了解、欣赏这项运动的新窗…

vxe-form-design 表单设计器的使用

vxe-form-design 在 vue3 中表单设计器的使用 查看官网 https://vxeui.com 安装 npm install vxe-pc-ui // ... import VxeUI from vxe-pc-ui import vxe-pc-ui/lib/style.css // ...// ... createApp(App).use(VxeUI).mount(#app) // ...使用 github vxe-form-design 用…

Python在忘mysql密码后该如何重新连mysql

步骤一 先到mysql的bin目录下 步骤二 用mysqld delete mysql 把之前的库删了 步骤三 通过管理员模式进去后 用命令mysqld --skip-grant-tables越过验证 再输入mysql -u root 直达账户 步骤四 用FLUSH PRIVILEGES; ALTER USER rootlocalhost IDENTIFIED BY new_password; 指…

Echarts x轴坐标二级分组

在使用echarts 封装组件的时候&#xff0c;偶尔会遇到需要x轴坐标进行二层分组的需求。那么如何对echarts 进行二层分组呢&#xff0c;有以下几个步骤&#xff1a; 仅介绍二层分组的逻辑。有兴趣的可以进行三层延伸。 1&#xff0c;修改echarts Options 中xAxis 的配置。 此…

【机器学习】K-近邻算法(KNN)全面解析

&#x1f308;个人主页: 鑫宝Code &#x1f525;热门专栏: 闲话杂谈&#xff5c; 炫酷HTML | JavaScript基础 ​&#x1f4ab;个人格言: "如无必要&#xff0c;勿增实体" 文章目录 K-近邻算法&#xff08;KNN&#xff09;全面解析概述1. 基本概念与原理1.1 KNN算…

Excel表格保护密码遗忘怎么办?三秒钟破解密码,轻松解锁!

在我们的日常工作中&#xff0c;Excel表格是一个非常实用的工具&#xff0c;但在某些情况下&#xff0c;我们可能会遇到密码忘记的问题&#xff0c;或者在尝试打开或删除文件时被锁定。别担心&#xff0c;这里有三个简单的解决方法来帮助您解决问题。 一、尝试默认密码或常见密…

使用 Orange Pi AIpro开发板基于 YOLOv8 进行USB 摄像头实时目标检测

文章大纲 简介算力指标与概念香橙派 AIpro NPU 纸面算力直观了解 手把手教你开机与基本配置开机存储挂载设置风扇设置 使用 Orange Pi AIpro进行YOLOv8 目标检测Pytorch pt 格式直接推理NCNN 格式推理 是否可以使用Orange Pi AIpro 的 NPU 进行推理 呢&#xff1f;模型开发流程…

gitlab push 代码,密码正确,仍然提示HTTP Basic: Access denied. The provided password

HTTP Basic: Access denied. The provided password or token is incorrect or your account has 2FA enabled and you must use a personal access token instead of a password gitlab 登录账户密码确认正确&#xff0c;登录获取代码仍然提示以上问题&#xff0c;解决方案 …

①单细胞学习-数据读取、降维和分群

目录 ①数据读取 ②计算线粒体基因比例 ③分开进行质控 ④两组单细胞数据合并 ⑤细胞周期评分 ⑥降维标准流程 降维 UMAP可视化 选择分群 ⑦marker基因 分析marker基因 marker基因可视化 ⑧细胞定群命名 单细胞的数据格式学习&#xff1a;单细胞 10X 和seurat对象…

【软件设计师】算法

1、算法的效率 时间复杂度:程序从开始到结束所需要的时间 空间复杂度&#xff1a;算法在运行过程中临时占用存储空间大小的度量 时间渐近复杂度&#xff1a;时间复杂度由最高次幂决定(判断大小技巧&#xff1a;将n10代入&#xff09; O(log2 n):二分查找法 O(n&#xff09;:for…

家政预约小程序07服务分类展示

目录 1 创建服务分类页面2 侧边栏选项卡配置3 配置数据列表4 从首页跳转到分类页总结 上一篇我们开发了首页的服务展示功能&#xff0c;本篇我们讲解一下服务分类功能的开发。在小程序中通常在底部导航栏有一个菜单可以展示所有服务&#xff0c;侧边选项卡可以展示分类信息&…

Python零基础一天丝滑入门教程(非常详细)

目录 第1章 初识python 第1节 python介绍 1.为什么要学习Python&#xff1f; 2.python排名 3.python起源 4.python 的设计目标 第2节 软件安装 第2章 快速上手&#xff1a;基础知识 第1节 Python3 基础语法 Python 变量 字面量 数据类型转换 Python3 注释 数据类…

垂类短视频:四川鑫悦里文化传媒有限公司

垂类短视频&#xff1a;内容细分下的新媒体力量 随着移动互联网的迅猛发展和智能手机的普及&#xff0c;短视频已成为当下最受欢迎的媒介形式之一。四川鑫悦里文化传媒有限公司而在短视频领域&#xff0c;一个新兴的概念——“垂类短视频”正逐渐崭露头角&#xff0c;以其独特…