vue3项目实战---知乎日报----项目搭建

2023-11-17

目录

基础框架和响应式布局

项目介绍

接口文档

vue.config

pagejson

初始化公共样式

vuex模块

路由模块

utils公共类库

axios 二次封装

响应式处理 &&  vant ui组件库


基础框架和响应式布局

项目介绍

知乎日报
@1 技术栈:@vue/cli、vue3、vuex4、vue-router4、vant3、axios(qs)...
  + postcss-pxtorem & amfe-flexible 基于这两个模块实现移动端适配
  + less & less-loader
  + babel-plugin-import 实现UI组件库的按需导入

@2 需要完成的页面
  + 首页:新闻列表、头部、轮播图...   /
  + 详情页:文章内容、底部操作栏      /detail/:id
  + 个人中心   /person
  + 收藏列表 /store
  + 登录页面   /login
  + 修改个人信息  /update

@3 开始搭建项目的架子
  + 基于@vue/cli创建项目 & 配置 vue.config.js & 处理浏览器兼容 & 安装需要的模块...
  + 在SRC目录中
    + 配置vuex
    + 配置vue-router
    + 配置api
  + 配置响应式布局方案 & 导入UI组件库
  + 然后一个组件一个组件的去开发即可「规划组件划分」

git地址 知乎icon-default.png?t=M3K6https://gitee.com/childe-jia/backstage.git

接口文档

总述:
POST模式,基于请求主体传递给服务器的数据格式 application/x-www-form-urlencoded 「/user_update接口特殊」
GET模式,基于“问号参数”传递数据

初始账号:珠峰培训  13161883402

服务器返回信息中{返回的数据格式:JSON}
  code :0成功 1失败 
  codeText :对状态码的描述

package.json
  "config": {
    "server": 7100,  //服务器启动WEB服务的端口号
    "secret": "ZFPX", //TOKEN加密秘钥
    "maxAge": "7d"  //TOKEN有效周期(7天)
  }
database存储相关的数据
static存储用户上传的头像

本后台不支持CORS跨域请求,请客户端基于Proxy跨域代理实现

=======================
获取最新新闻  /news_latest  GET
  @params
  @return
	{
		date:'20191204',
		stories:[{
			"image_hue": "0x484825",
			"title": "如何评价 12 月 4 号国行 Switch 发布会?",
			"url": "https:\/\/daily.zhihu.com\/story\/9717893",
			"hint": "WouldYouKindly · 7 分钟阅读",
			"ga_prefix": "120416",
			"images": ["https:\/\/pic2.zhimg.com\/v2-8d47848eb5ea9d747b12eead9dbf4741.jpg"],
			"type": 0,
			"id": 9717893
		},...],
		top_stories:[{
			"image_hue": "0x879943",
			"hint": "作者 \/ 苏澄宇",
			"url": "https:\/\/daily.zhihu.com\/story\/9717531",
			"image": "https:\/\/pic2.zhimg.com\/v2-5c87a645d36d140fa87df6e8ca7cb989.jpg",
			"title": "斑马的条纹到底是干嘛用的?",
			"ga_prefix": "120407",
			"type": 0,
			"id": 9717531
		},...]
	}


获取以往新闻  /news_before  GET
  @params 
	time:20211022  传递今天日期则获取昨日新闻(不传则默认是今天日期)
  @return
	{
		"date": "20191201",
		"stories": [{
			"image_hue": "0xb39f7d",
			"title": "小事 · 芳姐",
			"url": "https:\/\/daily.zhihu.com\/story\/9717813",
			"hint": "VOL.1146",
			"ga_prefix": "120122",
			"images": ["https:\/\/pic1.zhimg.com\/v2-26cbb28e78f2fd51d786d9ef542f9358.jpg"],
			"type": 0,
			"id": 9717813
		},...]
	}


获取新闻详细信息  /news_info  GET
  @params
	id:新闻ID
  @return
	{
		"body": "",
		"image_hue": "0x879943",
		"image_source": "12019 \/ CC0",
		"title": "斑马的条纹到底是干嘛用的?",
		"url": "https:\/\/daily.zhihu.com\/story\/9717531",
		"image": "https:\/\/pic2.zhimg.com\/v2-5c87a645d36d140fa87df6e8ca7cb989.jpg",
		"share_url": "http:\/\/daily.zhihu.com\/story\/9717531",
		"js": [],
		"ga_prefix": "120407",
		"images": ["https:\/\/pic4.zhimg.com\/v2-e5c464d7196a5fa254724cc91c15ca4b.jpg"],
		"type": 0,
		"id": 9717531,
		"css": ["http:\/\/news-at.zhihu.com\/css\/news_qa.auto.css?v=4b3e3"]
	}


获取新闻点赞信息  /story_extra  GET 
  @params
	id:新闻ID
  @return 
    {
		"long_comments": 1,  长评论总数
		"popularity": 183,  点赞总数
		"short_comments": 22,  短评论总数
		"comments": 23 评论总数
	}


用户登录  /login  POST
  @params
	phone:手机号码
	code:短信验证码   用户存在则为登录,不存在则为注册新用户
  @return
	{
		code:0,
       	codeText:'',
       	token:''
	}


获取手机验证码  /phone_code  POST
  @params
	phone:手机号
  @return
    {
		code:0,
       	codeText:''
	}
  临时测试:生成的验证码可在「后端程序 -> code.txt」中查看


=======================
以下接口需要在请求头中携带TOKEN信息
  authorzation:token「客户端登录成功后存储在本地的令牌信息(从服务器获取)」

检测是否登录  /check_login  GET
  @params
  @return
	code 
	codeText
	data:{
		id,
		name,
        phone,
		pic
	}


获取登录者信息  /user_info  GET
  @params 
  @return
	code 
	codeText
	data:{
		id,
		name,
        phone,
		pic
	}


修改用户名和头像  /user_update  POST
  @params  格式:multipart/form-data
	username
	file
  @return
    code 
	codeText
	data:{
		id,
		name,
        phone,
		pic
	}


收藏新闻  /store  POST 
  @params
	newsId:新闻ID
  @return
    code 
	codeText


移除收藏  /store_remove  GET
  @params
	id:收藏ID
  @return
    code 
	codeText


获取登录者收藏列表  /store_list  GET
  @params
  @return
	code 
	codeText
	data:[
		{
			id,
			userId,
			news: {
				id,
				title,
				image
			}
		},...
	]

vue.config

const ENV = process.env.NODE_ENV;
module.exports = {
    lintOnSave: ENV !== 'production',
    publicPath: './',
    productionSourceMap: false,
    devServer: {
        proxy: {
            '/api': {
                target: 'http://127.0.0.1:7100',
                ws: true,
                changeOrigin: true,
                pathRewrite: {
                    '^/api': ''
                }
            }
        }
    }
};

pagejson

{
  "name": "zhihu",
  "version": "0.1.0",
  "private": true,
  "scripts": {
    "serve": "vue-cli-service serve",
    "build": "vue-cli-service build",
    "lint": "vue-cli-service lint"
  },
  "dependencies": {
    "amfe-flexible": "^2.2.1",
    "axios": "^0.23.0",
    "blueimp-md5": "^2.19.0",
    "core-js": "^3.6.5",
    "postcss-pxtorem": "^5.1.1",
    "qs": "^6.10.1",
    "vant": "^3.2.5",
    "vue": "^3.2.26",
    "vue-router": "^4.0.12",
    "vuex": "^4.0.2"
  },
  "devDependencies": {
    "@vue/cli-plugin-babel": "~4.5.0",
    "@vue/cli-plugin-eslint": "~4.5.0",
    "@vue/cli-service": "~4.5.0",
    "@vue/compiler-sfc": "^3.0.0",
    "babel-eslint": "^10.1.0",
    "babel-plugin-import": "^1.13.3",
    "eslint": "^6.7.2",
    "eslint-plugin-vue": "^7.0.0",
    "less": "^3.13.1",
    "less-loader": "^7.3.0"
  },
  "eslintConfig": {
    "root": true,
    "env": {
      "node": true
    },
    "extends": [
      "plugin:vue/vue3-essential",
      "eslint:recommended"
    ],
    "parserOptions": {
      "parser": "babel-eslint"
    },
    "rules": {}
  },
  "browserslist": [
    "> 1%",
    "last 2 versions",
    "not dead"
  ]
}

初始化公共样式

body,h1,h2,h3,h4,h5,h6,hr,p,blockquote,dl,dt,dd,ul,ol,li,button,input,textarea,th,td{margin:0;padding:0}body{font-size:12px;font-style:normal;font-family:"\5FAE\8F6F\96C5\9ED1",Helvetica,sans-serif}small{font-size:12px}h1{font-size:18px}h2{font-size:16px}h3{font-size:14px}h4,h5,h6{font-size:100%}ul,ol{list-style:none}a{text-decoration:none;background-color:transparent}a:hover,a:active{outline-width:0;text-decoration:none}table{border-collapse:collapse;border-spacing:0}hr{border:0;height:1px}img{border-style:none}img:not([src]){display:none}svg:not(:root){overflow:hidden}html{-webkit-touch-callout:none;-webkit-text-size-adjust:100%}input,textarea,button,a{-webkit-tap-highlight-color:rgba(0,0,0,0)}article,aside,details,figcaption,figure,footer,header,main,menu,nav,section,summary{display:block}audio,canvas,progress,video{display:inline-block}audio:not([controls]),video:not([controls]){display:none;height:0}progress{vertical-align:baseline}mark{background-color:#ff0;color:#000}sub,sup{position:relative;font-size:75%;line-height:0;vertical-align:baseline}sub{bottom:-0.25em}sup{top:-0.5em}button,input,select,textarea{font-size:100%;outline:0}button,input{overflow:visible}button,select{text-transform:none}textarea{overflow:auto}button,html [type="button"],[type="reset"],[type="submit"]{-webkit-appearance:button}button::-moz-focus-inner,[type="button"]::-moz-focus-inner,[type="reset"]::-moz-focus-inner,[type="submit"]::-moz-focus-inner{border-style:none;padding:0}button:-moz-focusring,[type="button"]:-moz-focusring,[type="reset"]:-moz-focusring,[type="submit"]:-moz-focusring{outline:1px dotted ButtonText}[type="checkbox"],[type="radio"]{box-sizing:border-box;padding:0}[type="number"]::-webkit-inner-spin-button,[type="number"]::-webkit-outer-spin-button{height:auto}[type="search"]{-webkit-appearance:textfield;outline-offset:-2px}[type="search"]::-webkit-search-cancel-button,[type="search"]::-webkit-search-decoration{-webkit-appearance:none}::-webkit-input-placeholder{color:inherit;opacity:.54}::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}.clearfix:after{display:block;height:0;content:"";clear:both}

vuex模块

vuex解构函数 createStore  创建store 

main.js注册使用 app.use(store)

组件使用 vuex解构函数 useStore 创建store 只能通过 store.state.xxx store.commit/displach,派发任务,不能使用辅助函数

import { createStore } from "vuex";
const store = createStore({
    state: {},
    mutations: {},
    actions: {},
})
export default store 
--------------------------------mian.js
import { createApp } from 'vue'
import App from './App.vue'
import store from '../src/store/index'

const app = createApp(App)
app.use(store)
app.mount('#app')

--------------------------------组件
<script>
import { useStore } from "vuex";
export default {

  name: 'App',
  components: {},
  setup() {
    const store = useStore()
    console.log(store);
  },

}

路由模块

  • route 路由信息对象:path params(路径参数) hash query name
  • router是路由实例 路径的跳转方式(push require)
  • 必须指定路由模式  history: createWebHashHistory(),
  •  //createWebHistory-->History路由 createWebHashHistory-->HASH路由
  • main.js注册使用 app.use(router)
  • 组件使用路由从  vue-router 解构 useRoute, useRouter
  • 路由匹配后,放到 路由容器中<router-view></router-view>
---------------------路由信息
import Home from '@/views/Home.vue';

const routes = [{
    path: '/',
    name: 'Home',
    meta: { title: '知乎日报' },
    component: Home
}, {
    path: '/detail/:id',
    name: 'Detail',
    meta: { title: '文章详情' },
    component: () => import(/* webpackChunkName: "other" */'@/views/Detail.vue')
}, {
    path: '/person',
    name: 'Person',
    meta: { title: '个人中心' },
    component: () => import(/* webpackChunkName: "other" */'@/views/Person.vue')
}, {
    path: '/store',
    name: 'Store',
    meta: { title: '收藏列表' },
    component: () => import(/* webpackChunkName: "other" */'@/views/Store.vue')
}, {
    path: '/update',
    name: 'Update',
    meta: { title: '编辑个人信息' },
    component: () => import(/* webpackChunkName: "other" */'@/views/Update.vue')
}, {
    path: '/login',
    name: 'Login',
    meta: { title: '用户登录' },
    component: () => import(/* webpackChunkName: "other" */'@/views/Login.vue')
}, {
    path: '/:pathMatch(.*)',
    redirect: '/'
}];

export default routes;


--------------------------路由实例对象
import { createRouter, createWebHashHistory, } from "vue-router";
import routes from './routes';
const router = createRouter({
    //createWebHistory-->History路由 createWebHashHistory-->HASH路由
    //基于Hash指定模式
    history: createWebHashHistory(),
    routes,
})
export default router

---------------------mian.js
import { createApp } from 'vue'
import App from './App.vue'
import store from '../src/store/index'
import router from './router';
const app = createApp(App)

app.use(store)
app.use(router)

app.mount('#app')

---------------------app.vue
<template>

  <router-view></router-view>

</template>

<script>
import { useRoute, useRouter } from "vue-router";
export default {

  name: 'App',
  components: {},
  setup() {
    const route = useRoute()
    const router = useRouter()
    console.log(router, route);
  },

}
</script>

utils公共类库

// 检测是否为纯粹的对象
export const isPlainObject = function isPlainObject(obj) {
    let proto, Ctor;
    if (!obj || Object.prototype.toString.call(obj) !== "[object Object]") return false;
    proto = Object.getPrototypeOf(obj);
    if (!proto) return true;
    Ctor = proto.hasOwnProperty('constructor') && proto.constructor;
    return typeof Ctor === "function" && Ctor === Object;
};

// 处理最大宽度
export const handleMaxWidth = function handleMaxWidth() {
    let HTML = document.documentElement,
        app = document.querySelector('#app'),
        size = parseFloat(HTML.style.fontSize);
    if (size > 75) {
        HTML.style.fontSize = '75px';
        app.style.width = '750px';
        return;
    }
    app.style.width = '100%';
    app.style.minHeight = HTML.clientHeight + 'px';
};

// 日期格式化
export const formatTime = function formatTime(time, template) {
    if (typeof time !== "string") {
        time = new Date().toLocaleString('zh-CN', { hour12: false });
    }
    if (typeof template !== "string") {
        template = "{0}年{1}月{2}日 {3}:{4}:{5}";
    }
    let arr = [];
    if (/^\d{8}$/.test(time)) {
        let [, $1, $2, $3] = /^(\d{4})(\d{2})(\d{2})$/.exec(time);
        arr.push($1, $2, $3);
    } else {
        arr = time.match(/\d+/g);
    }
    return template.replace(/\{(\d+)\}/g, (_, $1) => {
        let item = arr[$1] || "00";
        if (item.length < 2) item = "0" + item;
        return item;
    });
};

axios 二次封装

  • axios.defaults.timeout 超时时间
  • axios.defaults.transformRequest  post请求统一处理 为问号查询字符串格式。不写默认为json
  • axios.interceptors.request.use请求拦截
  • axios.interceptors.response.use 响应拦截
import axios from "axios";
import qs from 'qs';
import { isPlainObject } from '@/assets/utils';
import { Notify } from 'vant';
// 将自动加在 `url` 前面,除非 `url` 是一个绝对 URL。它可以通过设置一个 `baseURL` 
axios.defaults.baseURL = '';
// 指定请求超时的毫秒数(0 表示无超时时间)
axios.defaults.timeout = 60000;
//允许在向服务器发送前,修改请求数据. 只能用在 'PUT', 'POST' 和 'PATCH' 这几个请求方法
axios.defaults.transformRequest = data => {
    if (isPlainObject(data)) return qs.stringify(data);
    return data;
};
//在请求或响应被 then 或 catch 处理前拦截它们。添加请求拦截器
axios.interceptors.request.use(config => {
    return config;
});
// 添加响应拦截器
axios.interceptors.response.use(response => {
    return response.data;
}, reason => {
    Notify({
        type: 'danger',
        message: '小主,当前网络繁忙,请稍后再试!'
    });
    return Promise.reject(reason);
});
export default axios;

响应式处理 &&  vant ui组件库

vant ui组件库

import { createApp } from 'vue'
import Vant from 'vant';
import 'vant/lib/index.css';
import App from './App.vue'
import store from '../src/store/index'
import router from './router';


const app = createApp(App)

app.use(store)
app.use(router)
app.use(Vant)

app.mount('#app')

底部安全区适配

  <meta name="viewport"
    content="width=device-width, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0, user-scalable=no, viewport-fit=cover">

Rem 布局适配

  • postcss-pxtorem 是一款 PostCSS 插件,用于将 px 单位转化为 rem 单位
  • amfe-flexible设置根元素字体大小

  • main.js 导入import 'amfe-flexible'(按照设备的宽度/10)

  • 在根目录下创建// postcss.config.js 对其进行配置

module.exports = {
    plugins: {
        'postcss-pxtorem': {
            rootValue: 37.5,
            propList: ['*'],
        },
    },
};

原理

  • vant 组件库本身就是以375的设计稿设计的(单位都为px)
  • amfe-flexible 使用单位会根据375的设计稿 把html的font-size值设置为37.5
  • 我们的目的是把px都转为rem  postcss-pxtorem处理这件事

如果设计稿的尺寸不是 375,而是 750 或其他大小,可以将 rootValue 配置调整为:

判断是否为vant组件库 是为375 不是则为设计稿大小

// postcss.config.js
module.exports = {
  plugins: {
    // postcss-pxtorem 插件的版本需要 >= 5.0.0
    'postcss-pxtorem': {
      rootValue({ file }) {
        return file.indexOf('vant') !== -1 ? 37.5 : 75;
      },
      propList: ['*'],
    },
  },
};

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

vue3项目实战---知乎日报----项目搭建 的相关文章

  • 如何在 React 中构建自动完成组件

    介绍 自动完成是一种输入字段根据用户输入建议单词的功能 这有助于改善应用程序中的用户体验 例如需要搜索的情况 在本文中 您将研究如何在 React 中构建自动完成组件 您将使用固定的建议列表 事件绑定 理解键盘代码以及操作状态管理 先决条件
  • 如何使用 Nmap 扫描开放端口

    介绍 对于许多崭露头角的系统管理员来说 网络是一个广泛且令人难以承受的主题 有各种层 协议和接口 以及许多必须掌握才能理解它们的工具和实用程序 在 TCP IP 和 UDP 网络中 ports是逻辑通信的端点 单个 IP 地址可能运行许多服
  • 如何设置 Jupyter Notebook 在 Ubuntu 16.04 上运行 IPython

    介绍 IPython 是 Python 的交互式命令行界面 Jupyter Notebook 为多种语言提供了交互式 Web 界面 包括 IPython 本文将引导您设置服务器来运行 Jupyter Notebook 并教您如何连接和使用该
  • Java 中的 Restful Web 服务教程

    欢迎来到 Java 中的 Restful Web 服务教程 REST是缩写代表性状态转移 休息是一个建筑风格用于开发可通过网络访问的应用程序 Roy Fielding 在 2000 年的博士论文中提出了 REST 架构风格 宁静的网络服务

随机推荐

  • 如何在 Ubuntu 18.04 上安装和保护 Grafana

    笔者精选 dev 颜色接受捐赠作为为捐款而写程序 介绍 Grafana是一个开源数据可视化和监控工具 集成了来自以下来源的复杂数据普罗米修斯 InfluxDB Graphite and 弹性搜索 Grafana 允许您为数据创建警报 通知和
  • Mockito 模拟静态方法 - PowerMock

    Mockito 允许我们创建模拟对象 由于静态方法属于类 因此 Mockito 中无法模拟静态方法 但是 我们可以使用 PowerMock 和 Mockito 框架来模拟静态方法 使用 PowerMock 的 Mockito 模拟静态方法
  • 如何在 Ubuntu 22.04 上使用 Nginx-RTMP 设置视频流服务器

    介绍 流媒体视频有很多用例 服务提供商如Twitch在处理流媒体的网络发现和社区管理方面非常受欢迎 并且免费软件 例如OBS工作室广泛用于实时组合来自多个不同流源的视频叠加 虽然这些平台非常强大 但在某些情况下 您可能希望能够托管不依赖其他
  • 如何在 Debian 11 上安装 MariaDB

    介绍 MariaDB是一个开源关系数据库管理系统 通常用作 MySQL 的替代品 作为流行的数据库部分LAMP Linux Apache MySQL PHP Python Perl 堆栈 它旨在成为 MySQL 的直接替代品 本安装指南的简
  • 如何在 Ubuntu 18.04 上使用 LEMP 安装 WordPress

    介绍 WordPress 是互联网上最流行的 CMS 内容管理系统 它允许您在具有 PHP 处理功能的 MySQL 后端上轻松设置灵活的博客和网站 WordPress 得到了令人难以置信的采用 是快速启动和运行网站的绝佳选择 设置完成后 几
  • 从 Python 列表中获取唯一值

    在这篇文章中 我们将了解从 Python 列表中获取唯一值的 3 种方法 在处理大量原始数据时 我们经常遇到需要从原始输入数据集中提取唯一且不重复的数据集的情况 下面列出的方法将帮助您解决这个问题 让我们开始吧 在 Python 中从列表中
  • 如何在 Ubuntu 14.04 上安装 MySQL

    介绍 MySQL是一个开源数据库管理系统 通常作为流行的一部分安装LAMP Linux Apache MySQL PHP Python Perl 堆栈 它使用关系数据库和 SQL 结构化查询语言 来管理其数据 简短版本的安装很简单 更新您的
  • 如何在 Ubuntu 12.04 上设置 vsftpd

    Status 已弃用 本文介绍不再受支持的 Ubuntu 版本 如果您当前运行的服务器运行 Ubuntu 12 04 我们强烈建议您升级或迁移到受支持的 Ubuntu 版本 升级到Ubuntu 14 04 从 Ubuntu 14 04 升级
  • 图像处理第 5 部分:算术、按位和掩码

    在图像处理系列的第五部分中 我们将详细讨论 Python 中的算术和位运算以及图像掩码 建议以前的文章在开始您的蒙面学习冒险之前 请先完成一遍 设置环境 以下代码行用于下面给出的所有应用程序 我们将把它们包含在这里 这样您就不必阅读大量代码
  • 计算机网络(五)传输层详解

    目录 第五章 传输层 5 1 传输层概述 进程之间的通信 网络层与传输层的区别 传输层的两个主要协议 传输层的端口 TCP IP传输层端口 5 2 UDP UDP需要实现的功能 UDP提供的服务 UDP适合哪些应用 UDP协议的特点 UDP
  • 华为OD机试真题(Java),吃到最多的刚好合适的菜(100%通过+复盘思路)

    一 题目描述 入职后 导师会请你吃饭 你选择了火锅 火锅里会在不同时间下很多菜 不同食材要煮不同的时间 才能变得刚好合适 你希望吃到最多的刚好合适的菜 但你的手速不够快 用m代表手速 每次下手捞菜后至少要过m庙才能在捞 每次只能捞一个 那么
  • umijs + dva + request + js-cookie实现登录

    umijs dva umi request js cookie实现登录 一 在src下创建models文件夹 创建user ts 二 在pages下创建login文件下 组件使用函数创建 三 创建cookie管理文件 和request ts
  • 阿里云dataworks就是个半成品!

    用hadoop EMR 不要用dataworks 不要用dataworks 不要用dataworks 重要的事情说三遍 各种莫名其妙的坑 ip黑盒 工程师无法干涉 傻瓜式无限的提交 发布 点来点去浪费时间 各种bug fuxi错误 完全没有
  • (2023,网络修剪)探索 few-shot 图像生成中的不相容知识迁移

    Exploring Incompatible Knowledge Transfer in Few shot Image Generation 公众号 EDPJ 目录 0 摘要 1 简介 2 相关工作 3 基础 4 FSIG 中不兼容的知识转
  • Mac之zip unzip 命令(压缩)

    https blog csdn net yxys01 article details 73848720 最通俗的用法 zip q r e m o myfile zip someThing 1 q 表示不显示压缩进度状态 r 表示子目录子文件
  • 记录自己开发入职第一天需要干的事情

    拉取代码前的准备工作 安装JDK 数据库本地可视化客户端 如Navicat SQLyog DBeaver Workbench Windows连接linux终端工具 Xshell SecureCRT Putty 下载IDEA 配置IDEA开发
  • adb shell 获取手机分辨率

    使用adb修改屏幕像素密度 此命令针对全志开发板子 adb shell am display density 120 以下命令针对高通的开发板子 获取Android设备屏幕分辨率 adb shell wm size获取android设备屏幕
  • Tomcat简介及优化思路

    Tomcat 处理请求大致流程和架构 请求流程 1 HTTP服务器会把请求信息使 ServletRequest对象封装起来 2 进 步去调 Servlet容器中某个具体的Servlet 3 在 2中 Servlet容器拿到请求后 根据URL
  • 超分辨率重建测试(DASR)

    测试链接 GitHub LongguangWang DASR CVPR 2021 Unsupervised Degradation Representation Learning for Blind Super Resolutionhttp
  • vue3项目实战---知乎日报----项目搭建

    目录 基础框架和响应式布局 项目介绍 接口文档 vue config pagejson 初始化公共样式 vuex模块 路由模块 utils公共类库 axios 二次封装 响应式处理 vant ui组件库 基础框架和响应式布局 项目介绍 知乎