组件冲突、data函数、组件通信

文章目录

    • 1.组件的三大组成部分 - 注意点说明
    • 2.组件的样式冲突(用 scoped 解决)
    • 3.data是一个函数
    • 4.组件通信
      • 1.什么是组件通信?
      • 2.不同的组件关系 和 组件通信方案分类
    • 5.prop详解
      • prop 校验
        • ①类型校验
        • ②完整写法(类型,非空,默认,自定义)
      • prop & data 单项数据流
    • 6.非父子通信(拓展)- event bus 事件总线
    • 7.非父子通信-provide-inject(拓展)
    • 8.v-model详解(帮助更好的理解v-model应用与组件进行组件通信)
      • v-model原理
      • 表单类组件封装 $ v-model 简化代码
    • 9.sync修饰符
    • 10.ref 和$refs
      • 获取dom元素
      • 获取组件元素
    • 11.Vue异步更新,$nextTick

1.组件的三大组成部分 - 注意点说明

组件的三大组成部分 - 注意点说明👇

①结构 < template >:只能有一个根元素
②样式 < style >:
全局样式(默认):影响所有组件
局部样式:scoped样式下,只作用于当前组件
③逻辑 < script >:el根实例独有,data是一个函数,其他配置项一致
(下面将详细的逐一地学一下②③部分)

2.组件的样式冲突(用 scoped 解决)

默认情况:写在组件中的样式会 全局生效→ 因此很容易造成多个组件之间的样式冲突问题。

scoped原理:

  • 1.给当前组件模板的所有元素,都会被添加上一个自定义属性data-v-hash值(且同一个组件中的hash值是一样的,所以它就可以用不同的hash值区分不同的组件)
    在这里插入图片描述
  • 2.css选择器的后面,被自动处理,添加上了属性选择器
    在这里插入图片描述
  • 最终效果必须是当前组件的元素,才会有这个自定义属性,才会被这个样式作用到

在这里插入图片描述

//BaseOne.vue
<template><div>BaseOne</div>
</template><script>
export default{
}
</script>
<style>
/* 默认的style样式,会作用于全局 */div {border:  3px solid blue;margin: 30px;}
</style>//BaseTwo.vue
<template><div>BaseTwo</div>
</template>
<script>
export default{
}
</script>
<style>
</style>//App.vue
<template><div id="app"><BaseOne></BaseOne><BaseTwo></BaseTwo></div>
</template><script>
import BaseOne from './components/BaseOne.vue';
import BaseTwo from './components/BaseTwo.vue'
export default{name:'App',components:{BaseOne:BaseOne,BaseTwo:BaseTwo}}
</script><style></style>
效果图如下

在这里插入图片描述

👇加上scoped进行修改

<style scoped>
/* 1.默认的style样式,会作用于全局2.加上scoped属性的style样式,只会作用于当前组件👉局部样式
组件应该有着自己独立的样式,推荐加上scoped*/div {border:  3px solid blue;margin: 30px;}
</style>
效果图如下

在这里插入图片描述

3.data是一个函数

①一个组件如果要提供数据,也是通过data
②一个组件的data选项必须是一个函数。👉 保证每一个组件实例,维护独立的一份数据对象。
每次创建新的组件实例,都会新执行一次data函数,得到一个新的对象

<template><div class="base-count"><button @click="count--">-</button><span>{{ count }}</span><button @click="count++">+</button></div>
</template><script>
export default{// data必须是一个函数 → 保证每个组件实例data (){return{count: 999}}
}
</script>
<style scoped>
.base-count{margin: 20px;
}
</style>

图文总结👇
在这里插入图片描述

4.组件通信

1.什么是组件通信?

组件通信,就是指组件与组件之间的数据传递

  • 组件的数据是独立的,无法直接访问其他组件的数据。
  • 想用其他组件的数据 → 组件通信

思考:1.组件之间有哪些关系? 2.对应的组件通信方案有哪几类?

2.不同的组件关系 和 组件通信方案分类

  • 组件关系分类:
    1.父子关系:组件A包裹组件B.那AB就是父子关系
    2.非父子关系:A包裹B和C,所以BC是非父子关系
    在这里插入图片描述
<!-- App.vue -->
<template><div style="border:3px solid #000;margin: 10px;">我是App组件<!-- 老爹的这个组件,儿子要用 --><!-- 1. 给组件标签,添加属性的方式传值--><Son :title="myTitle"></Son></div>
</template><script>import BaseSon from './components/BaseSon.vue'
export default{data () {return {myTitle:'黑马程序员'}},components:{BaseSon:BaseSon,}
}
</script>
<style>
</style><!-- BaseSon.vue -->
<template><div style="border:3px solid #000;margin: 10px;"><!-- 3.渲染使用 -->我是组件Son {{ title }}</div>
</template><script>
export default{// 2.通过props进行接受,且props里面的名字要和老爹里面要传过来的东西同名props:['title']//3.这边接收完毕,页面中就可以直接渲染使用了
}
</script>
<style>
</style>

在这里插入图片描述

<!-- App.vue -->
<template><div style="border:3px solid #000;margin: 10px;">我是App组件<!-- 老爹的这个组件,儿子要用 --><!-- 1. 给组件标签,添加属性的方式传值--><Son :title="myTitle" @changeTitle="handelChange"></Son></div>
</template><script>import BaseSon from './components/BaseSon.vue'
export default{data () {return {myTitle:'黑马程序员'}},components:{BaseSon:BaseSon,},methods:{//3.提供处理函数,提供逻辑handelChange (newTitle) {this.myTitle = newTitle}}
}
</script>
<style>
</style><!-- BaseSon.vue -->
<template><div style="border:3px solid #000;margin: 10px;">我是组件Son {{ title }}<button @click="changeFn">修改titile</button></div>
</template><script>
export default{props:['title'],methods:{changeFn () {//1.通过$emit,向父组件发送消息通知this.$emit('changeTitle','传智教育')}}
}
</script>
<style>
</style>

图文总结👇在这里插入图片描述

5.prop详解

什么是prop
Prop定义:组件上注册一些自定义属性
prop作用:向子组件传递数据

特点:

  • 可以传递任意数量的prop
  • 可以传递任意类型的prop

写法:1.在父组件中提供一些数据(字符串,对象,布尔值等)
2.然后通过给当前这个组件以添加属性的方式传值
3.传了之后,在子组件内部,就可以通过props接收
4.最终一面当中就可以做渲染了
👇
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

App.vue<template><div class="app"><!-- 父传子 --><UserInfo:username="username":age="age":isSingle="isSingle":car="car":hobby="hobby"></UserInfo></div>
</template><script>
import UserInfo from './components/UserInfo.vue'
export default {data() {return {username: '小帅',age: 28,isSingle: true,car: {brand: '宝马',},hobby: ['篮球', '足球', '羽毛球'],}},components: {UserInfo,},
}
</script><style>
</style>UserInfo.vue<template><div class="userinfo"><h3>我是个人信息组件</h3><div>姓名:{{ username }}</div><div>年龄:{{ age }}</div><div>是否单身:{{ isSingle ? 'yes' : 'no' }}</div><div>座驾:{{ car.brand }}</div><div>兴趣爱好:{{ hobby.join('、') }}</div>    <!-- 加上 .join('、') 就可以给三个爱好的文字之间加上顿号 --></div>
</template><script>
export default {props:['username','age','isSingle','car','hobby']
}
</script><style>
.userinfo {width: 300px;border: 3px solid #000;padding: 20px;
}
.userinfo > div {margin: 20px 10px;
}
</style>

prop 校验

思考:组件的prop可以乱传吗?(不可以,比如一个百分比数字不可以给它传布尔值)
作用:为组件的prop指定验证要求,不符合要求,控制台就会有错误提示 → 帮助开发者快速发现错误
语法
①类型校验
②非空校验
③默认值
④自定义校验

①类型校验

需要将原来props接收数据的写法改成对象,对象里面就可以写键值对了。值就是对应的类型要求:比如传进来的是Number类型,就写number
在这里插入图片描述

App.vue
<template><div class="app"><BaseProgress :w="width"></BaseProgress></div>
</template><script>
import BaseProgress from './components/BaseProgress.vue'
export default {data() {return {width: 'abc',}},components: {BaseProgress,},
}
</script><style>
</style>BaseProgress.vue
<template><div class="base-progress"><div class="inner" :style="{ width: w + '%' }"><span>{{ w }}%</span></div></div>
</template><script>
export default {// props: ["w"],props:{w:Number//Number String Boolean Array Object Function}// 1.基础写法(类型校验)// 2.完整写法(类型、是否必填、默认值、自定义校验)
}
</script><style scoped>
省略
</style>

在这里插入图片描述

②完整写法(类型,非空,默认,自定义)

在这里插入图片描述

<script>
export default {// props: ["w"]//1.基础校验(类型校验)// props:{//   w:Number//Number String Boolean Array Object Function// }// 2.完整写法(类型、是否必填、默认值、自定义校验)props:{w:{//对类型有要求type:Number,required:true,//需要非空default:0,//如果希望有一个默认值。而不是必填validator (value){//写这样一个方法,这个方法的形参,是可以拿到//你传递过来的prop传值的,拿到传值,就可以对他进行判断if (value >=0 && value <=100) {return true}return false}}}
}
</script>

prop & data 单项数据流

共同点:都可以给组件提供数据
区别:

  • data的数据是自己的 → 随便改
  • prop的数据是外部的 → 不能直接改 ,要循环单向数据流
App.vue
<template><div class="app"><BaseCount></BaseCount></div>
</template><script>
import BaseCount from './components/BaseCount.vue'
export default {components:{BaseCount},data(){return {count:100}},methods:{}
}
</script><style></style>erzi
<template><div class="base-count"><button @click="count--">-</button><span>{{ count }}</span><button @click="count++">+</button></div>
</template><script>
export default {// 1.自己的数据随便修改 (谁的数据 谁负责)// 意思就是,打开网页,想加就加,想减就减// data () {//   return {//     count: 100,//   }// },// 2.外部传过来的数据(由父组件提供) 不能随便修改props:{count:Number}
}
</script><style>
.base-count {margin: 20px;
}
</style>

上面的代码,数据由父组件提供,一保存会直接报错(外部数据不能直接改)
需要提供对应的函数

app.vue
<template><div class="app"><!-- 老爹监听 --><BaseCount@changeCount="handleChange"></BaseCount></div>
</template><script>
import BaseCount from './components/BaseCount.vue'
export default {components:{BaseCount},data(){return {count:666}},methods:{handleChange (newCount) {this.count = newCount}}
}
</script><style></style>~.vue
<template><div class="base-count"><button @click="handleSub">-</button><span>{{ count }}</span><button @click="handleAdd">+</button></div>
</template><script>
export default {// 1.自己的数据随便修改 (谁的数据 谁负责)// 意思就是,打开网页,想加就加,想减就减// data () {//   return {//     count: 100,//   }// },// 2.外部传过来的数据(由父组件提供) 不能随便修改//单项数据流:父组件的prop更新,会单向的向下流动,影响到子组件props:{count:Number},methods:{handleAdd(){//通过子传父 this.$emit(事件名,参数)//告诉老爹改数字,然后在老爹里面需要监听一下this.$emit('changeCount',this.count + 1)},handleSub(){this.$emit('changeCount',this.count - 1)}}
}
</script><style>
.base-count {margin: 20px;
}
</style>

6.非父子通信(拓展)- event bus 事件总线

作用:非父子组件之间,进行简易消息传递。(复杂场景 → Vuex)
1.创建一个都能访问到的事件总线(空 Vue实例)→ utils/EventBus.js

impprt Vue for 'vue'
const Bus = new Vue()
export default Bus

2.A组件(接收方),监听Bus实例的事件监听事件(订阅消息)

created () {Bus.$on('sendMsg',(msg) =>{this.msg = msg})

3.B组件(发送方),触发Bus实例的事件

Bus.$emit('sendMsg','这是一个消息')

在这里插入图片描述

7.非父子通信-provide-inject(拓展)

provide & inject 作用:跨层级共享数据

1.父组件`provide``提供数据
(provide写成一个函数,在里面return,return就是共享的数据,里面可以写多个数据【简单(string)/复杂(对象)类型】)

2.你在父组件中共享了数据,在孙组件中想要接收,直接写inject,想接收谁就写谁的名字,一旦接收好了,就可以在孙组件的上方直接渲染

3.共享数据的时候,通常会把它包成的一个对象,一复杂类型(响应式)的方式向下共享

在这里插入图片描述

export default {provide () {return {//普通类型【非响应式】colour:this.color,//复杂类型【响应式】userInfo:this.userInto,}}
}

子/孙组件(无论多少层) inject取值使用(直接写你要接收的属性名就可以了,将来也可以通过this直接访问)

export default {inject: ['color','userInfo'],created () {console,log(this.color,this.userInfo)}	
}

注:也可以接收多个数据 {{ xxx }} {{ xxx }} {{ xxx }}

App.vue
<template><div class="app">我是APP组件<button @click="change">修改数据</button><SonA></SonA><SonB></SonB></div>
</template>
<script>
import SonA from './components/SonA.vue'
import SonB from './components/SonB.vue'
export default {provide() {return {// 简单类型 是非响应式的color: this.color,// 复杂类型 是响应式的userInfo: this.userInfo,}},data() {return {color: 'pink',userInfo: {name: 'zs',age: 18,},}},methods: {change() {this.color = 'red'this.userInfo.name = 'ls'},},components: {SonA,SonB,},
}
</script>
<style>
lue
</style>~.vue
<template><div class="grandSon">我是GrandSon{{ color }} -{{ userInfo.name }} -{{ userInfo.age }}</div>
</template><script>
export default {inject: ['color', 'userInfo'],
}
</script><style>
lue
</style>

8.v-model详解(帮助更好的理解v-model应用与组件进行组件通信)

v-model原理

原理:v-model本质上是一个语法糖。例如应用在输入框上,就是value属性input事件的合写
作用:提供数据的双向绑定
①数据变,视图跟着变:value
②视图变,数据跟着变@input
注意$event用于在模板中,获取事件的形参
<input v-model='msg' type='text'> =<input :value="msg" + @input="msg = $event.target.value" type=“text”>

<template><div class="app"><input v-model="msg1" type="text" /><br /><input :value="msg2" @input="msg2 = $event.target.value" type="text" > <br><br></div>
</template><script>
export default {data() {return {msg1: '',msg2:''}},
}
</script>

在这里插入图片描述
在这里插入图片描述

表单类组件封装 $ v-model 简化代码

1.表单类组件封装 → 实现 子组件 和 父组件数据的 双向绑定
①父传子:数据应该是父组件props传递过来的,v-model拆解 绑定数据
②子传父:监听输入,子传父值给父组件修改
在这里插入图片描述

App.vue
<template><div class="app"><!-- 把城市Id传下去 --><BaseSelect:cityId="selectId"@changeId="selectId= $event"></BaseSelect></div>
</template><script>
import BaseSelect from './components/BaseSelect.vue'
export default {data() {return {//数据应该由老爹提供selectId: '102',}},components: {BaseSelect,},methods: {handleChange(e) {console.log(e);this.selectId = e}}
}
</script><style>
</style>~vue
<template><div><select :value="cityId" @change="handleChange"><!--里面不能写 v-model="cityId" 不能修改cityId,子组件是不让改的,所以这里要拆--><option value="101">北京</option><option value="102">上海</option><option value="103">武汉</option><option value="104">广州</option><option value="105">深圳</option></select></div>
</template><script>
export default {// 在子组件中用props接收props:{cityId:String},// 写处理函数methods:{handleChange (e) {this.$emit('changeId',e.target.value)}}
}
</script><style>
</style>

2.父组件v-model 简化代码,实现 子组件 和 父组件数据 双向绑定
核心步骤
①子组件中:props通过value接收,事件触发 input
②父组件中:v-model给组件直接绑数据(:value+@input

通过value进行接收,然后设置给上面的select,通过value往下传递,监听下拉菜单的改变,然后触发事件提交数据时,触发事件提交数据的是`input``
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

App.vue
<template><div class="app"><!-- v-model => :value + @input --><BaseSelectv-model="selectId"></BaseSelect></div>
</template><script>
import BaseSelect from './components/BaseSelect.vue'
export default {data() {return {//数据应该由老爹提供selectId: '102',}},components: {BaseSelect,},
}
</script>~.vue
<template><div><select :value="value" @change="handleChange"><!--里面不能写 v-model="cityId" 不能修改cityId,子组件是不让改的,所以这里要拆--><option value="101">北京</option><option value="102">上海</option><option value="103">武汉</option><option value="104">广州</option><option value="105">深圳</option></select></div>
</template><script>
export default {// 在子组件中用props接收props:{value:String},// 写处理函数methods:{handleChange (e) {this.$emit('input',e.target.value)}}
}
</script>

9.sync修饰符

作用:可以实现 子组件 与 父组件数据 的双向绑定,简化代码
特点:prop属性名,可以自定义,非固定为value
场景:封装弹框类的基础组件,visible属性 true显示 false隐藏
在这里插入图片描述

//father
<BaseDialong :visible.sync = "isShow">
<BaseDialog:visible="isShow"@updata:visible="isShow = $event"
>//son
<script>
props:{visible:Boolean
},
this.$emit('updata:visible',false)
</script>

10.ref 和$refs

作用:利用ref和¥refs可以用于获取dom元素,或组件实例
特点:查找范围 → 当前组件内(更精确稳定)
①获取dom:1.目标标签-添加ref属性
<div ref="chartRef">我是渲染图表的容器</div>
②恰当时机,通过this.$refs.xxx,获取目标标签
mounted () {
console.log(this.$refs.chartRef)
},

获取dom元素

App.vue
<template><div class="app"><div class="base-chart-box">这是一个捣乱的盒子</div><BaseChart></BaseChart></div>
</template>~vue
<template><div ref="mychart" class="base-chart-box">子组件</div>
</template><script>
import * as echarts from 'echarts'export default {mounted() {//const myChart = echarts.init{document.querySelect'base-chart-box'}//这个会找到父组件中的盒子//但我们想找当前组件范围内的盒子,用ref// 基于准备好的dom,初始化echarts实例const myChart = echarts.init(this.$ref.mychart)// 绘制图表
}
</script>

如上代码,就算有一个捣乱盒子,图表也不会放错地方
在这里插入图片描述

获取组件元素

在这里插入图片描述
1.目标组件 - 添加ref属性
<BaseFrom ref="baseForm"></BaseForm>
2.恰当时机,通过this.$refs.xxx,获取目标组件,就可以调用组件对象里面的方法
this.$refs.baseFrom.组件方法()

App.vue
<template><div class="app"><BaseForm ref="baseFrom"></BaseForm><button @click="handleGet">获取数据</button><button @click="handleReset">重置数据</button></div>
</template><script>
import BaseForm from './components/BaseForm.vue'
export default {data (){return {}
}, components: {BaseForm,},methods: {handleGet () {console.log(this.$refs.baseForm.getValue())},handleReset () {this.$refs.baseForm.resetValues()}}
}
</script>~。vue
<template><div class="app"><div>账号: <input v-model="username" type="text"></div><div>密码: <input v-model="password" type="text"></div><div><button @click="getFormData">获取数据</button><button @click="resetFormData">重置数据</button></div></div>
</template><script>
export default {data() {return {account: '',password: '',}},methods: {//方法1:收集表单数据,返回一个对象getValues() {retyrn () {account: this.account,password:this.password}},//方法2:重置表单resetValues() {this.account = ''this.password = ''console.log('重置表单数据成功');},}
}
</script>

11.Vue异步更新,$nextTick

需求:编辑标题,编辑框自动聚焦
1.点击编辑,显示编辑框
2.让编辑框,立刻获取焦点

this.isShowEdit = true //显示输入框
this.$refs.inp.focus() //获取焦点

问题:“显示之后”,立刻获取jiajiao点不能成功显示
原因:Vue是 异步更新DOM(提升性能)

想要在DOM更新wan’chwanche那个之后做某件事,可以使用$nextTick
在这里插入图片描述

<template><div class="app"><div v-if="isShowEdit"><input v-model="editValue" type="text"  ref="inp" /><button>确认</button></div><div v-else><span>{{ title }}</span><button @click="handleEdit">编辑</button></div></div>
</template><script>
export default {data() {return {title: '大标题',isShowEdit: false,editValue: '',}},methods: {handleEdit(){//显示输入框(异步dom更新)this.isShowEdit = true//让输入框获取焦点this.$nextTick(()=>{console.log(this.$refs.inp)this.$refs.inp.focus()})// setTimeout(() => {//   this.$refs.inp.focus()// },1000)}
}
}
</script><style>
</style>

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

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

相关文章

Windows系统安装OpenSSH+VS Code结合内网穿透实现远程开发

文章目录 前言1、安装OpenSSH2、vscode配置ssh3. 局域网测试连接远程服务器4. 公网远程连接4.1 ubuntu安装cpolar内网穿透4.2 创建隧道映射4.3 测试公网远程连接 5. 配置固定TCP端口地址5.1 保留一个固定TCP端口地址5.2 配置固定TCP端口地址5.3 测试固定公网地址远程 前言 远程…

计算机毕业设计 | SpringBoot 求职招聘管理系统(附源码)

1&#xff0c;绪论 1.1 开发背景 高学历人群是网络求职者的主体&#xff0c;且结构趋向固定。而在疫情肆虐的今日&#xff0c;线上招聘成了越来越多企业和个人选择的方式。在疫情期间线下招聘转为线上招聘&#xff0c;是疫情防控的需要。不能否定的是新的招聘模式的出现一定会…

IS-IS:04 DIS

IS-IS 协议只支持两种网络类型&#xff0c;即广播网络和点到点网络。与 OSPF 协议相同&#xff0c; IS-IS 协议在广播网络中会将网络视为一个伪节点 &#xff08; Pesudonde&#xff0c;简称 PSN&#xff09;&#xff0c;并选举出一台DIS &#xff08;Designated IS&#xff09…

【SVD生成视频+可本地部署】ComfyUI使用(二)——使用Stable Video Diffusion生成视频 (2023.11开源)

SVD官方主页 &#xff1a; Huggingface | | Stability.ai || 论文地址 huggingface在线运行demo : https://huggingface.co/spaces/multimodalart/stable-video-diffusion SVD开源代码&#xff1a;Github&#xff08;含其他项目&#xff09; || Huggingface 在Comfyui使用&…

力扣72. 编辑距离

动态规划 思路&#xff1a; 假设 dp[i][j] 是 word1 长度 i 和 word2 长度 j 的编辑距离&#xff1b;有三种编辑方式&#xff1a;插入、删除、替换&#xff0c;即 word1 插入、word2 插入、替换&#xff1b;那么 dp[i][j] 可以是&#xff1a; dp[i - 1][j] 在 word1 中插入一个…

数据结构----链表介绍、模拟实现链表、链表的使用

文章目录 1. ArrayList存在的问题2. 链表定义2.1 链表的概念及结构2.2 链表的组合类型 3. 链表的实现3.1 单向、不带头、非循环链表的实现3.2 双向、不带头节点、非循环链表的实现 4.LinkedList的使用4.1 什么是LinkedList4.2 LinkedList的使用4.2.1. LinkedList的构造4.2.2. L…

基于Java SSM框架实现药品销售系统项目【项目源码+论文说明】

基于java的SSM框架实现药品销售系统演示 摘要 本论文主要论述了如何使用JAVA语言开发一个药品销售系统 &#xff0c;本系统将严格按照软件开发流程进行各个阶段的工作&#xff0c;采用B/S架构&#xff0c;面向对象编程思想进行项目开发。在引言中&#xff0c;作者将论述药品销…

【Node.js】fs与path模块的基础使用

文章目录 前言一、什么叫做模块二、fs模块2.1 fs模块是干什么的&#xff1f;2.2 fs模块的使用导入fs模块读取文件的内容写入文件内容处理路径问题path路径模块 总结 前言 在Node.js中&#xff0c;fs模块&#xff08;文件系统模块&#xff09;是一个重要的核心模块&#xff0c;…

软件设计师——软件工程(五)

&#x1f4d1;前言 本文主要是【软件工程】——软件设计师——软件工程的文章&#xff0c;如果有什么需要改进的地方还请大佬指出⛺️ &#x1f3ac;作者简介&#xff1a;大家好&#xff0c;我是听风与他&#x1f947; ☁️博客首页&#xff1a;CSDN主页听风与他 &#x1f304…

如何在群晖NAS部署office服务实现多人远程协同办公编辑文档

文章目录 本教程解决的问题是&#xff1a;1. 本地环境配置2. 制作本地分享链接3. 制作公网访问链接4. 公网ip地址访问您的分享相册5. 制作固定公网访问链接 本教程解决的问题是&#xff1a; 1.Word&#xff0c;PPT&#xff0c;Excel等重要文件存在本地环境&#xff0c;如何在编…

项目交付后,PM该如何做复盘总结?

2023已经收尾&#xff0c;那些让我们或焦灼、或紧急、或喜悦、或悲伤的项目也都交付完毕了。为了更好的总结工作成果与反思&#xff0c;各家单位开始一边排练年会舞蹈一边要求员工做出项目交付后复盘方案了&#xff0c;那么&#xff0c;怎样的复盘才会让项目工作更加明确&#…

【SpringBoot3】集成Knife4j、springdoc-openapi作为接口文档

一、什么是springdoc-openapi Springdoc-openapi 是一个用于生成 OpenAPI&#xff08;之前称为 Swagger&#xff09;文档的库&#xff0c;专为 Spring Boot 应用程序设计。它可以根据你的 Spring MVC 控制器、REST 控制器和其他 Spring Bean 自动生成 OpenAPI 文档&#xff0c…

【Docker】数据持久化 挂载

Docker的镜像是只读的&#xff0c;但是容器是可写的&#xff0c;我们可以将数据写入到容器&#xff0c;不过一旦容器删除数据将会丢 失&#xff0c;那么有什么办法能将数据进行持久化存储呢&#xff1f; ——在宿主机上开辟一块地方&#xff0c;存储内容和docker容器的存储内…

基于Vue uniapp和java SpringBoot的汽车充电桩微信小程序

摘要&#xff1a; 随着新能源汽车市场的迅猛发展&#xff0c;汽车充电桩的需求日益增长。为了满足市场需求&#xff0c;本课题开发了一款基于Java SpringBoot后端框架和Vue uniapp前端框架的汽车充电桩微信小程序。该小程序旨在为用户提供一个简洁高效的充电服务平台&#xff0…

Vite+Electron快速构建一个VUE3桌面应用(一)

一. 简介 首先&#xff0c;介绍下vite和Electron。 Vite是一种新型前端构建工具&#xff0c;能够显著提升前端开发体验。Electron是一个使用 JavaScript、HTML 和 CSS 构建桌面应用程序的框架。 嵌入Chromium和Node.js到二进制的 Electron 允许您保持一个 JavaScript 代码代码…

git仓库批量备份

git的mirror参数 在git中&#xff0c;--mirror是一个用于克隆和推送操作的参数。它用于创建一个镜像仓库&#xff0c;包含了源仓库的所有分支、标签和提交历史记录。 当使用git clone --mirror <source-repo>命令时&#xff0c;会创建一个完全相同的镜像仓库&#xff0…

ROS学习笔记11——ROS中的重名问题

一、ros功能包重名——ros工作空间覆盖 功能包重名时&#xff0c;会按照 ROS_PACKAGE_PATH 查找&#xff0c;在前的会优先执行。ROS 会解析 .bashrc 文件&#xff0c;并生成 ROS_PACKAGE_PATH ROS包路径&#xff0c;即调用功能包的顺序&#xff0c;该变量中按照 .bashrc 中配置…

《安富莱嵌入式周报》第331期:单片机实现全功能软件无线电,开源电源EEZ升级主控,ARM 汇编用户指南,UDS统一诊断服务解析,半导体可靠性设计手册

周报汇总地址&#xff1a;嵌入式周报 - uCOS & uCGUI & emWin & embOS & TouchGFX & ThreadX - 硬汉嵌入式论坛 - Powered by Discuz! 目录&#xff1a; 1、单片机实现低配版全功能软件无线电&#xff0c;范围0.5-30 MHz&#xff0c;支持SSB、AM、FM和CW …

websocket 通信协议

websocket是什么 答: 它是一种网络通信协议&#xff0c;是 HTML5 开始提供的一种在单个 TCP 连接上进行全双工通讯的协议。 意思就是服务器可以主动向客户端推送信息&#xff0c;客户端也可以主动向服务器发送信息 属于服务器推送技术的一种. 为什么需要websocket? 疑问?…

python爬虫demo——爬取历史平均房价

简单爬取历史房价 需求 爬取的网站汇聚数据的城市房价 https://fangjia.gotohui.com/ 功能 选择城市 https://fangjia.gotohui.com/fjdata-3 需要爬取年份的数据&#xff0c;等等 https://fangjia.gotohui.com/years/3/2018/ 使用bs4模块 使用bs4模块快速定义需要爬取的…