Vue day01

news2024/11/25 8:14:44

Vue

1.简介:

​ Vue是一套用于构建用户界面的渐进式框架。与其他大型框架不同的是,Vue被设计为可以自底向上逐层应用。Vue的核心库只关注视图层,不仅容易上手,还便于与第三方库或既有项目整合。另一方面,当与现代化的工具链以及各种支持类库结合使用时,Vue也完全能够为复杂的单页应用提供驱动。用来做单页面应用–index.html,页面跳转用的vue插件路由来实现跳转。

【vue】https://cn.vuejs.org/

【gitee封面人物:尤雨溪谈Vue.js】https://gitee.com/gitee-stars/14

【采访 Vue 作者尤雨溪】https://www.jianshu.com/p/3092b382ee80

【Object.defineProperty()详解 拓展理解vue源码】https://www.cnblogs.com/ldq678/p/13854113.html https://zhuanlan.zhihu.com/p/22695144

1-Vue基本渲染-插值
### js代码
    window.onload = function () {
            // 创建vue实例,vue实例要与模板(DOM)绑定
           let vm= new Vue({
                el: "#app",
                data: {// 数据模型
                    msg:'hello world'
                },
                // 函数
                methods: {
                    changeData(){
                      if(this.msg==='hello world'){
                        // 更改数据模型中的数据
                        // 获取数据模型中的数据
                        // 在vue实例内访问vue实例身上的属性和方法
                        this.msg='你好我是修改后的值'
                      }else{
                         this.msg='hello world';
                      }
                    }
                },
            })
        }
### html代码
<!-- 以前把msg作为元素文本的,获取dom节点,绑定事件,dom.innerText=msg-->
    <div id="app">
        <!-- 在模板内访问vue实例中数据模型中的数据 插值 -->
        <!-- 基本渲染 插值 -->
        {{msg}}
        <p>{{msg}}</p>
        <!-- 点击按钮 改变数据模型中的数据msg变量 -->
        <button @click='changeData'>点我修改数据模型msg数据</button>
    </div>
数据模型更改,引发了vm驱动

2.MVVM

​ Model 数据模型

​ View 视图

​ VM ViewModel 连接视图和数据模型的纽带,数据模型发生了变化,vm通知视图修改;视图发生了变化,vm通知数据模型进行相对应的修改.

视图模型 帮我们把数据模型中的数据渲染到视图中 相当于一个纽带

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-wd2QUqbw-1691293440376)(D:\代码区域\ES6和vue上课文档\images\image-20210527142359964.png)]

优化渲染:当前数据模型发生改变只改变对应的视图,只渲染对应的视图层

mvvm介绍:
m指model服务器上的业务逻辑操作,v指view视图(页面),vm指ViewModel模型跟视图间的核心枢纽,比如vue.js

可以将上图中的DOM Listeners Data Bindings 看作两个工具,它们是实现双向绑定的关键。

从View侧看,ViewModel中的DOM Listeners 工具会帮我们监测页面上DOM元素的变化,如果有变化,则更改Model中的数据;

从Model侧看,当我们更新Model中的数据时,Data Bindings 工具会帮我们更新页面中的DOM元素。

### 2.数据模型
 let vm=new Vue({
            el:'#app',
            data:{
               msg:'科大优质男',
			   time:new Date()
            },
            methods:{
                sayName(){
                    console.log(this.name)
                },
            }
        })
        // 每隔一秒重新查询一次时间
        setInterval(()=>{
            vm.time=new Date()
        },1000)
        // 查看vue实例对象
        console.log(vm)

****** **** 3.生命周期(钩子函数)

从vue实例创建虚拟dom产生再到数据绑定监听数据渲染以及销毁的整个过程

生命周期的第一步首先是创建vue实例,并且进行初始化。
### vue实例初始化阶段
beforeCreate
    在初始化的时候调用了beforeCreate,完成了vue实例的生命周期相关属性的初始化以及事件的初始化。这个时候还不能访问数据模型中的data和methods中的方法。
created
    在初始化完毕之后,完成vue的数据注入以及数据监听操作,该构造的执行意味着vue实例创建完毕,可以进行data数据模型和和methods方法的访问
### vue实例挂载阶段
beforeMount
    在created之后,vue会判断实例中是否含有el属性,如果没有vm.$mount(el),接着会判断是否含有template属性,如果有将其解析为一个render function,如果没有将el指定的外部html进行解析。这里只完成了模板的解析但是数据并没有绑定到模板中。
mounted
	创建vm.$el替换el,实际上完成的是数据绑定操作,在其间执行了render函数,将模板进行了解析,将数据进行了动态绑定
### vue实例更新阶段
	beforeUpdate
    更新虚拟dom节点
    updated
    完成了页面的重新渲染
### vue实例销毁阶段
	beforeDestroy
    销毁之前调用,此时可以访问vue实例
    destroyed
    完成了监听器,子组件,事件监听等移除,销毁vue实例对象。
### js代码
<script>
        let vm=new Vue({
            el:"#app",
            data:{
                msg:'hello world'
            },
            beforeCreate(){
                console.log('vue实例初始化之前')
            },
            created() {
                console.log('vue实例初始化好了,可以访问到数据模型中的数据以及methods方法')
            },
            beforeMount() {
                console.log('实例挂载之前')
            },
            mounted(){
                console.log('实例挂载完毕,可以获取dom节点,一般不操作dom')
            },
            beforeUpdate() {
                console.log('实例发生改变之前触发该生命周期')
            },
            updated() {
                console.log('实例发生改变后页面视图发生变化,触发该生命周期')
            },
            beforeDestroy() {
                // console.log('实例销毁之前,仍然可以访问到数据模型中的数据和方法')
            },
            destroyed() {
                // console.log('实例销毁完毕,销毁了监听器和事件监听以及子组件');
            },
            methods:{
                sayHello(){
                    console.log(this.msg)
                },
            }
        });
        console.log(vm)
        setTimeout(()=>{
            vm.$destroy()            
        },3000)
    </script>
### html代码
 <div id="app">
        {{msg}}
 </div>

4.模板语法

介绍:

vue使用了基于HTML的模板语法,允许开发者声明式地将DOM绑定至底层Vue实例的数据。所有 Vue的模板都是合法的 HTML,所以能被遵循规范的浏览器和HTML解析器解析。在底层的实现上,Vue 将模板编译成虚拟 DOM 渲染函数。结合响应系统,Vue 能够智能地计算出最少需要重新渲染多少组件,并把 DOM 操作次数减到最少。如果你熟悉虚拟 DOM 并且偏爱 JavaScript 的原始力量,你也可以不用模板,直接编写渲染函数及render,使用可选的 JSX 语法(react采用的就是jsx语法)。

1.插值: 1.基本渲染 {{}}

当一个 Vue 实例被创建时,它将 data 对象中的所有的 property 加入到 Vue 的响应式系统中。当这些 property 的值发生改变时,视图将会产生“响应”,即匹配更新为新的值。

渲染最常见的形式就是使用“Mustache”语法 (双大括号) 的文本插值。

2.原始html(v-html,解析标签中的文本内容)
3.属性v-bind(可以使用:简写 表示绑定的是一个变量)
4.事件v-on:click (可以使用@简写)
5.javascript表达式(可以进行js逻辑运算)
 ```Mustache 标签```将会被替代为对应数据对象上 ```msg property```的值。无论何时,绑定的数据对象上 ```msg property ```发生了改变,插值处的内容都会更新。当这些数据改变时,视图会进行重渲染。
1.文本渲染
	### js代码
	let vm=new Vue({
            el:'#app',
            data:{
                msg:'hello world',
                animal:['大笨象','小猴子','狐狸']
            },
            methods:{
            }
        });
	### html代码
   	<div id="app">
        <div>{{animal}}</div>
        <div>{{msg}}</div>
    </div>
也可以使用v-once指令,执行一次性地插值,当数据发生改变,插值处的内容不会更新
### js代码
	 let vm=new Vue({
            el:'#app',
            data:{
                msg:'hello world'
            }
        })
        setTimeout(()=>{
            vm.msg='hello vue'
        },2000)
### html代码
	<div id="app" >
        <!-- {{ msg }} 不会再更改,一直是hello world -->
        <div v-once>{{msg}}</div>
    </div>
2.如果我们向后台请求的数据是一段HTML代码,如果我们直接通过{{}}来输出,会将HTML代码也一起输出。双大括号会将数据解析为普通文本,而非 HTML 代码。但是我们可能希望的是按照HTML格式进行解析,并且显示对应的内容。如果我们希望解析出HTML展示
可以使用**v-html**指令:该指令后面往往会跟上一个string类型,会将string的html解析出来并且进行渲染。
	<div id="app">
        <div v-html='url'></div>
    </div>
	 new Vue({
            el:'#app',
            data(){
                return {
                    list:"All the changan flowers in one day",
                    url:'<a href="https://www.baidu.com">百度一下</a>'
                }
            }
        })
3.属性渲染
双大括号语法不能作用在元素属性上,遇到这种情况应该使用**v-bind**指令 :
	### js代码
	new Vue({
            el:"#app",
            data(){
                return {
                    msg:'我是数据模型中的msg',
                    title:'我是鼠标悬浮就会展示的title'
                }
            }
        })
	### html代码
    <div id="app">
        <!-- <div v-bind:title='title'>{{msg}}</div> -->
         <!-- 简写为:属性名="变量名" -->
        <div :title='title'>{{msg}}</div>
    </div>
4.事件渲染
可以使用v-on给当前元素绑定事件,也可以使用简写形式@click
 ###js代码
	 new Vue({
            el:'#app',
            data:{
            },
            methods:{
                test(){
                    alert(1)
                }
            }
        })
 ### html代码
  	<div id="app">
        <button v-on:click='test'>点我点我</button>
        <button @click='test'>点我点我</button>
    </div>
5.javaScript表达式
	###js代码
 	new Vue({
            el:'#app',
            data(){
                return {
                   animal:['大笨象','小猴子','狐狸'],
                   count:1001,
                   firstname:'ren',
                   lastname:'terry'
                }
            }
        })
	###html代码
    <div id="app">
        <ul>
            <li v-for='(item,index) in animal'>
                {{index+1}}-{{item}}-{{index}}
            </li>
        </ul>
        <div>{{Number(animal)}}</div>
        <div>{{Boolean(animal)}}</div>
        <div>{{count*100}}</div>
        <div>{{firstname}}--{{lastname}}</div>
    </div>

条件渲染

​ 1.v-if(可以单独使用)表达式为true的时候渲染使用v-if属性的元素,否则使用v-else渲染

​ 2.v-show(切换css样式中display属性),频繁切换css样式,使用v-show**

​ 不推荐同时使用 v-if 和 v-for。当 v-if 与 v-for 一起使用时,v-for 具有比 v-if 更高的优先级。

****** v-show 与 v-if 的区别 : v-show 不支持 v-else v-show 不管初始条件是什么,元素总是会被渲染,并且只是简单地基于 CSS 进行切换。 v-if 是“真正”的条件渲染,因为它会确保在切换过程中条件块内的事件监听器和子组件适当地被销毁和重建。 v-if 也是惰性的:如果在初始渲染时条件为假,则什么也不做;直到条件第一次变为真时,才会开始渲染条件块。 v-if 有更高的切换开销,而 v-show 有更高的初始渲染开销。因此,如果需要非常频繁地切换,则使用 v-show 较好;如果在运行时条件很少改变,则使用 v-if 较好。
v-if对应的是元素/标签的添加或者删除
满足条件添加元素
不满足条件删除元素
v-show对应的是元素的CSS样式中的display属性
满足条件对应的是元素的显示 display:block
不满足条件对应的是元素的隐藏 display:none
v-show用于频繁的切换css样式

 	### javascript代码
	new Vue({
			el:"#app",
			data:{
				type:'email',
				animal:['老虎','大象','狮子'],
				isShow:false
			}
		})
	### html代码
    <button @click="type='email'">点我获取email</button>
		<button @click="type='telephone'">点我获取telephone</button>
		<div v-if="type=='email'">
			<form>
				<input type="text" placeholder="请输入email">
			</form>
		</div>
		<div v-else-if="type==='telephone'">
			<form >
				<input type="text" placeholder="请输入telephone">
			</form>
		</div>
		<div v-else>错误</div>
		<ul v-show="">
			<li v-for="item in animal" :key="item">{{item}}</li>
		</ul>
	</div>

列表渲染 v-for

用于将列表数据进行渲染。v-for 指令需要使用 item in items 形式的特殊语法,其中 items 是源数据数组,而 item 则是被迭代的数组元素的别名。

*** key

Vue 会尽可能高效地渲染元素,通常会复用已有元素而不是从头开始渲染。这么做可以使 Vue 变得非常快。但是有些时候,我们却不希望vue复用,这时候Vue 为你提供了一种方式来表达“这两个元素是完全独立的,不要复用它们”。只需添加一个具有唯一值的 key

   ### html代码
		<ul>
            <li v-for='(item,index) in animal' :key='item'>
                {{index+1}}-{{item}}-{{index}}
            </li>
        </ul>
	### js代码
	  new Vue({
            el:'#app',
            data(){
                return {
                   animal:['大笨象','小猴子','狐狸'],
                }
            }
        })

style绑定

操作元素的class列表和内联样式是数据绑定的一个常见需求,因为它们都是attribute,所以我们可以用v-bind处理它们:只需要通过表达式计算出字符串结果即可。不过,字符串拼接麻烦且易错。因此,在将v-bind用于class和style时,Vue做了专门的增强。表达式结果的类型除了字符串之外,还可以是对象或数组。

### html代码
    <div :style="styleObj">Hello</div>
    <div :style="{color:currentColor}">World</div>
    <div :style="[styleObj2,styleObj]"> hello world</div>
### css代码
 new Vue({
      el: '#app',
      data: {
        currentColor: 'blue',
        styleObj: {
          color: 'red',
          "font-size": '30px',
        },
        styleObj2: {
          background: 'pink',
          color: 'blue'
        }
      },
    })

class绑定

操作元素的class列表和内联样式是数据绑定的一个常见需求,因为它们都是attribute,所以我们可以用v-bind处理它们:只需要通过表达式计算出字符串结果即可。不过,字符串拼接麻烦且易错。因此,在将v-bind用于class和style时,Vue做了专门的增强。表达式结果的类型除了字符串之外,还可以是对象或数组。

  ### css样式
   .red {
      color: red;
    }
    .size {
      font-size: 30px;
    }
	### html代码
     <div id="app">
        <div class="red" :class="{size:true}">Hello</div>
        <div :class="{red:false,size:true}">World</div>
        <div :class="[{red:true},{size:false}]">hello World</div>
  	</div>
	### js代码
     new Vue({
      el: '#app',
      data: {
      
      },
    })

********* 【面试题:为什么在大型项目中data是一个函数而不是一个对象】

组件是一个可复用的实例,当你引用一个组件的时候,组件里的data是一个普通的对象,所有用到这个组件的都引用的同一个data,就会造成数据污染。

不使用return包裹的数据会在项目的全局可见,会造成变量污染;
使用return包裹后数据中变量只在当前组件中生效,不会影响其他组件。
当一个组件被定义, data 必须声明为返回一个初始数据对象的函数,因为组件可能被用来创建多个实例。如果 data 仍然是一个纯粹的对象,则所有的实例将共享引用同一个数据对象!通过提供 data 函数,每次创建一个新实例后,我们能够调用 data 函数,从而返回初始数据的一个全新副本数据对象。
//1、在简单的vue实例中看到的Vue实例中data属性,如下所示:
<script>
  let vm=new Vue({
    el:'',
    data:{},//数据可以直接挂在vue实例上
    methods:{}
  })
</script>
//2、在使用组件化的项目中,如下所示:
//每一个.vue文件中都对应一个vue组件实例,该vue组件实例的构造函数参数由当前页面的export default提供
<script>
  export default{
  	data(){
		return {
          
      	}
	},
    methods:{
	}
</script>
```
官方推荐我们在使用v-for时,给对应的元素或组件添加上一个:key属性。
为什么需要这个key属性呢(了解)?

这个其实和Vue的虚拟DOM的Diff算法有关系。

当某一层有很多相同的节点时,也就是列表节点时,我们希望插入一个新的节点
  • 我们希望可以在B和C之间加一个F,Diff算 法默认执行起来是这样的。
  • 即把C更新成F,D更新成C,E更新成D,最 后再插入E,是不是很没有效率?
    在这里插入图片描述
所以我们需要使用key来给每个节点做一个唯一标识
  • Diff算法就可以正确的识别此节点

  • 找到正确的位置区插入新的节点。

所以一句话,key的作用主要是为了高效的更新虚拟DOM。

![[外链图片转存中...(img-NxoOjIU8-1691293440378)]](https://img-blog.csdnimg.cn/327e67c95dc4415c8d3a34109e611626.

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

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

相关文章

taro Swiper组件--异形滚动

效果 <SwiperindicatorDots{false}previousMargin50pxnextMargin50pxautoplay{false}interval100onChange{onChangeSwiper} >{[1,2,3].map((item, index) > {return (<SwiperItemkey{item-${index}}><View className{demo-item ${currentIndex index ? ac…

【PCL-6】PCL基于凹凸型的分割算法(LCCP)

凹凸型分割算法适用于颜色类似、棱角分明的物体场景分割。LCCP方法不依赖点云颜色&#xff0c;只使用空间信息和法线信息。 算法流程&#xff1a; 1、基于超体聚类的过分割&#xff1b; 2、在超体聚类的基础上再聚类。 算法思路&#xff1a; 1、基于CC和SC判断凹凸性&…

24.Netty源码之合理管理堆内存

highlight: arduino-light 合理管理 Netty 堆外内存 内存使用目标 •内存占用少(空间) •应用速度快(时间) 即多快好省 对 Java 而言&#xff1a;减少 Full GC 的 STW(Stop the world)时间 内存使用技巧 • 减少对象本身大小 md 例 1&#xff1a;用基本类型就不要用包装类。 例…

程序使用Microsoft.XMLHTTP对象请求https时出错解决

程序中使用Microsoft.XMLHTTP组件请求https时出现如下错误&#xff1a; 出错程序代码示例&#xff1a; strUrl "https://www.xxx.com/xxx.asp?id11" dim objXmlHttp set objXmlHttp Server.CreateObject("Microsoft.XMLHTTP") objXmlHttp.open "…

关于架构与架构师的一些感悟

本博客地址&#xff1a;https://security.blog.csdn.net/article/details/132152177 一、引子 最近在做工作总结的过程中&#xff0c;对于架构与架构师又有了一些新的感悟&#xff0c;本文有感而写&#xff0c;分为四个部分&#xff1a; ● 关于系统架构 ● 关于系统架构师 …

动手学深度学习(三)线性神经网络—softmax回归

分类任务是对离散变量预测&#xff0c;通过比较分类的概率来判断预测的结果。 softmax回归和线性回归一样也是将输入特征与权重做线性叠加&#xff0c;但是softmax回归的输出值个数等于标签中的类别数&#xff0c;这样就可以用于预测分类问题。 分类问题和线性回归的区别&#…

《24海南大学835软件工程考研经验贴》

1.经验之谈 首先&#xff0c;我是一个二战的考生&#xff0c;一战给我带来的经验有几点。第一&#xff0c;数学、专业课这两门越早复习越好&#xff0c;越拖到后面你就会发现来不及了&#xff0c;这学不完&#xff0c;那学不完的。第二、我认为是比较关键的一点&#xff0c;一定…

WebRTC基础知识

文章目录 基础概念NAT (Network Address Translation) 打洞STUN&#xff08;Session Traversal Utilities for NAT&#xff09;基于STUN协议的DDoS反射攻击 # TODO TURN&#xff08;Traversal Using Relays around NAT&#xff09;ICE&#xff08;Interactive Connectivity Est…

Java版企业电子招标采购系统源码Spring Cloud + Spring Boot +二次开发+ MybatisPlus + Redis tbms

​ 功能描述 1、门户管理&#xff1a;所有用户可在门户页面查看所有的公告信息及相关的通知信息。主要板块包含&#xff1a;招标公告、非招标公告、系统通知、政策法规。 2、立项管理&#xff1a;企业用户可对需要采购的项目进行立项申请&#xff0c;并提交审批&#xff0c;查…

[C#] 简单的俄罗斯方块实现

一个控制台俄罗斯方块游戏的简单实现. 已在 github.com/SlimeNull/Tetris 开源. 思路 很简单, 一个二维数组存储当前游戏的方块地图, 用 bool 即可, true 表示当前块被填充, false 表示没有. 然后, 抽一个 “形状” 类, 形状表示当前玩家正在操作的一个形状, 例如方块, 直线…

力扣 474. 一和零

题目来源&#xff1a;https://leetcode.cn/problems/ones-and-zeroes/description/ C题解&#xff1a;本题其实是01背包问题&#xff01;只不过这个背包有两个维度&#xff0c;一个是m 一个是n&#xff0c;而不同长度的字符串就是不同大小的待装物品。动规五部曲&#xff1a; …

Java并发 | 常见线程安全容器

文章目录 简介一、Hash表&#x1f6a3;1、ConcurrentHashMap1.1 内部实现原理1.2 并发操作方法1.3 ConcurrentHashMap与Hashtable的比较 二、集合&#x1f6a3;2、CopyOnWriteArrayList2.1 内部实现原理2.2 Copy-On-Write(COW)设计思想2.3 实操 三、Map&#x1f6a3;3、Concurr…

C语言第十课----------------扫雷----------数组的经典练手题

作者前言 &#x1f382; ✨✨✨✨✨✨&#x1f367;&#x1f367;&#x1f367;&#x1f367;&#x1f367;&#x1f367;&#x1f367;&#x1f382; &#x1f382; 作者介绍&#xff1a; &#x1f382;&#x1f382; &#x1f382;…

力扣120.三角形最小路径和(动态规划)

/*** author Limg* date 2022/08/09* 给定一个三角形 triangle &#xff0c;找出自顶向下的最小路径和。* 每一步只能移动到下一行中相邻的结点上。* 相邻的结点在这里指的是下标与上一层结点下标相同或者等于上一层结点下标 1 的两个结点。* 也就是说&#xff0c;如果正位于当…

(MVC)SpringBoot+Mybatis+Mapper.xml

前言&#xff1a;本篇博客主要对MVC架构、Mybatis工程加深下理解&#xff0c;前面写过一篇博客&#xff1a;SprintBoothtml/css/jsmybatis的demo&#xff0c;里面涉及到了Mybatis的应用&#xff0c;此篇博客主要介绍一种将sql语句写到了配置文件里的方法&#xff0c;即Mybatis里…

AVL树(二叉搜索树)

AVL树 1.1 AVL树的概念1.2 AVL树节点的定义1.3 AVL树的旋转1.3.1 右旋&#xff08;右单旋&#xff09;1.3.2 左旋&#xff08;左单旋&#xff09;1.3.3 左右双旋&#xff08;先左单旋再右单旋&#xff09;1.3.4 右左双旋&#xff08;先右单旋再左单旋&#xff09; 1.4 AVL树的插…

进程 的初识

程序和进程有什么区别 程序是静态的概念&#xff0c;gcc xxx.c -o pro 磁盘中生成的文件&#xff0c;叫做程序。进程是程序的一次运行活动&#xff0c;通俗点的意思就是程序跑起来了&#xff0c;系统中就多了一个进程。 如何查看系统中有哪些进程 使用 ps 指令&#xff08;完整…

❤ vue组件的生命周期

❤ vue组件的生命周期 介绍 在vue组件中&#xff0c;生命周期指的是从组件创建开始&#xff0c;到组件销毁&#xff0c;所经历的整个过程&#xff1b;在这个过程中的一些不同的阶段&#xff0c;vue会调用指定的一些组件方法。基本生命周期函数有下面几个阶段&#xff1a;创建…

Python中的dataclass:简化数据类的创建

Python中的dataclass是一个装饰器&#xff0c;用于自动添加一些常见的方法&#xff0c;如构造函数、__repr__、__eq__等。它简化了创建数据类的过程&#xff0c;减少了样板代码&#xff0c;提高了代码的可读性和可维护性。有点类似java里面的Java Bean。 让我们看一个简单的例子…

将.doc文档的默认打开方式从WPS修改为word office打开方式的具体方法(以win 10 操作系统为例)

将.doc文档的默认打开方式从WPS修改为word office打开方式的具体方法&#xff08;以win 10 操作系统为例&#xff09; 随着近几年WPS软件的不断完善和丰富&#xff0c;在某些方面取得了具有特色的优势。在平时编辑.doc文档时候也常常用到wps软件&#xff0c;不过WPS文献也存在…