做网站怎么样才能赚到钱/电子商务网站推广

做网站怎么样才能赚到钱,电子商务网站推广,招标网官网登录,哪个网站教做公众号前面通过几篇文章了解并掌握了 Vue 项目构建及运行的前期工作 。接下来我们可以走进 Vue 项目的内部,一探其内部配置的基本构成。 1. 路由配置 由于 Vue 这类型的框架都是以一个或多个单页构成,在单页内部跳转并不会重新渲染 HTML 文件,其路…

前面通过几篇文章了解并掌握了 Vue 项目构建及运行的前期工作 。接下来我们可以走进 Vue 项目的内部,一探其内部配置的基本构成。

1. 路由配置

由于 Vue 这类型的框架都是以一个或多个单页构成,在单页内部跳转并不会重新渲染 HTML 文件,其路由可以由前端进行控制,因此我们需要在项目内部编写相应的路由文件,Vue 会解析这些文件中的配置并进行对应的跳转渲染。

我们来看一下 CLI 给我们生成的 router.js 文件的配置:

/* router.js */import Vue from 'vue'
import Router from 'vue-router'
import Home from './views/Home.vue' // 引入 Home 组件
import About from './views/About.vue' // 引入 About 组件Vue.use(Router) // 注册路由export default new Router({routes: [{path: '/',name: 'home',component: Home}, {path: '/about',name: 'about',component: About}]
})

这份配置可以算是最基础的路由配置,有以下几点需要进行优化:

  • 如果路由存在二级目录,需要添加 base 属性,否则默认为 "/"

  • 默认路由模式是 hash 模式,会携带 # 标记,与真实 url 不符,可以改为 history 模式

  • 页面组件没有进行按需加载,可以使用 require.ensure() 来进行优化

下面是我们优化结束的代码:

/* router.js */import Vue from 'vue'
import Router from 'vue-router'// 引入 Home 组件
// 使用 require.ensure 实现代码分割,只有在访问该路由时才会加载 Home.vue 组件,实现懒加载
const Home = resolve => {require.ensure(['./views/Home.vue'], () => {resolve(require('./views/Home.vue'))})
}// 引入 About 组件
const About = resolve => {require.ensure(['./views/About.vue'], () => {resolve(require('./views/About.vue'))})
}Vue.use(Router)//获取基础路径.适应不同的部署环境
let base = `${process.env.BASE_URL}` export default new Router({mode: 'history',base: base,routes: [{path: '/',name: 'home',component: Home}, {path: '/about',name: 'about',component: About}]
})

改为 history 后我们 url 的路径就变成了 http://127.0.0.1:8080/vue/about,而不是原来的 http://127.0.0.1:8080/vue/#/about,但是需要注意页面渲染 404 的问题,具体可查阅:HTML5 History 模式。

而在异步加载的优化上,我们使用了 webpack 提供的 require.ensure() 进行了代码拆分,主要区别在于没有优化前,访问 Home 页面会一起加载 About 组件的资源,因为它们打包进了一个 app.js 中:

但是优化过后,它们分别被拆分成了 2.js 和 3.js:

如此,只有当用户点击了某页面,才会加载对应页面的 js 文件,实现了按需加载的功能。

webpack 在编译时,会静态地解析代码中的 require.ensure(),同时将模块添加到一个分开的 chunk 当中。这个新的 chunk 会被 webpack 通过 jsonp 来按需加载。 关于 require.ensure() 的知识点可以参考官方文档:require.ensure。

当然,除了使用 require.ensure 来拆分代码,Vue Router 官方文档还推荐使用动态 import 语法来进行代码分块,比如上述 require.ensure 代码可以修改为

// 引入 Home 组件
const Home = () => import('./views/Home.vue');// 引入 About 组件
const About = () => import('./views/About.vue');

其余代码可以保持不变,仍然可以实现同样的功能。如果你想给拆分出的文件命名,可以尝试一下 webpack 提供的 Magic Comments(魔法注释):

const Home = () => import(/* webpackChunkName:'home'*/ './views/Home.vue');

2. Vuex 配置

除了 vue-router,如果你的项目需要用到 Vuex ,那么你应该对它有一定的了解,Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式。这里我们先来看一下使用 CLI 生成的配置文件 store.js 中的内容:

import Vue from 'vue'
import Vuex from 'vuex'Vue.use(Vuex)export default new Vuex.Store({state: {},mutations: {},actions: {}
})

该配置文件便是 Vuex 的配置文件,主要有 4 个核心点:state、mutations、actions 及 getter,详细的介绍大家可以参考官方文档:核心概念,这里我用一句话介绍它们之间的关系就是:我们可以通过 actions 异步提交 mutations 去 修改 state 的值并通过 getter 获取

需要注意的是不是每一个项目都适合使用 Vuex,如果你的项目是中大型项目,那么使用 Vuex 来管理错综复杂的状态数据是很有帮助的,而为了后期的拓展性和可维护性,这里不建议使用 CLI 生成的一份配置文件来管理所有的状态操作,我们可以把它拆分为以下目录:

└── store├── index.js          # 我们组装模块并导出 store 的地方├── actions.js        # 根级别的 action├── mutations.js      # 根级别的 mutation└── modules├── moduleA.js    # A模块└── moduleB.js    # B模块

与单个 store.js 文件不同的是,我们按模块进行了划分,每个模块中都可以包含自己 4 个核心功能。比如模块 A 中:

/* moduleA.js */const moduleA = {state: { text: 'hello'},mutations: {addText (state, txt) {// 这里的 `state` 对象是模块的局部状态state.text += txt}},actions: {setText ({ commit }) {commit('addText', ' world')}},getters: {getText (state) {return state.text + '!'}}
}export default moduleA

上方我们导出 A 模块,并在 index.js 中引入:

/* index.js */import Vue from 'vue'
import Vuex from 'vuex'
import moduleA from './modules/moduleA'
import moduleB from './modules/moduleB'
import { mutations } from './mutations'
import actions from './actions'Vue.use(Vuex)export default new Vuex.Store({state: {groups: [1]},modules: {moduleA, // 引入 A 模块moduleB, // 引入 B 模块},actions, // 根级别的 actionmutations, // 根级别的 mutations// 根级别的 gettersgetters: {getGroups (state) {return state.groups}}   
})

3. 接口配置

在项目的开发过程中,我们也少不了与后台服务器进行数据的获取和交互,这一般都是通过接口完成的,那么我们如何进行合理的接口配置呢?我们可以在 src 目录下新建 services 文件夹用于存放接口文件:

└── src└── services├── http.js      # 接口封装├── moduleA.js    # A模块接口└── moduleB.js    # B模块接口

为了让接口便于管理,我们同样使用不同的文件来配置不同模块的接口,同时由于接口的调用 ajax 请求代码重复部分较多,我们可以对其进行简单的封装,比如在 http.js 中(fetch为例):

/* http.js */
import 'whatwg-fetch'// HTTP 工具类
export default class Http {static async request(method, url, data) {const param = {method: method,headers: {'Content-Type': 'application/json'}};if (method === 'GET') {url += this.formatQuery(data)} else {param['body'] = JSON.stringify(data)}// Tips.loading(); // 可调用 loading 组件return fetch(url, param).then(response => this.isSuccess(response)).then(response => {return response.json()})}// 判断请求是否成功static isSuccess(res) {if (res.status >= 200 && res.status < 300) {return res} else {this.requestException(res)}}// 处理异常static requestException(res) {const error = new Error(res.statusText)error.response = resthrow error}// url处理static formatQuery(query) {let params = [];if (query) {for (let item in query) {let vals = query[item];if (vals !== undefined) {params.push(item + '=' + query[item])}}}return params.length ? '?' + params.join('&') : '';}// 处理 get 请求static get(url, data) {return this.request('GET', url, data)}// 处理 put 请求static put(url, data) {return this.request('PUT', url, data)}// 处理 post 请求static post(url, data) {return this.request('POST', url, data)}// 处理 patch 请求static patch(url, data) {return this.request('PATCH', url, data)}// 处理 delete 请求static delete(url, data) {return this.request('DELETE', url, data)}
}

封装完毕后我们在 moduleA.js 中配置一个 github 的开放接口:https://api.github.com/repos/octokit/octokit.rb

/* moduleA.js */
import Http from './http'// 获取测试数据
export const getTestData = () => {return Http.get('https://api.github.com/repos/octokit/octokit.rb')
}

然后在项目页面中进行调用,会成功获取 github 返回的数据,但是一般我们在项目中配置接口的时候会直接省略项目 url 部分,比如:

/* moduleA.js */
import Http from './http'// 获取测试数据
export const getTestData = () => {return Http.get('/repos/octokit/octokit.rb')
}

这时候我们再次调用接口的时候会发现其调用地址为本地地址:http://127.0.0.1:8080/repos/octokit/octokit.rb,这便是CORS(跨域资源共享)问题。那么为了让其指向 https://api.github.com,我们需要在 vue.config.js 中进行 devServer 的配置:

/* vue.config.js */module.exports = {...devServer: {// string | Object 代理设置proxy: {// 接口是 '/repos' 开头的才用代理'/repos': {// 目标API地址,所有匹配 /repos 的请求都会转发到这个地址target: 'https://api.github.com',// 允许跨域changeOrigin: true, // 重新写路径,将 '/api' 前缀去掉,这样,实际请求发送到 https://api.github.com 时不会再包含 /api 前缀pathRewrite: { '^/api': '' }, }},}...
}

在 devServer 中 我们配置 proxy 进行接口的代理,将我们本地地址转换为真实的服务器地址,此时我们同样能顺利的获取到数据,不同点在于接口状态变成了 304(重定向):

 拓展1

 304 状态码

1.304 状态码的含义
  • 304 Not Modified: 这个状态码表示自从上次请求以来,资源没有被修改。服务器会在响应中不返回资源的实体内容,而是告诉客户端使用缓存的版本。

为什么会出现 304 状态码?

当你在开发环境中使用代理设置时,devServer 可能会利用浏览器的缓存机制。以下是一些可能导致出现 304 状态码的原因:

  1. 浏览器缓存: 浏览器会根据 Cache-Control ETag 等 HTTP 头信息来缓存资源。如果你之前请求过某个接口,且没有添加任何请求参数或头信息,浏览器可能会直接从缓存中返回 304 状态。

  2. 代理配置的影响: 如果 proxy 的目标服务器支持缓存,并且根据请求头(如 If-None-Match)返回 304,则会在代理过程中看到这一返回状态。

如何处理 304 状态码?

如果你希望确保始终获取最新的数据,而不是使用缓存,可以考虑以下几种方法:

  1. 禁用缓存: 在请求中添加一些请求头,告知服务器和浏览器不使用缓存。

    axios.get('/api/repos/octokit/octokit.rb', {headers: {'Cache-Control': 'no-cache','Pragma': 'no-cache','Expires': '0'}
    });
  2. 使用唯一的请求参数: 在请求 URL 中添加随机参数或时间戳,以确保请求是唯一的。

    axios.get(`/api/repos/octokit/octokit.rb?timestamp=${new Date().getTime()}`);
  3. 检查服务器响应: 确保你的服务器设置了适当的缓存策略。如果你在开发环境中使用的是某种 API,可以检查其文档,确保它按预期工作。

2.什么是重定向

在 HTTP 协议中,重定向是指服务器向客户端发送一个响应,告知其需要访问其他的 URL。这通常发生在请求的资源位置发生变化、需要进行身份验证、或者为了其他目的引导用户访问不同的页面或接口。

常见的重定向状态码

以下是一些常见的 HTTP 重定向状态码及其含义:

  1. 301 Moved Permanently: 永久重定向,表示请求的资源已被永久移至新位置。客户端应使用新 URL 进行后续请求。

  2. 302 Found: 临时重定向,表示请求的资源临时被移至新位置。客户端仍应使用原 URL 进行后续请求。

  3. 303 See Other: 表示请求的响应可以在另一个 URL 上找到,通常用于 POST 请求之后重定向到 GET 请求。

  4. 307 Temporary Redirect: 临时重定向,表示请求的资源临时移至新位置,客户端应使用新 URL 进行后续请求,但仍应使用原请求方法。

  5. 308 Permanent Redirect: 永久重定向,表示请求的资源已被永久移至新位置,客户端应使用新 URL 进行后续请求,且保留原请求方法。

重定向的工作流程

  1. 客户端发送请求到一个特定的 URL。
  2. 服务器处理请求并返回一个重定向状态码(如 301 或 302),通常附带一个新的 URL。
  3. 客户端接收到响应,并根据新的 URL 再次发送请求。
  4. 服务器响应新的请求,返回最终的资源。

开发中重定向的应用

在前端开发中,重定向常用于以下场景:

  • 用户登录: 在用户成功登录后,将其重定向到首页或仪表板。
  • 资源迁移: 当 API 路径发生变化时,可以通过重定向引导用户使用新的路径。
  • 访问控制: 未经授权的用户访问受保护的资源时,可以重定向到登录页面。

示例:使用 Axios 处理重定向

在前端使用 Axios 进行 HTTP 请求时,如果遇到重定向,Axios 会自动处理这些重定向。以下是一个简单的示例:

import axios from 'axios';axios.get('https://example.com/api/resource').then(response => {console.log('最终响应数据:', response.data);}).catch(error => {console.error('请求出错:', error);});

在这个示例中,如果 https://example.com/api/resource 发生重定向,Axios 会自动跟踪重定向并最终返回最终资源的数据。

4. 公共设施配置

最后我们项目开发中肯定需要对一些公共的方法进行封装使用,这里我把它称之为公共设施,那么我们可以在 src 目录下建一个 common 文件夹来存放其配置文件:

/* index.js */
import Validate from './validate'
import Other from './other'export {Validate,Other,
}

这样我们在页面中只需要引入一个 index.js 即可。

本案例代码地址:single-page-project

拓展2

1.devServer 中 proxy 的 key 值代表什么?如果再添加一个 /reposed 的配置会产生什么隐患?

devServer proxy 配置中,key 值(即配置的 URL 路径)是用来匹配请求的 URL 的前缀。当你的开发服务器收到请求时,它会检查请求的 URL 是否以配置的 key 开头。如果匹配,则会将该请求转发到指定的目标服务器。

例如:

javascript
module.exports = {devServer: {proxy: {'/api': {target: 'http://example.com',changeOrigin: true},'/repos': {target: 'http://another-api.com',changeOrigin: true}}}
};

在这个示例中:

  • 所有以 /api 开头的请求将会被代理到 http://example.com
  • 所有以 /repos 开头的请求将会被代理到 http://another-api.com

添加 /repos 配置的隐患

  1. 冲突: 如果 /repos 与其他 URL 路径重叠,可能会导致请求的目标不明确。例如,如果你有一个 /api/repos 的请求,可能会导致混淆,无法确定请求应该被代理到哪个目标。

  2. 优先级: 在 proxy 的配置中,匹配是基于先出现的规则。如果 /api/repos 都存在,并且请求是 /api/repos,则首先匹配到 /api,而不会转发到 /repos。这可能导致一些意外的行为,尤其是当你希望某些请求到达特定的服务器时。

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

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

相关文章

CocosCreator-引擎案例-TS:spine

工程1&#xff1a;LoadSpine&#xff1a;简单加载spine资源 建立工程&#xff0c;在层级上建立一个空对象&#xff0c;改名spine 在spine上添加spine组件&#xff1a; 添加组件>渲染组件>spine 在spine上挂上脚本loadspine onLoad () {cc.resources.load(loadSpine/ali…

使用FreeNAS软件部署ISCSI的SAN架构存储(IP-SAN)练习题

一&#xff0c;实验用到工具分别为&#xff1a; VMware虚拟机&#xff0c;安装教程&#xff1a;VMware Workstation Pro 17 安装图文教程 FreeNAS系统&#xff0c;安装教程&#xff1a;FreeNAS-11.2-U4.1安装教程2024&#xff08;图文教程&#xff09; 二&#xff0c;新建虚…

【ANGULAR网站开发】初始环境搭建

1. 初始化angular项目 1.1 创建angular项目 需要安装npm和nodejs&#xff0c;这边不在重新安装 直接安装最新版本的angular npm install -g angular/cli安装指定大版本的angular npm install -g angular/cli181.2 启动angular 使用idea启动 控制台启动 ng serve启动成功…

【再谈设计模式】享元模式~对象共享的优化妙手

一、引言 在软件开发过程中&#xff0c;我们常常面临着创建大量细粒度对象的情况&#xff0c;这可能会导致内存占用过高、性能下降等问题。享元模式&#xff08;Flyweight Pattern&#xff09;就像是一位空间管理大师&#xff0c;它能够在不影响功能的前提下&#xff0c;有效地…

Milvus×EasyAi:如何用java从零搭建人脸识别应用

如何从零搭建一个人脸识别应用&#xff1f;不妨试试原生Java人工智能算法&#xff1a;EasyAi Milvus 的组合拳。 本文将使用到的软件和工具包括&#xff1a; EasyAi&#xff1a;人脸特征向量提取Milvus&#xff1a;向量数据库用于高效存储和检索数据。 01. EasyAi&#xff1a;…

NS3学习——tcpVegas算法代码详解(2)

NS3学习——tcpVegas算法代码详解&#xff08;1&#xff09;-CSDN博客 目录 4.TcpVegas类中成员函数 (5) CongestionStateSet函数 (6) IncreaseWindow函数 1.检查是否启用 Vgas 2.判断是否完成了一个“Vegas 周期” 2.1--if&#xff1a;判断RTT样本数量是否足够 2.2--e…

GitLab 将停止为中国区用户提供服务,60天迁移期如何应对? | LeetTalk Daily

“LeetTalk Daily”&#xff0c;每日科技前沿&#xff0c;由LeetTools AI精心筛选&#xff0c;为您带来最新鲜、最具洞察力的科技新闻。 GitLab作为一个广受欢迎的开源代码托管平台&#xff0c;近期宣布将停止服务中国大陆、澳门和香港地区的用户提供服务。根据官方通知&#x…

华为实训课笔记 2024 1223-1224

华为实训 12/2312/24 12/23 [Huawei]stp enable --开启STP display stp brief --查询STP MSTID Port Role STP State Protection 实例ID 端口 端口角色 端口状态 是否开启保护[Huawei]display stp vlan xxxx --查询制定vlan的生成树计算结…

《Java源力物语》-3.空值猎手

~犬&#x1f4f0;余~ “我欲贱而贵&#xff0c;愚而智&#xff0c;贫而富&#xff0c;可乎&#xff1f; 曰&#xff1a;其唯学乎” \quad 夜色渐深&#xff0c;在一处偏僻小径上&#xff0c;月光透过浓密的源力云层&#xff0c;在地面上投下斑驳的光影。String正独自练习着刚从…

科技云报到:人工智能时代“三大件”:生成式AI、数据、云服务

科技云报到原创。 就像自行车、手表和缝纫机是工业时代的“三大件”。生成式AI、数据、云服务正在成为智能时代的“新三大件”。加之全球人工智能新基建加速建设&#xff0c;成为了人类社会数字化迁徙的助推剂&#xff0c;让新三大件之间的耦合越来越紧密。从物理世界到数字世…

hiprint结合vue2项目实现静默打印详细使用步骤

代码地址是&#xff1a;vue-plugin-hiprint: hiprint for Vue2/Vue3 ⚡打印、打印设计、可视化设计器、报表设计、元素编辑、可视化打印编辑 本地安装包地址&#xff1a;electron-hiprint 发行版 - Gitee.com 1、先安装hipint安装包在本地 2、项目运行npm&#xff08;socket.…

CUDA各种内存和使用方法

文章目录 1、全局内存2、局部内存3、共享内存3.1 静态共享内存3.2 动态共享内存 4、纹理内存5、常量内存6、寄存器内存7、用CUDA运行时API函数查询设备CUDA 错误检测 1、全局内存 特点&#xff1a;容量最大&#xff0c;访问延时最大&#xff0c;所有线程都可以访问。 线性内存…

Chapter 03 复合数据类型-1

1.列表 Python内置的一种有序、可变的序列数据类型&#xff1b; 列表的定义&#xff1a; [ ]括起来的逗号分隔的多个元素组成的序列 列表对象的创建&#xff1a; &#xff08;1&#xff09;直接赋值 >>> list1 []#创建一个空列表赋值给list1 >>> list…

【后端】LNMP环境搭建

长期更新各种好文&#xff0c;建议关注收藏&#xff01; 本文近期更新完毕。 LNMPlinuxnginxmysqlphp 需要的资源 linux服务器 web服务软件nginx 对应的语言编译器代码文件 数据库mysql安装 tar.gz包或者命令行安装 进入root&#xff1a; sodu 或su mkdir path/{server,soft}…

基于PyQt5的UI界面开发——多界面切换

介绍 最初&#xff0c;因为课设的缘故&#xff0c;我只是想做一个通过按键进行切面切换而已&#xff0c;但是我看网上资料里面仅是语焉不详&#xff0c;让我困惑的很&#xff0c;但后面我通过摸索才发现这件事实在是太简单了&#xff0c;因此我想要记录下来。 本博客将介绍如…

操作002:HelloWorld

文章目录 操作002&#xff1a;HelloWorld一、目标二、具体操作1、创建Java工程①消息发送端&#xff08;生产者&#xff09;②消息接收端&#xff08;消费者&#xff09;③添加依赖 2、发送消息①Java代码②查看效果 3、接收消息①Java代码②控制台打印③查看后台管理界面 操作…

机器视觉检测相机基础知识 | 颜色 | 光源 | 镜头 | 分辨率 / 精度 / 公差

注&#xff1a;本文为 “keyence 视觉沙龙中机器视觉检测基础知识” 文章合辑。 机器视觉检测基础知识&#xff08;一&#xff09;颜色篇 视觉检测硬件构成的基本部分包括&#xff1a;处理器、相机、镜头、光源。 其中&#xff0c;和光源相关的最重要的两个参数就是光源颜色和…

【体验官招募】SoFlu - JavaAI 开发助手:开启智能开发新时代

你是否有过这样的经历&#xff1f;在深夜的办公室里&#xff0c;面对紧急的 Java 项目&#xff0c;看着厚厚的需求文档&#xff0c;你是否感到无从下手&#xff1f; 当你尝试理解客户那些复杂又模糊的需求时&#xff0c;是否会因为要和产品经理反复沟通确认每一个细节而感到厌…

自学记录HarmonyOS Next DRM API 13:构建安全的数字内容保护系统

在完成了HarmonyOS Camera API的开发之后&#xff0c;我开始关注更复杂的系统级功能。在浏览HarmonyOS Next文档时&#xff0c;我发现了一个非常有趣的领域&#xff1a;数字版权管理&#xff08;DRM&#xff09;。最新的DRM API 13提供了强大的工具&#xff0c;用于保护数字内容…

【HENU】河南大学计院2024 操作系统 简答题复习

和光同尘_我的个人主页 一直游到海水变蓝。 单项选择 15x2 30 判断 10x1 10 简答 3x10 30 综合 3x10 30 简答题 简述操作系统的四个基本特征。 并发性 共享性 虚拟性 异步性 并发性是最重要特性&#xff0c;其它三种特性以此为前提。 并发 并发(Concurrence)&#…