乐闻世界logo
搜索文章和话题

前端

Web前端开发是从网页制作演变而来的,名称上有很明显的时代特征。在互联网的演化进程中,网页制作是Web 1.0时代的产物,那时网站的主要内容都是静态的,用户使用网站的行为也以浏览为主。2005年以后,互联网进入Web 2.0时代,各种类似桌面软件的Web应用大量涌现,网站的前端由此发生了翻天覆地的变化。网页不再只是承载单一的文字和图片,各种富媒体让网页的内容更加生动,网页上软件化的交互形式为用户提供了更好的使用体验,这些都是基于前端技术实现的。
前端
查看更多相关内容
Vue组件之间通信方式有哪些
在Vue.js中,组件之间的通信是一个非常重要的话题,因为它关系到应用程序如何将数据和事件在多个组件之间传递。Vue提供了多种组件通信的方式,适用于不同的场景。下面是一些常见的通信方式: ### 1. Props 和 Events 这是最基本也是最常用的组件间通信方式。父组件通过props向子组件传递数据,子组件通过事件向父组件发送消息。 **例子**: 在父组件中: ```vue <template> <Child :parentData="data" @childEvent="handleEvent"/> </template> <script> import Child from './Child.vue'; export default { components: { Child }, data() { return { data: 'data from parent', }; }, methods: { handleEvent(payload) { console.log('Event received from child:', payload); }, }, }; </script> ``` 在子组件中: ```vue <template> <button @click="sendToParent">Send to Parent</button> </template> <script> export default { props: ['parentData'], methods: { sendToParent() { this.$emit('childEvent', 'data from child'); }, }, }; </script> ``` ### 2. Event Bus Event bus 是一种使用Vue实例作为中央事件总线的方法,在不直接关联的组件之间传递消息。 **例子**: ```javascript // eventBus.js import Vue from 'vue'; export const EventBus = new Vue(); ``` 在发送事件的组件中: ```javascript import { EventBus } from './eventBus.js'; export default { methods: { sendEvent() { EventBus.$emit('do-something', 'some data'); }, }, }; ``` 在接收事件的组件中: ```javascript import { EventBus } from './eventBus.js'; export default { created() { EventBus.$on('do-something', data => { console.log(data); }); }, }; ``` ### 3. Vuex Vuex是Vue.js的状态管理库,可以用来管理所有组件的共享状态,是一种全局的通信方式。 **例子**: ```javascript // store.js import Vue from 'vue'; import Vuex from 'vuex'; Vue.use(Vuex); export default new Vuex.Store({ state: { message: '', }, mutations: { updateMessage(state, message) { state.message = message; }, }, }); ``` 在一个组件中更新状态: ```vue <template> <button @click="update">Update Message</button> </template> <script> import { mapMutations } from 'vuex'; export default { methods: { ...mapMutations([ 'updateMessage', // 映射 this.updateMessage() 为 this.$store.commit('updateMessage') ]), update() { this.updateMessage('Hello from Component A'); }, }, }; </script> ``` 在另一个组件中获取状态: ```vue <template> <div>{{ message }}</div> </template> <script> import { mapState } from 'vuex'; export default { computed: { ...mapState([ 'message', // 映射 this.message 为 this.$store.state.message ]), }, }; </script> ``` ### 4. Provide / Inject 这是一种在更深层次的嵌套组件中传递数据的方法,不需要通过每个组件层次传递props。 **例子**: 在祖先组件中: ```vue <script> export default { provide() { return { theme: 'dark', }; }, }; </script> ``` 在任意后代组件中: ```vue <script> export default { inject: ['theme'], mounted() { console.log(this.theme); // 输出: 'dark' }, }; </script> ``` 这些通信方式各有优缺点,适用于不同的场景和需求,通常在实际开发中需要根据应用的具体需求来选择合适的通信方式。
前端 · 7月4日 09:37
Composition API和Options API 之间的区别是什么
Composition API 和 Options API 是 Vue.js 框架中用于创建和组织组件的两种不同的API。Vue.js 是一个流行的前端JavaScript框架,用于构建用户界面和单页应用程序。下面我将详细说明它们之间的区别: ### Options API Options API 是 Vue.js 最初提供的接口,它是基于一个包含描述组件选项的对象的概念。这些选项包括了`data`、`methods`、`props`、`computed`、`watch`、`lifecycle hooks`等属性。这种API的特点是将组件的不同方面划分到这些选项中,代码按功能组织。 **例子**: ```javascript export default { data() { return { message: 'Hello Vue!', }; }, props: { user: String, }, computed: { normalizedUser() { return this.user.trim().toLowerCase(); }, }, methods: { sayHello() { alert(this.message); }, }, }; ``` 在这个例子中,`data`是组件的状态,`props`是外部传入的属性,`computed`是计算属性,`methods`是组件的方法。 **优点**: - 易于理解和上手,特别是对于初学者。 - 由于选项类型的组织方式,IDEs 和静态类型检查工具通常可以提供更好的支持。 **缺点**: - 在大型和复杂的组件中,相互关联的逻辑会被拆分到不同的选项中,导致代码维护和理解上的困难。 - 当组件变得庞大时,相同功能的代码可能散布在不同的选项中,难以追踪和组织。 ### Composition API Composition API 是在 Vue.js 3 中引入的,旨在解决 Options API 在构建大型应用时遇到的问题。它提供了更加灵活的方式来组织和重用代码。使用Composition API,开发者可以更容易地将组件逻辑基于功能划分和抽象成可复用的函数。 **例子**: ```javascript import { ref, computed } from 'vue'; export default { setup(props) { const message = ref('Hello Vue!'); const normalizedUser = computed(() => props.user.trim().toLowerCase()); function sayHello() { alert(message.value); } return { message, normalizedUser, sayHello, }; }, props: { user: String, }, }; ``` 在这个例子中,`setup`函数是组件中所有Composition API逻辑的起点。通过导入`ref`和`computed`,我们可以定义响应式状态和计算属性。`setup` 函数返回的对象将定义组件的响应式状态和方法。 **优点**: - 更好的逻辑复用和抽象,便于开发者根据功能组织代码,使得代码更加模块化。 - 更容易控制变量的作用域和生命周期。 - 更好地与TypeScript集成,提升类型推断的能力和开发体验。 **缺点**: - 学习曲线相对较陡峭,特别是对于那些习惯于 Options API 的开发者。 - 尽管它提供了更大的灵活性,但在小型项目或简单组件中可能会引入不必要的复杂性。 ### 结论 Options API 和 Composition API 都是 Vue.js 提供的强大工具,它们各有优势。选择哪种API取决于项目的需求、组件的复杂性以及开发团队的偏好。Composition API 在处理大型项目和复杂组件时优势明显,而Options API 在小型项目或对于新手更
前端 · 7月4日 01:22
什么是同源策略?什么是跨域问题?有什么手段可以解决跨域问题?
### 同源策略 同源策略是一种对浏览器发出请求的安全策略。根据这种策略,一个Web页面只能从同一来源(协议,域名和端口都必须相同)获取数据。 ### 跨域问题. 当一个Web页面尝试从不同的源访问资源时,就会出现跨域问题。例如,一个在 www.example1.com 上托管的脚本尝试访问 www.example2.com 上的资源,这就违反了同源策略,所以浏览器会阻止这个请求并产生跨域错误。 ### 解决跨域问题的手段 以下是一些常见的解决跨域问题的方法: 1. **CORS(跨源资源共享)**:CORS是一种让服务器允许来自特定源访问资源的机制。服务器通过设置特定的HTTP头部告诉浏览器哪些Web页面可以访问这些资源。 2. **JSONP(JSON with Padding)**:JSONP是一种通常用于解决跨域数据获取问题的方式。不过,这种方式局限于GET请求,并且安全性较差。 3. **代理服务器**:可以使用服务器端的代理转发请求,因为在服务器端不受同源策略限制。 4. **postMessage API**:使用HTML5引入的 window.postMessage 方法,可以安全地实现跨源通信。 5. **WebSocket协议**:WebSocket是一种建立在TCP协议之上的全双工通信协议,不受同源策略影响。 6. **WebSockets**:WebSockets API 是另一种通信协议,它不受同源策略的影响,可以用于任何地方的通信。 7. **Document.domain+iframe**:基于 document.domain 的跨域方法只适合主域相同的情况,也就是abc.example.com到www.example.com这样的跨域,区域子域和顶级字段相同。
前端 · 6月24日 16:43
Web前端安全攻击手段有哪些?以及应该如何做相应的防御措施?
Web前端安全攻击主要有以下几种常见的方式: 1. **XSS攻击(跨站脚本攻击)**:攻击者通过在目标网站上注入恶意的HTML代码,当用户浏览该网站时就会运行这些恶意代码。 **防御措施**:输入验证与过滤、输出编码、使用CSP(内容安全策略)防止不安全的动态脚本执行。 2. **CSRF攻击(跨站请求伪造)**:攻击者诱导用户点击链接,使用用户的登录凭证发送恶意请求。 **防御措施**:使用CSRF token,验证每个请求。 3. **点击劫持**:攻击者将透明的恶意网站覆盖在真实网站上,诱导用户在不知情的情况下进行恶意操作。 **防御措施**:使用X-FRAME-OPTIONS来防止网页被iframe调用。 4. **DoS攻击(拒绝服务攻击)**:恶意请求过多使得服务无法处理正常的请求。 **防御措施**:限制访问频率、使用CDN(内容分发网络)等方式分散流量。 5. **SQL注入攻击**:攻击者通过输入特殊的SQL查询语句,来获取数据库的敏感信息。 **防御措施**:使用预处理语句(Prepared Statements)或参数化的SQL命令,拒绝直接执行动态生成的SQL语句。 6. **上传恶意文件**:攻击者通过上传恶意文件,例如包含病毒或者后门的文件,来破坏服务器或者网页。 **防御措施**:限制可上传文件类型,扫描上传的文件以防止上传恶意软件,对上传文件名严格过滤等。
前端 · 6月24日 16:43
为什么有移动端 1px 的问题以及有什么方案可以解决移动端 1px 的问题?
> 为什么存在 1px 问题 移动端的1px问题主要是由于设备的物理像素和逻辑像素的不同所致。在高清显示屏(即设备独立像素比例devicePixelRatio大于1)的设备上,一个CSS像素可能会对应多个设备像素。这就导致了CSS的1px边框在高清屏上显示得比预期更粗。 > 1px 以下是一些主要的解决1px问题的方案: 1. **视口缩放(Viewport Scale)** 视口缩放的原理是将页面的视口设置为设备宽度的一半或一部分,然后布局以这个新的视口宽度为基准进行。由于视口被缩小,一个CSS像素也就对应了更少的设备像素。 ```html <meta name="viewport" content="width=device-width,initial-scale=.5,maximum-scale=.5,user-scalable=no"> ``` 2. **使用Media Query** 可以使用CSS的Media Query配合devicePixelRatio设定不同dpr下的边框样式,这样可以确保在不同dpr的设备上边框都看起来只有1px。 ```css @media only screen and (-webkit-device-pixel-ratio: 2) { .border { border-width: 0.5px; } } ``` 3. **使用伪元素 + transform: scaleY(.5)/scaleX(.5)** 利用伪元素,将元素的边框做一次.5的缩放,使得高清屏下1px边框变细。 ```css .border:after { content: ''; position: absolute; bottom: 0; background: #000; width: 100%; height: 1px; transform: scaleY(.5); -webkit-transform: scaleY(.5); } ``` 4. **使用SVG** 可以使用SVG矢量图形来实现1px边框。由于SVG是矢量图形,在任何分辨率的屏幕上都会很清晰。 ```html <svg width="100%" height="1" xmlns="http://www.w3.org/2000/svg" version="1.1"> <line x1="0" y1="0" x2="100%" y2="0" stroke="black" stroke-width=".5"/> </svg> ``` 5. **边框图片(Border Image)** `border-image` 属性可以让你使用图像作为边框,你可以自由定义图像如何填充和拉伸。 以上只是其中的一些常用解决方案,每种方法都有其适用范围和局限。在实际开发过程中,需要根据具体的应用情况选择最合适的方案。
前端 · 6月24日 16:43
CSS 选择器有哪些
CSS 选择器用于决定某个HTML元素上应用哪些样式。 以下是一些常用的CSS选择器: **1. 元素选择器** 基于HTML元素的名称选择元素。例如,选择所有的 `<p>` 元素: ```css p { color: red; } ``` **2. id 选择器** 使用HTML元素的 `id` 属性选择特定元素。id 选择器在CSS中使用 #" 符号定义。例如,选择 `id="intro"`的元素: ```css #intro { color: blue; } ``` **3. 类选择器** 使用HTML元素的 `class` 属性选择特定元素。类选择器在CSS中使用 `.` 符号定义。例如,选择 `class="highlight"`的所有元素: ```css .highlight { background-color: yellow; } ``` **4. 属性选择器** 可以选择带有指定属性的HTML元素。例如,选择所有带有 `target` 属性的 `<a>` 元素: ```css a[target] { background-color: pink; } ``` **5. 伪类选择器** 用于选择HTML元素的特定状态。例如,选择鼠标悬停在上面的 `<a>` 元素: ```css a:hover { color: green; } ``` **6. 伪元素选择器** 用于选择元素的某一部分。例如,选择每个 `<p>` 元素的第一行: ```css p::first-line { color: orange; } ``` **7. 组合选择器** 有时候,我们需要选择满足多项条件的元素,这时候就可以使用组合选择器。常见的组合选择器如下: - 后代选择器(空格) ```css div p { color: brown; } ``` - 子代选择器(>) ```css div > p { color: purple; } ``` - 相邻兄弟选择器(+) ```css div + p { color: gray; } ``` - 一般兄弟选择器(~) ```css div ~ p { color: teal; } ```
前端 · 6月24日 16:43