aurora-article's People
aurora-article's Issues
2020-10-11 日常笔记
感觉 typecho 自带的 /admin 后台地址不是太安全,所以更换了 typecho 后台地址。Vue 过渡 & 动画,Vue 混入的使用及简单例子。
更换typecho后台地址
默认的typecho后台地址是admin,一般是一定要换掉默认的后台地址,可以让自己的网站更加安全。
更换后台地址非常简单,一共两步
第一步:更改网站根目录的admin目录名,换成你的后台地址,如qwe123456789
第二步:修改网站根目录下的config.inc.php配置文件,将
/** 后台路径(相对路径) */
define('__TYPECHO_ADMIN_DIR__', '/admin/');
代码中的 /admin/ 更改为 /定义的后台地址/ , 如*/qwe123456789/*
然后访问 域名/qwe123456789/ 就是的后台地址了。
Vue过渡&动画
进入和离开的过渡
过渡的类名
- v-enter 定义进入过渡的开始状态.
- v-enter-active 定义进入过渡生效时的状态。
- v-enter-to 定义进入过渡的结束状态。
- v-leave 定义离开过渡的开始状态。
- v-leave-active 定义离开过渡生效时的状态。
- v-leave-to 定义离开过渡的结束状态。
其中 v-enter v-enter-active v-leave-active v-leave-to 比较常用
css 过渡
<style>
.fade-enter-active, .fade-leave-active {
transition: opacity .5s;
}
.fade-enter, .fade-leave-to {
opacity: 0;
}
</style>
<div id="app">
<button @click="show = !show">按钮</button>
<transition name="fade">
<p v-if="show">一段文字</p>
</transition>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
const app = new Vue({
el:'#app',
data(){
return{
show:true
}
}
})
</script>
css 动画
更改下css样式即可
.fade-enter-active{
animation: fade-in .5s;
}
.fade-leave-active{
animation: fade-in 5s reverse;
}
@keyframes fade-in {
0% {
opacity: 0;
}
100% {
opacity: 1;
}
}
自定义过渡类名结合animate动画库
<transition
name="fade"
enter-active-class="animated fadeInUp"
leave-active-class="animated fadeInDown"
>
<p v-if="show" style="color:red;text-align: center;">一段文字</p>
</transition>
JavaScript 钩子
允许使用的javascript钩子
<transition
v-on:before-enter="beforeEnter"
v-on:enter="enter"
v-on:after-enter="afterEnter"
v-on:enter-cancelled="enterCancelled"
v-on:before-leave="beforeLeave"
v-on:leave="leave"
v-on:after-leave="afterLeave"
v-on:leave-cancelled="leaveCancelled"
>
<!-- ... -->
</transition>
注意事项
当只用 JavaScript 过渡的时候,在 enter 和 leave 中必须使用 done 进行回调。否则,它们将被同步调用,过渡会立即完成。
推荐对于仅使用 JavaScript 过渡的元素添加 v-bind:css="false",Vue 会跳过 CSS 的检测。这也可以避免过渡过程中 CSS 的影响。
<div id="app">
<button @click="show = !show">按钮</button>
<transition
v-on:before-enter="beforeEnter"
v-on:enter="enter"
v-on:leave="leave"
v-bind:css="false"
>
<p v-if="show" style="color:red;text-align: center;">一段文字</p>
</transition>
</div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/velocity/1.2.3/velocity.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
const app = new Vue({
el:'#app',
data(){
return{
show:true
}
},
methods:{
beforeEnter: function (el) {
el.style.opacity = 0
el.style.transformOrigin = 'left'
},
enter: function (el, done) {
Velocity(el, { opacity: 1, fontSize: '1.4em' }, { duration: 300 })
Velocity(el, { fontSize: '1em' }, { complete: done })
},
leave: function (el, done) {
Velocity(el, { translateX: '15px', rotateZ: '50deg' }, { duration: 600 })
Velocity(el, { rotateZ: '100deg' }, { loop: 2 })
Velocity(el, {
rotateZ: '45deg',
translateY: '30px',
translateX: '30px',
opacity: 0
}, { complete: done })
}
}
})
</script>
初始渲染的过渡
官方没有说太多,只是一个初始渲染
.custom-appear-active-class{
transition: all 2s;
}
.custom-appear-class{
opacity: 0;
transform: translate(100px);
}
<transition
appear
appear-class="custom-appear-class"
appear-to-class="custom-appear-to-class"
appear-active-class="custom-appear-active-class animated fadeIn"
>
<p>一段文字</p>
</transition>
多个元素之间的过渡,如果是相同的元素,需要加上 key 属性
<transition name="fade" mode="out-in">
<button v-if="show" @click="show = !show" key="p1">一段文字</button>
<button v-else @click="show = !show" key="p2">另一段文字</button>
</transition>
过渡模式
默认的过的模式时进入和离开同时进行
可以通过修改mode更改过渡模式,可选的过的模式有
in-out:新元素先进行过渡,完成之后当前元素过渡离开。
out-in:当前元素先进行过渡,完成之后新元素过渡进入。
一般in-out比较少用
多个组件的过渡
多个组件的过渡可以使用动态组件
<div id="app">
<input type="radio" v-model="view" value="a-component">A
<input type="radio" v-model="view" value="b-component">B
<transition name="fade" mode="out-in">
<component :is="view"></component>
</transition>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
const AComponent = {
template:`
<p>我是A组件</p>
`
}
const BComponent = {
template:`
<p>我是B组件</p>
`
}
const app = new Vue({
el:'#app',
data(){
return{
view:'a-component'
}
},
components:{
AComponent,
BComponent
}
})
</script>
列表过渡
一个简单的例子
<style>
.list-item {
transition: all 1s;
display: inline-block;
margin-right: 10px;
}
.list-enter, .list-leave-to {
opacity: 0;
transform: translateY(30px);
}
.list-leave-active {
position: absolute;
}
</style>
<div id="app">
<button @click="addNum">添加</button>
<button @click="delNum">删除</button>
<button @click="shuffleNum">重新排序</button>
<transition-group name="list" tag="ul">
<li class="list-item" v-for="item in list" :key="item">{{item}}</li>
</transition-group>
</div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.14.1/lodash.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
const app = new Vue({
el:'#app',
data(){
return {
list:[1,2,3,4,5,6,7,8,9],
nextNum:10
}
},
methods:{
randomNum(){
return _.random(0, this.list.length - 1);
},
addNum(){
this.list.splice(this.randomNum(),0,this.nextNum++)
},
delNum(){
this.list.splice(this.randomNum(),1)
},
shuffleNum(){
this.list = _.shuffle(this.list)
}
}
})
</script>
可复用的过渡
Vue.component('my-special-transition',{
methods:{
beforeEnter: function (el) {
el.style.opacity = 0
},
enter: function (el, done) {
Velocity(el, { opacity: 1, translateX: 100 }, { duration: 300 })
Velocity(el, { translateX: 0 }, { duration: 2000, complete: done })
},
leave: function (el, done) {
Velocity(el, { opacity: 0}, { duration: 300,complete: done })
}
},
template:`
<transition
mode="out-in"
@before-enter="beforeEnter"
@enter="enter"
@leave="leave"
:css="false"
>
<slot></slot>
</transition>
`
})
函数式组件形式,看起来更加整洁
Vue.component('my-special-transition',{
functional: true,
render(h,c){
var data = {
props: {
mode: 'out-in',
css:false
},
on: {
beforeEnter: function (el) {
el.style.opacity = 0
},
enter: function (el, done) {
Velocity(el, { opacity: 1, translateX: 100 }, { duration: 300 })
Velocity(el, { translateX: 0 }, { duration: 2000, complete: done })
},
leave: function (el, done) {
Velocity(el, { opacity: 0}, { duration: 300,complete: done })
}
}
}
return h('transition', data, c.children)
}
})
我的观点
通常情况单个元素还是使用更改class的方式定义动画比较方便。
<style>
.text{
transition: all .5s;
opacity: 0;
}
.text.active{
opacity:1
}
</style>
<div id="app">
<button @click="show = !show">按钮</button>
<p class="text" :class="{active : show}">一段文字</p>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
const app = new Vue({
el:'#app',
data(){
return {
show:false
}
}
})
</script>
多个元素和组件之间的过渡建议使用Vue过渡。
和Vue搭配的动画库大多是外过的如animate和Velocity.js,国内虽然有翻译,但由于版本的更新,翻译的不是很及时,比如Velocity.js最后一次更新在2017年。
Vue混入
简单的例子
<div id="app">
<a-component></a-component>
<hr>
<b-component></b-component>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
const MixinA = {
data(){
return{
list:[1,2,3,4,5,6,7,8,9],
nextNumber:10
}
},
methods:{
randomIndex(){
return Math.floor(Math.random() * this.list.length)
}
}
}
const AComponent = {
name:'AComponent',
mixins:[MixinA],
methods:{
deleteNumber(){
this.list.splice(this.randomIndex(),1)
}
},
template:`
<div>
<button @click="deleteNumber">删除</button>
<ul>
<li v-for="item in list" :key="item">{{item}}</li>
</ul>
</div>
`
}
const BComponent = {
name:'BComponent',
mixins:[MixinA],
methods:{
addNumber(){
this.list.splice(this.randomIndex(),0,this.nextNumber++)
}
},
template:`
<div>
<button @click="addNumber">添加</button>
<ul>
<li v-for="item in list" :key="item">{{item}}</li>
</ul>
</div>
`
}
const app = new Vue({
el:'#app',
components:{
AComponent,
BComponent
}
})
</script>
混入中的data数据在不同组件中不共享,如果要实现数据共享,可以使用vuex
选项合并
数据对象在内部会进行递归合并,并在发生冲突时以组件数据优先。
同名钩子函数将合并为一个数组,因此都将被调用。
methods、components 和 directives,将被合并为同一个对象。两个对象键名冲突时,取组件对象的键值对。
leancloud 学习
leancloud 后端云服务,其中有数据存储、云引擎、即时通讯服务等。不过这些都不重要,数据存储有3万一天的请求次数,可以存一些简单的数据。原文时间:2020-10-27 15:30
建议使用国际版,不用备案,一天3万次请求,对于练习(薅羊毛)来说足够了→_→ 。
#安装JavaScript SDK
npm install leancloud-storage --save
#初始化
import Vue from 'vue'
import AV from 'leancloud-storage'
AV.init({
appId: `应用的appId`,
appKey: `应用的appKey`
})
Vue.prototype.$av = AV
调用时直接this.$av即可
存个数据
async saveData() {
// 声明 class
const todo = this.$av.Object(`Todo`)
//添加字段
todo.set(`title`, `马拉松报名`)
todo.set(`priority`, 2)
//保存
await todo.save().then(data => {
console.log(data)
})
}
根据objectId获取数据
async getDataByObjectId() {
const objectId = `5f97cedbd47c5a4bea913ebc`
const query = new this.$av.Query(`Todo`)
await query.get(objectId).then(data => {
console.log(data.toJSON())
})
}
根据objectId更新数据
updateByObjectId() {
const objectId = `5f97cedbd47c5a4bea913ebc`
const todo = this.$av.Object.createWithoutData(`Todo`, objectId)
todo.set(`title`, `这周周会改到周三下午三点。`)
todo.save()
}
根据objectId删除数据
delByObjectId() {
const objectId = `5f97cedbd47c5a4bea913ebc`
const todo = this.$av.Object.createWithoutData(`Todo`, objectId)
todo.destroy()
}
批量添加
saveAllData() {
const todos = []
for (let i = 0 ; i < 50 ; i++) {
const todo = this.$av.Object(`Todo`)
todo.set(`title`, `标题${i + 1}`)
todo.set(`click`, i + 1)
todos.push(todo)
}
this.$av.Object.saveAll(todos)
}
git报错22: Connection timed out
2020-10-13 日常笔记
Vue Router,vue 官方推荐的路由,包括路由组件传参、路由守卫、路由元信息、路由过渡的总结,大多数都是搬运的官方的例子。
#Vue Router
路由组件传参
在组件中使用 $route 会使之与其对应路由形成高度耦合,从而使组件只能在某些特定的 URL 上使用,限制了其灵活性。
可以使用 props 将组件和路由解耦
const User = {
props:{
id:{
type:String,
required:true
}
},
template: '<div>User {{id}}</div>'
}
const routes = [
{ path: '/user/:id', component: User ,props:true},
// 对于包含命名视图的路由,你必须分别为每个命名视图添加 `props` 选项:
{
path: '/user/:id',
components: { default: User, sidebar: Sidebar },
props: { default: true, sidebar: false }
}
]
布尔模式
如果 props 被设置为 true,route.params 将会被设置为组件属性。
对象模式
props为对象会按原样设置为组件属性,当props为静态时比较有用
函数模式
布尔模式只会获得params属性,不可以获取route其他的属性,如query,使用函数模式可以解决这个问题。
{ path: '/user/:id', component: User ,props:route=>({query:route.query,id:route.params.id})}
导航守卫
参数或查询的改变并不会触发进入/离开的导航守卫。
想要监听参数或查询的改变需要可以通过观察 $route 对象来应对这些变化,或使用 beforeRouteUpdate 的组件内守卫。
全局前置守卫
next():进行管道中的下一个钩子。如果全部钩子执行完了,则导航的状态就是 confirmed (确认的)。
next(false):表示中断当前的导航
next('/')或next({ path: '/' }):表示跳转到一个地址
//全局前置守卫
router.beforeEach((to, from, next) => {
console.log(to,from)
//如果用户的id为4,跳转到id为1的用户
if(to.params.id === '4'){
next({name:'user',params:{id:'1'}})
}else{
next()
}
})
全局后置钩子
router.afterEach((to, from) => {
// ...
})
路由独享的守卫
在routes中有可选的beforeEnter,可以直接定义
const routes = [
{ path: '/user/:id',name:'user', component: User ,props:route=>({query:route.query,id:route.params.id}),
beforeEnter:(to,from ,next)=>{
console.log('路由独享守卫')
next()
}
}
]
路由独享守卫也不会因为参数或查询的改变而触发。
路由组件内的守卫
beforeRouteEnter (to, from, next) {
console.log('beforeRouteEnter')
next()
// 在渲染该组件的对应路由被 confirm 前调用
// 不!能!获取组件实例 `this`
// 因为当守卫执行前,组件实例还没被创建
},
beforeRouteUpdate (to, from, next) {
console.log('beforeRouteUpdate')
next()
// 在当前路由改变,但是该组件被复用时调用
// 举例来说,对于一个带有动态参数的路径 /foo/:id,在 /foo/1 和 /foo/2 之间跳转的时候,
// 由于会渲染同样的 Foo 组件,因此组件实例会被复用。而这个钩子就会在这个情况下被调用。
// 可以访问组件实例 `this`
},
beforeRouteLeave (to, from, next) {
console.log('beforeRouteLeave')
next()
// 导航离开该组件的对应路由时调用
// 可以访问组件实例 `this`
},
其中beforeRouteEnter 不能通过this访问组件实例,不过可以给next传递一个回调函数获取组件实例
beforeRouteEnter (to, from, next) {
next(vm => {
// 通过 `vm` 访问组件实例
})
}
beforeRouteEnter 是支持给 next 传递回调的唯一守卫。
路由元信息
定义路由的时候可以配置 meta 字段
{
path: '/foo',
component: Foo,
children: [
{
path: 'bar',
component: Bar,
// a meta field
meta: { requiresAuth: true }
}
]
}
过渡动效
是基本的动态组件,所以我们可以用 组件给它添加一些过渡效果
参数或查询的改变并不会触发过渡,组件的切换才会进行过渡。
数据获取
导航完成之后获取:先完成导航,然后在接下来的组件生命周期钩子中获取数据。在数据获取期间显示“加载中”之类的指示。
导航完成之前获取:导航完成前,在路由进入的守卫中获取数据,在数据获取成功后执行导航。
两种方式都可以。
const GoodsContent = {
data(){
return {
swiper:null
}
},
//导航完成前获取数据
// beforeRouteEnter (to, from, next) {
// next(vm=>{
// vm.fetchData(to.params.id).then(response=>{
// vm.swiper = response.data.message
// })
// })
// },
// beforeRouteUpdate (to, from, next) {
// this.swiper = null
// this.fetchData(to.params.id).then(response=>{
// this.swiper = response.data.message
// next()
// console.log(response.data.message.goods_name);
// })
// },
//导航完成后获取数据
watch:{
$route:{
handler(val){
this.swiper = null
console.log(val.params);
this.fetchData(val.params.id).then(response=>{
this.swiper = response.data.message
console.log(response.data.message.goods_name);
})
},
immediate:true
}
},
methods:{
fetchData(goods_id){
return axios.get('后台地址?goods_id='+goods_id)
}
},
template:`<div>
<div v-if="swiper">
{{swiper.goods_name}}
</div>
<div v-else>
Loading...
</div>
</div>`
}
ECharts 简单上手
echarts📊,在使用 echarts 时,理解概念时非常重要的。这也是为什么在官方教程中,没有举出很多例子,而是主讲概念。原文时间:2020-10-17 23:26
上手
在使用echarts时,理解概念时非常重要的。
这也是为什么在官方教程中,没有举出很多例子,而是主讲概念。
简单例子
<template>
<div
ref="main"
style="width: 600px;height: 400px;"
/>
</template>
<script>
import echarts from 'echarts'
export default {
mounted() {
const option = {
title: {
text: `ECharts 入门示例`
},
tooltip: {},
legend: {
data: [`销量`]
},
xAxis: {
data: [`衬衫`, `羊毛衫`, `雪纺衫`, `裤子`, `高跟鞋`, `袜子`]
},
yAxis: {},
series: [
{
name: `销量`,
type: `bar`,
data: [5, 20, 36, 10, 10, 20]
}
]
}
echarts.init(this.$refs.main).setOption(option)
}
}
</script>
基础概念
一个网页中可以创建多个 echarts 实例。每个 echarts 实例 中可以创建多个图表和坐标系等等(用 option 来描述)。
系列
一组数值以及他们映射成的图。
const dataset = {
xAxis: {
type: `category`
},
yAxis: {},
dataset: {
source: [
[`一月`, 23, 12, `XX`],
[`二月`, 12, 23, `YY`],
[`三月`, 63, 4, `ZZ`],
[`四月`, 44, 34]
]
},
series: [
{
type: `pie`,
center: [`65%`, 60],
radius: 35,
encode: { itemName: 3, value: 2 }
},
{
type: `line`,
encode: { x: 0, y: 1 }
},
{
type: `bar`,
encode: { x: 0, y: 2 }
}
]
}
const series = {
xAxis: {
data: [`一月`, `二月`, `三月`, `四月`]
},
yAxis: {},
series: [
{
type: `pie`,
center: [`65%`, 60],
radius: 35,
data: [
{ name: `XX`, value: 52 },
{ name: `YY`, value: 54 },
{ name: `ZZ`, value: 42 }
]
},
{
type: `line`,
data: [3, 1, 2, 4, 6]
},
{
type: `bar`,
data: [30, 10, 20, 40, 60]
}
]
}
坐标系
const dataset = {
xAxis: [
{ type: `category`, gridIndex: 0 },
{ type: `category`, gridIndex: 1 }
],
yAxis: [
{ type: `value`, gridIndex: 0 },
{ type: `value`, gridIndex: 1 }
],
grid: [
{
top: 40,
bottom: `58%`
},
{
top: `58%`,
bottom: 40
}
],
dataset: {
source: [
[`一月`, 23, 12, `XX`, 52],
[`二月`, 12, 23, `YY`, 54],
[`三月`, 63, 4, `ZZ`, 42],
[`四月`, 44, 34]
]
},
series: [
{
type: `pie`,
center: [`100%`, 40],
radius: 35,
encode: { itemName: 3, value: 4 }
},
{
type: `line`,
encode: { x: 0, y: 2 },
xAxisIndex: 0,
yAxisIndex: 0
},
{
type: `line`,
encode: { x: 0, y: 1 },
xAxisIndex: 1,
yAxisIndex: 1
},
{
type: `bar`,
encode: { x: 0, y: 2 },
xAxisIndex: 1,
yAxisIndex: 1
}
]
}
使用主题
使用官方的主题构建工具
选择一个主题,给主题起名字,然后下载为js格式
使用
import './theme/custom'
this.$echarts.init(this.$refs.pieChart, `custom`).setOption(option)
通过图片链接批量下载图片
最近想把保存在图床的图片下载到本地,然而当选中所有图片之后并没有下载按钮,只可以获取到所有图片的嵌入代码,可能是批量下载图片比较耗带宽吧。
复制 HTML 图像链接
dogecloud 存储空间新建 index.html 文件
复制 index.html 文件链接到 Image Extractor
然后选择全部下载即可。
之后要添加的文章2021-03-17
之后添加《如何看bilibili港澳台及特殊(泰国版限定)番剧》文章。
b站解除地区限制
B站番剧存在限制,如港澳台限定、仅限**地区等,解锁地区限制可以看港澳台番剧,圣光少、删减少,最重要的是很多大会员才能看的番在港澳台完全是免费的!
bilibili港澳台番剧的优点
- 圣光少、删减少。
- 弹幕少,清净,如果你喜欢看很多弹幕那这是缺点。
- 免费番剧多且大多数新番可以免费看最新一集。
- 很多港澳台番都有简中字幕。
- 受到“先审后播”影响,港澳台可以更早的看到新番。
翻墙
翻墙简单粗暴,因为有一些番剧仅限**地区,所以机场建议选有**节点的。
但是翻墙并不是最好的方法,假如你连接了**节点,那么你无法观看除港澳台之外的番剧并且所有的流量都是走的机场流量,如果你看的剧比较多,会需要来回开关翻墙软件,很麻烦。
使用油猴插件
这种方法只限pc端才可以
首先安装油猴,谷歌搜索tampermonkey下载就好了。
然后在 获取新脚本页面搜索:解除b站区域限制,没意外的话第一个就是了,安装即可。
安装之后找一个番剧页面,点小星球图标,会弹出一个设置页面。
之后设置下首选服务器。
使用bilibili漫游
这种方法只限安卓手机才可以,目前苹果只能翻墙看
这个方法有一个好处就是可以看一些泰国特供番剧。
点击下面链接下载apk直接用就行,不过还需要设置下解析服务器就是了。
使用 哔哩哔哩uwp
这种方法只限win pc端才可以
谷歌或微软商店直接搜索:哔哩哔哩uwp 下载即可。
vue 实现图片不同加载方式
使用 vue 实现图片显示在视图时加载和图片按顺序加载两种方式,代码使用了 vue3 的新的组合式 api,代码较简单,可以稍微改进下。
首先是两种方式都要用到 CoverImage 组件
整个组件最重要的部分就是 loadImg 方法,这个方法用来加载图片,并当图片加载完成后显示该图片。
<template>
<div>
<img :src="imgSrc" v-show="visible" />
</div>
</template>
<script>
import { ref } from 'vue'
export default {
name: `CoverImage`,
setup() {
const imgSrc = ref(``)
const visible = ref(false)
const loadImg = function (src) {
let img = new Image()
img.src = src
img.onload = img.onerror = () => {
imgSrc.value = src
visible.value = true
this.$emit(`addLoadIndex`)
}
}
return { imgSrc, visible, loadImg }
},
}
</script>
图片显示在视图时加载
主要是利用js提供的 IntersectionObserver 对象来实现。
<template>
<div>
<div class="img-wrap" v-for="(src, index) in srcList" :key="index">
<cover-image :ref="setItemRef" :eleIndex="index"></cover-image>
</div>
</div>
</template>
<script>
import { onBeforeUpdate, onMounted } from 'vue'
import CoverImage from './components/CoverImage'
export default {
name: `CoverShowList`,
components: {
CoverImage
},
setup() {
const srcList = [
`https://i.postimg.cc/prGHDHk6/14.jpg`,
`https://i.postimg.cc/tTzy4P6y/13.jpg`,
`https://i.postimg.cc/YqDrF1sC/10.jpg`
]
let itemRefs = []
let io = null
const setItemRef = function (el) {
itemRefs.push(el)
}
const getStatus = function (items) {
items.map((item) => {
if (!item.isIntersecting) return
const eleIndex = item.target.getAttribute(`eleIndex`)
itemRefs[eleIndex].loadImg(srcList[eleIndex])
io.unobserve(item.target)
})
}
onMounted(() => {
io = new IntersectionObserver(getStatus)
itemRefs.map((item) => {
io.observe(item.$el)
})
})
onBeforeUpdate(() => {
itemRefs = []
})
return { srcList, setItemRef }
}
}
</script>
<style>
.img-wrap {
border: 1px solid red;
padding: 400px 200px;
margin-top: 200px;
}
.display-none {
display: none;
}
</style>
图片按顺序加载
在父组件中设置一个 loadIndex 变量,然后用watch监听loadIndex的变化。
<template>
<div>
<div v-for="(item, i) in srcList" :key="i">
<cover-image :ref="setItemRef" @addLoadIndex="addLoadIndex"></cover-image>
</div>
</div>
</template>
<script>
import { ref, watch, onMounted, onBeforeUpdate } from 'vue'
import CoverImage from './components/CoverImage'
export default {
name: `CoverImageList`,
components: {
CoverImage
},
setup() {
const srcList = [
`https://i.postimg.cc/prGHDHk6/14.jpg`,
`https://i.postimg.cc/tTzy4P6y/13.jpg`,
`https://i.postimg.cc/YqDrF1sC/10.jpg`
]
let itemRefs = []
const loadIndex = ref(0)
const setItemRef = function (el) {
itemRefs.push(el)
}
const addLoadIndex = function () {
loadIndex.value++
}
onMounted(() => {
itemRefs[loadIndex.value].loadImg(srcList[loadIndex.value])
})
onBeforeUpdate(() => {
itemRefs = []
})
watch(loadIndex, (value) => {
itemRefs[value] && itemRefs[value].loadImg(srcList[loadIndex.value])
})
return { loadIndex, srcList, setItemRef, addLoadIndex }
}
}
</script>
解决 lol 连接断开问题
最近换了移动宽带,玩 lol 网通区经常连接断开,而且发现基本都是家用网络会出这些问题,高端的网吧或网咖则不会出现这种问题。
原因
网络和游戏服务器连接不稳定
解决方法
分两类解决方法,第一类是修复自己网络的问题,第二类是更换游戏服务器
第一类
修复LSP
大多数的游戏加速器都有这个功能,修复之后重启一下电脑
使用游戏加速器
可以使用一下海豚、熊猫、小黑盒这类的加速器,一个不行多试几个
关闭代理
win + i 键打开 windows设置,搜索 “代理” ,选择 “代理服务器设置”,把三个开关全关掉
关闭 wegame 自带的加速
点击右上角设置,点击辅助工具关闭
更换网络运营商或更换更优质网络线路
不多说了,最根本的解决方法
第二类
修改游戏服务器,当然肯定不是真的修改,lol不同区服的服务器是不一样的,可以去一些人比较多的区,比如电一、德玛西亚等,相对来说会好一些
补充
网上有些人说不要用 wegame ,不过个人感觉关掉 wegame 自带的加速后没什么问题
机场使用体验及测速
主要记录自己的使用经体验,非评测,会附上使用的时间,不能保证机场现在的好坏,并附带一些简单的测速(移动)。
由于精力有限,没法及时更新,如果要使用推荐 毒药推荐的
有一阵子没更新了,不过推荐那种最便宜套餐都是一月20块以上的,那种比较好。
番茄 V2 航线
使用感受
稳定性还不错,偶尔会有少数节点 ping 不通。
测速
使用时间
2021-08-08到~2021-09-07
可莉
使用感受
稳定性还不错。
测速
使用时间
2021-07-08到~2021-08-07
TNTV2
使用感受
多数节点速度不错,稳定性一般,便宜。
测速
使用时间
2021-06-21到~2021-07-08
星星饭团
使用感受
稳定性不错,近期增加了节点的倍率。
10元套餐涨价为15元,倍率降为x1 [ 2021-06-12 ]
测速
使用时间
2020-04-06到~2021-06-21
魅影极速
使用感受
稳定性不错,价格略贵。
测速
使用时间
2020-02-23到~2020-05-23
cordcloud
使用感受
稳定性一般,尤其是在晚间高峰时间稳定性不太好。
使用时间
2020-02-19到2021-02-22
cheapv2ray
使用感受
不是很稳定,便宜。
使用时间
2020-01-17到2021-02-18
wocloud卧槽云
使用感受
节点少,稳定性一般。
使用时间
2020-12-04到2021-01-15
审计规则
多数机场都有审计规则和审计记录,违反过多的审计规则可能会封号,在使用机场前请先查看审计规则,有些机场虽然没有明确标出各个规则,不过依然存在。
总结
适合自己才是最好的,一月 10~20 软妹币的就差不多了。
如何找二次元图片出处
是不是在网上看到了好看的二次元图片,但不知道怎么根据图片去找原图或原图作者的烦恼?看了这篇文章可以帮助你 90% 找到原图片。当然也会说明有些情况依然无法找到原图的原因。
最近,本人在玩原神,所以就以找一张原神图片作为例子吧,首先去原神吧逛一逛看看有没有人发图片。
找到了,这个帖子附带了一张芭芭拉的图片,接下来要做的就是找到这张图的出处。
首先,使用snipaste截图工具(其他截图工具也可以,没有百度下载一个就行)截取完整的图片或另存为。
之后打开saucenao网站,添加图片点击get sause。
稍等片刻,就会显示搜索结果了,然后 ctrl+点击pixiv ID即可找到原图。
以上是一种简单方法,sause网站识图往往只能识别原图,如果这张图片进行了修改,如截取、模糊等处理,那么sause很有可能识别不到该图片。
对于这种情况建议先使用google识图找到原图片,在使用sause,以下是一张截取了的图片,可以通过google识图查找
截取的图片。
截取的图片
缩水的原图片
然后根据这张缩水的原图片去sause查找原图出处即可。
当然,用了以上方法还是有可能搜不到,原因有很多,比如说这张图(侵删)。
这张图片是休嫁一慧的图片,ta本人目前(20-12-29 20点32分)只在微博上发了这个图片,还没有发布到p站等平台上,这种是搜不到的,目前也没有太好的国内插画搜索,所以对此情况也没有太好的办法。
微信小而美
博客主题推荐和欣赏
推荐和欣赏一些非常不错的博客主题,不限平台(wordpress、typecho、hexo等都有),主要是acg类主题,大多都是博客圈大佬搞出来的。
shoka
lolimeow
WordPress博客主题二次元风。
Sinner
Sinner,一款 Typecho 主题。
简洁。
Mirages
Mirages,一款 Typecho 主题。
简洁。
argon
argon,一款wordpress、hexo主题,免费使用。
没什么好说的,好就对了。
handsome
handsome ,一款typecho主题,售价88元。
这款主题当时第一次看到感觉挺一般的,但是又看了几遍之后越来越佩服这个主题了,主要是因为这款主题的完成度非常的高,包括一些小细节打磨的很好。
aurora
aurora,一款非常漂亮的vue主题,免费使用。
个人觉得是非常漂亮的,包括一些动画及风格什么的。
Cuteen4.x
Cuteen4.x,一款typecho主题,售价58元。
最近刚看到的主题,还不错。
Sakura
Sakura ,一款wordpress主题,免费使用。
个人认为很棒的一个博客,用的人也很多。
Sakurairo
Sakurairo,一款wordpress主题,免费使用。
在Sakura主题中添加了额外的特效、Live2d等。
Kratos-pjax
Kratos-pjax,一款wordpress主题,免费使用。
比较“旧”的一款主题了,不过作为二次元向的博客主题可以说非常经典了。
Yun
Yun,一款hexo主题,免费使用。
漂亮的hexo主题,用的人不少。
Vue 学习笔记
使用 vue 一段时间了,但是并没有系统的总结过所学习的知识,所以特意新建一篇文章总结一下 vue 中比较重要的知识点,以便之后方便翻阅复习。
数据的响应式
Vue 实例被创建时,data对象所有的属性会被加入到Vue 的响应式系统中。
当data中的属性发生变化,视图也会跟着发生变化。
如果一个值,一开始不会使用,但是之后会使用,可以为这个值设置一个类型相同的初始值
data: {
newTodoText: '',//字符串类型初始值
visitCount: 0,//数字类型初始值
hideCompletedTodos: false,//布尔类型初始值
todos: [],//数组类型初始值
obj: {}//对象类型初始值
error: null//不存在数据的初始值
}
如果没有设置初始值,在Vue实例创建后为data添加属性,此时的属性是非响应式的
除非使用
Vue.set(vm.someObject, 'b', 2)
//or
this.$set(this.someObject,'b',2)
关于对象
对于一个对象类型,使用obj.prop = 'xxx' 新添加属性是非响应式的
如果要添加响应式的属性,可以使用this.$set或重新赋值新对象的方法
// obj:{
// a:1,
// b:2
// }
//向obj种添加单个属性c
this.$set(this.obj,'c',3)
//向obj中添加c和d属性
this.obj = Object.assign({},this.obj,{c:3,d:4})
关于数组
和对象不同,大多数的数组方法都会触发视图更新
如push() pop() splice() sort() 等
也有些方法不会变更原始数组,那么可以直接把整个数组替换掉
// numbers: [ 1, 2, 3, 4, 5 ]
this.numbers = this.numbers.filter(number => number>3)
数组依然有两种情况是非响应的
- 直接使用索引修改一个数组项时 this.items[indexOfItem] = newValue
- 修改数组长度 this.items.length = 1
对于第一种情况可以使用vm.set
// numbers: [ 1, 2, 3, 4, 5 ]
//无法使用索引直接修改
//this.numbers[3] = 123456
//应该使用
this.$set(this.numbers,3,123456)
// or
this.numbers.splice(3,1,123456)
对于第二种情况则使用数组的splice
// numbers: [ 1, 2, 3, 4, 5 ]
//无法直接修改数组长度
// this.numbers.length = 2
//应该使用
this.numbers.splice(2)
关于数组对象
如过有一个列表,要控制每个列表的显隐
第一种情况
sourceData:[
{id:1,name:'红',show:false},
{id:2,name:'黄',show:false},
{id:3,name:'蓝',show:false},
],
元数据中就有show这个属性,此时的show为响应式的,此时没有问题。
changeShow(show,record){
//直接修改视图可响应
record.show = !show
}
第二种情况
因为数据是从后台获取,一般先给默认值sourceData:[],然后赋值
//从后台得到数据
this.handleData = [
{id:1,name:'红'},
{id:2,name:'黄'},
{id:3,name:'蓝'},
]
//处理一下后台的数据
this.handleData = sourceData.map(item=>{
item.show = false
return item
})
此时的show属性是非响应的,id和name属性是响应的,因为show属性是后加给对象的,vue没有跟踪,解决方法也非常简单
第一种解决方法,添加对象新属性的时候重新赋予一个新的对象
this.handleData = sourceData.map(item=>{
item = Object.assign({},item,{show:false})
return item
})
第二个方法,使用数组的响应式方法
changeShow(show,record){
//直接修改视图不会响应
record.show = !show
//官方推荐使用方法
this.$set(
this.handleData,
this.handleData.findIndex(item => {
return item.id === record.id
}),
Object.assign({},record,{show:!show})
)
//使用splice
this.handleData.splice(
this.handleData.findIndex(item => {
return item.id === record.id
}),
1,
Object.assign({},record,{show:!show})
)
}
推荐使用第一种,为对象添加新的属性时,不要使用obj.prop = 'xxx',而是使用obj = Object.assign({},obj,{prop:propValue})或this.$set(obj,'propName',propValue),只有在修改对象属性时才使用obj.prop = 'xxx'。
表单输入绑定
v-model 会忽略所有表单元素的 value、checked、selected attribute 的初始值而总是将 Vue实例的数据作为数据 > 来源。你应该通过 JavaScript 在组件的 data 选项中声明初始值。
复选框
单个复选框绑定一个布尔值
<input type="checkbox" v-model="form.checked" value="apple">是否{{form.checked}}
多个复选框绑定一个数组
<input type="checkbox" v-model="form.fruits" value="apple">苹果
<input type="checkbox" v-model="form.fruits" value="banana">香蕉
<input type="checkbox" v-model="form.fruits" value="peach">桃子
单选按钮
单选按钮绑定一个字符串
<input type="radio" value="1" v-model="form.gender">男
<input type="radio" value="2" v-model="form.gender">女
选择框
单选时绑定一个字符串
多选时绑定一个数组
值绑定
对于单个复选框绑定的值为布尔值,也可绑定为字符串
<input
type="checkbox"
v-model="toggle"
true-value="yes"
false-value="no"
>
也可绑定为其他的数据类型
<select v-model="selected">
<option v-bind:value="obj">选项1</option>
</select>
关于组件
在组件中使用v-model
<input v-model="searchText">
等价于
<input
:value="searchText"
@input="searchText = $event.target.value"
>
运用在组件上也是如此
<custom-input
v-model="searchText"
></custom-input>
等价于
<custom-input
:value="searchText"
@input="searchText = $event"
></custom-input>
所以要在子组件中接收value和触发input事件
Vue.component('custom-input',{
props:['value'],
template:`
<div>
<input :value="value" @input="$emit('input',$event.target.value)" />
</div>
`
})
自定义组件的 v-model
一个组件上的 v-model 默认会利用名为 value 的 prop 和名为 input 的事件
如果是复选框,单选框可能需要监听不同的prop和事件,比如监听复选框的checked的prop和change的事件
Vue.component('child-component',{
model: {
prop: 'checked',
event: 'change'
},
props: {
checked: Boolean
},
template: `
<div>
<input
type="checkbox"
:checked="checked"
@change="$emit('change', $event.target.checked)"
>
</div>
`
})
动态组件
<component :is="currentComponent"></component>
Vue.component('home-co',{
template:`<h1>Home Page</h1>`
})
Vue.component('archive-co',{
template:`<h1>Archive Page</h1>`
})
Vue.component('post-co',{
template:`<h1>Post Page</h1>`
})
const app = new Vue({
el:'#app',
data(){
return {
text:'',
currentComponent:'archive-co'
}
}
})
将原生事件绑定到组件
组件的某个特定的元素监听原生事件
Vue.component('base-input', {
inheritAttrs: false,
props: ['label', 'value'],
computed: {
inputListeners: function () {
var vm = this
return Object.assign({},
this.$listeners,
{
input: function (event) {
vm.$emit('input', event.target.value)
}
}
)
}
},
template: `
<label>
{{ label }}
<input
v-bind="$attrs"
:value="value"
v-on="inputListeners"
>
</label>
`
})
.sync修饰符
<child-component :message.sync="message"></child-component>
等于
<child-component :message="message" @update:message="message = $event"></child-component>
sync相当于一个缩写,以下是一个简单的例子
Vue.component('parent-component',{
data(){
return{
message:'旧消息',
}
},
template:`
<child-component :message="message" @update:message="message = $event"></child-component>
`
})
Vue.component('child-component',{
props:{
message:{
type:String,
required:false,
default:''
}
},
template:`<div>
子组件:{{message}}
<button @click="$emit('update:message','新消息')">按钮</button>
</div>`
})
Prop
传入一个对象的所有 property
数据对象
post: {
id: 1,
title: 'My Journey with Vue'
}
绑定数据
<blog-post v-bind="post"></blog-post>
相当于
<blog-post
v-bind:id="post.id"
v-bind:title="post.title"
></blog-post>
单向数据流
注意在 JavaScript 中对象和数组是通过引用传入的,所以对于一个数组或对象类型的 prop 来说,在子组件中改变变更这个对象或数组本身将会影响到父组件的状态。
关于
关于博主
~ 肥宅 ~
~ 现实中颓废的人 ~
~ 有点丧 ~
~ 活着的乐趣就是玩游戏、看番和玩galgame ~
在玩的游戏
- lol#已退游
- 明日方舟#已退游
- 原神#半退游#大小月卡已停
- 决战 平安京#已退游
- 其他各种优秀单机
时间轴
- 添加了暗黑模式,变得更酷啦。 -- 2023-07-25
- 文章图片添加预览功能。 -- 2023-06-02
- 网站将删除周杰伦的歌曲。 -- 2023-01-01
- 想给文章图片加入点击大图功能,不过太耗性能了,算了。 -- 2022-08-03
- 可能是因为高考的原因,感觉 github 访问速度好慢啊。 -- 2022-06-07
- 对字体和部分样式进行了修改。 -- 2022-06-04
- 更新了图片地址,并且优化了部分页面。 -- 2022-05-08
- 已将站内所有图片转移到新图床。 -- 2021-03-15
- 发现旧图床会删除图片,准备将网站所有图片迁移到新图床。 -- 2021-03-14
网站实用工具
"图片压缩 : TinyPNG "
"cdn : jsdelivr "
"视频存储 : 多吉云 "
"数据存储 : leancloud "
"emoji表情 : emojiall "
"------"
"以上工具都是个人实用感觉不错而且比较稳定的。"
补充
如果图片加载不出来,那么大概率是 jsdelivr 被屏蔽了,可能大概过个几天就好啦。
unicloud 阿里云服务空间清理通知
unicloud 阿里云服务空间清理通知
通知链接 | 简单来说 45 天没使用会被清理,且无法找回。这要是存了什么重要不活跃的数据还是挺恐怖的。😰
快速下载磁力资源
之前文章说过了 IDM 下载云盘资源,但是 IDM 磁力的下载方法已经失效了,所以又寻找了一些其他的方法。由于国内环境受限,导致磁力资源下载速度较慢。
前提文章
再看这篇文章之前,建议先看下这篇文章,了解一下为什么国内的下载速度这么慢。
建议
-
相信大家看了文章之后也了解了,磁力下载的速度取决于做种的人数,做种的多了,下的自然就快了。
-
尽量别用迅雷。
-
推荐的替代迅雷的软件:
BitComet
qBittorrent
qBittorrentEE - 大佬做的加强版
aria2 - 以管理员身份启动AriaNg启动器.exe -
修改track
具体看这篇文章 -
不要盯着一个软件用,建议几个软件都开着,看哪个有速度用哪个。
二次元网站整理
主要收集一些不错的二次元(动漫、里番、galgame、插画等),去除了一些论坛类网站,大多数网站可以直接用,话说不会真的有人可以快速上手论坛吧😮?
一些网站无法正常打开需要挂梯子
有一些网站没有网址发布页,所以网址可能会失效
动漫的720p和1080p区别不大
一些带有血腥、暴力、色情的番建议不要看bilibili的播放源,会有删减和圣光
age动漫
在线动漫,播放速度快,手机建议下载客户端使用。
极的箱子
在线动漫,不要下载手机端app,广告太多了。
233 动漫
界面挺土的,不过看番还不错。
樱花动漫
比较知名的在线动漫网站,有广告。
百度搜索到的樱花动漫是樱花1站,视频清晰度不行。
樱花2站开梯子视频加载慢(主要是有好多都是直接拉取的b站和a站的资源),不开梯子图片加载不出来。
众所周知,樱花动漫有两个
扶她404
需要用梯子才行,清晰度很不错。
很多老资源失效了,站长没补,可以去留言板留言要求补,不过看新番还是挺不错的。
飞极速动漫
还行,有些资源也是b站的。
edd动漫
在线动漫,有弹幕。
动漫岛
更新速度还行。
zzzfun
在线动漫,有弹幕,不过相对于edd用的人更少。
喵绅士
本子网站。
绅士漫画
本子网站。
琉璃神社
这个比较出名,国内热爱二次元的基本都会略有耳闻,主要分享里番、galgame等,通过哈希值下载观看(建议下载最好不要用迅雷哦)。
灵梦御所
这个也是比较出名的,我的几个热爱二次元同学基本也都知道。
网站成立之初主要是补充琉璃神社没有的资源,后来资源多了也成为一个"知名"网站了。
网站也是通过下载观看,下载之前需要看新手指南。
2dfan
通常在这里查找一下galgame的攻略。
hanime1
中文繁体的hanime?
画质要比hanime稍差一点,和hanime的720p差不多,实际观感也差不了多少。
在线里番,资源全,需要梯子,视频加载速度取决于你的网速和梯子,节点建议使用**的,我这一点都不卡。
绅士天堂
目前完全免费下载。
汉化galgame分享站,资源较少,更新频率一般,不过网站一直在正常运行中。
维咔VikACG
汉化galgame分享站,更新频率较快。
需要注册登录,签到获取积分下载。
天使二次元
汉化galgame分享站,更新频率较快。
需要注册登录,首次注册需要20元买邀请码,签到获取积分下载,积分无法通过签到以外的途径获取。
忧郁的弟弟
汉化galgame分享站,据说站长结婚了,所以停止了更新,网站上都是一些较久的资源。
目前下载需要注册登录,当然也可以用国际线路。
国内线路需要积分购买下载,每天进入网站获取3积分,积分只能通过每天进入网站获取。
hanime
个人认为不错的英文看番网站。
免费,签到可以换会员开1080画质,唯一的缺点就是英文的。
看不了就是梯子有问题。
漫音社
动漫无损音乐下载站。
japaneseasmr
可以在线收听同人音声。
完全免费。
EroVoice
输入 rj code 下载同人音声。
lolipoi(现在叫poi3)
b格很高的一个站,干什么的就不说了。
付费网站,注册需要注册码,非常低调的一个网站,和梦次元有关系。
目前好像只能通过站内人介绍得到注册码。
幻想次元
知名的绅士网站。
想要注册需要投稿,投稿会获取邀请码,当然也可以直接找别人买。
目前网站更新较慢。
司机会所
严格意义上并不是二次元站点,不过有一些cos二次元的。
主要分享一些cos和a-----v。
下载速度慢建议用IDM下载。
网站更新频率较快,部分资源收费。
E-Hentai
又称e站(当然e站还指erocool和edd动漫),界面不是太友好,刚进入会有眼花缭乱的感觉。
资源很多,下载慢,全英文界面。
pornhub
国外知名的搞黄色网站,翻墙的py应该难免会听说过,又称p站(当然p站还指pixiv站)、黑黄站。
质量越来越差了。
松鼠仓库
个人印象不是很好的网站,广告太多了。
中文字幕,资源不全,可以在线观看。
嗷呜acg
目前已经关闭了有一段时间了,站长说可能会回来。
嘀哩嘀哩
比较知名的在线动漫网站。
不过现在的嘀哩嘀哩不是以前的了,这两个嘀哩嘀哩都是"假的"。
捏它动漫
有不在任何通知的情况下关闭网站,不是很稳,不过可以看。
不要下载ta们的app!
在线动漫,加载速度慢,天气之子加载了一分钟😡。
网站屏蔽了其他地区的ip。
控制台报错2021-03-02
控制台报错是APlayer插件报的错,不过不影响使用,所以就不管了。
Underscore 使用及私人问题存放处
underscore 算是 lodash 函数库的精简版本,把 lodash 中最常用的函数提取出来,相对于 lodash 体积更小、更易上手。原文时间:2020-10-23 18:43
根据id和pid的关系 生成 children 数组
如:
categoryArr: [
{ id: 1, name: `音乐`, pid: 0 },
{ id: 2, name: `萝卜`, pid: 9 },
{ id: 3, name: `食物`, pid: 0 },
{ id: 4, name: `菠菜`, pid: 9 },
{ id: 5, name: `周杰伦`, pid: 1 },
{ id: 6, name: `五月天`, pid: 1 },
{ id: 7, name: `五花肉`, pid: 8 },
{ id: 8, name: `肉`, pid: 3 },
{ id: 9, name: `蔬菜`, pid: 3 }
],
要变为:
childrenArr: [
{
id: 1,
name: `音乐`,
pid: 0,
children: [
{ id: 5, name: `周杰伦`, pid: 1 },
{ id: 6, name: `五月天`, pid: 1 }
]
},
{
id: 3,
name: `食物`,
pid: 0,
children: [
{
id: 8,
name: `肉`,
pid: 3,
children: [{ id: 7, name: `五花肉`, pid: 8 }]
},
{
id: 9,
name: `蔬菜`,
pid: 3,
children: [
{ id: 2, name: `萝卜`, pid: 9 },
{ id: 4, name: `菠菜`, pid: 9 }
]
}
]
}
]
方法:
handleCategory(categoryArr) {
const first = categoryArr.filter(h => h.pid === 0),
notFisrt = categoryArr.filter(h => h.pid !== 0)
this.renderChildren(first, notFisrt)
return first
},
renderChildren(firstArr, notFisrtArr) {
firstArr.forEach(h => {
const children = notFisrtArr.filter(j => j.pid === h.id)
if (children) {
this.renderChildren(children, notFisrtArr)
}
h.children = children
})
}
使用:
console.log(this.handleCategory(this.categoryArr))
将多维的 children 数组变成一维的数组
如:
childArr: [
{ id: 12, name: `肉`, children: [] },
{
id: 1,
name: `水果`,
children: [
{ id: 2, name: `香蕉` },
{ id: 3, name: `橘子` }
]
},
{
id: 4,
name: `车`,
children: [
{
id: 5,
name: `国产车`,
children: [
{
id: 8,
name: `红旗`
},
{ id: 9, name: `长虹` }
]
},
{
id: 6,
name: `外国车`,
children: [
{
id: 7,
name: `奔驰`
}
]
}
]
}
]
方法:
handleOneDimensional(childrenArr) {
const result = []
this.renderFirst(result, childrenArr)
return result.map(h => {
delete h.children
return h
})
},
renderFirst(oneArr, childrenArr) {
childrenArr.forEach(h => {
oneArr.push(h)
if (h.children && h.children.length !== 0) {
this.renderFirst(oneArr, h.children)
}
})
}
使用:
console.log(this.handleOneDimensional(this.childArr))
forEach究竟能不能改变数组的值
forEach方法里操作对象生效,想要操作里面的基本数据类型,就用arr[i]的形式直接操作数组。
arr.forEach((item, index) => {
arr[index] = item * 3
})
基本数据类型,就是复制一份数据放到栈内存中,所以item也是复制了一份基本数据类型,所以修改item无效。引用数据类型是将堆内存地址复制了一份给item,所以item可以通过地址操作对象。
简单来说就是item无法被重新赋值
const arr = [{ id: 1 }, { id: 2 }, { id: 3 }]
arr.forEach(item => {
item = { id: 4 }
})
console.log(arr)//[{ id: 1 }, { id: 2 }, { id: 3 }]
Underscore
为什么要学习Underscore?
Underscore是一个js实用库。对于js非常熟练的人完全可以不需要学习,js本身提供的方法足够了,尤其是es6就可以满足非常多的需求了。但是js提供的这些方法都有两个问题,第一个是方法比较杂,第二个是很多方法不同数据类型都是不通用的,比如forEach循环,只能对数组使用,那遍历对象呢,又有另外一个方法,而underscore中的_.each方法无论数组和对象都可以使用。
const arr = [
{ id: 1, name: `小明` },
{ id: 2, name: `小红` },
{ id: 3, name: `小刚` }
]
_.each(arr, h => {
console.log(h)
})
const obj = {
a: 1,
b: 2,
c: 3
}
_.each(obj, (k, v) => {
console.log(k, v)
})
其中underscore有些方法非常方便,比如escape、unescape、throttle、debounce,但也不用强求都要使用unserscore的方法。
_.max方法
有一个数组对象
peopleInfo: [
{ id: 101, name: `小明`, age: 32 },
{ id: 102, name: `小刚`, age: 12 },
{ id: 103, name: `小红`, age: 16 }
]
要获取到年龄最大的那一条
//使用underscore
_.max(this.peopleInfo, h => h.age)
//不使用unserscore的简单方法
this.peopleInfo.sort((a, b) => {
return b.age - a.age
})[0]
使用sort会修改原数组,而_.max则不会
当然也可以先拷贝一下
this.peopleInfo.concat().sort((a, b) => b.age - a.age)[0]
underscore大部分方法不会修改原数据
_.chunk
分割数组,在渲染视图时经常会用到
_.chunk([1, 2, 3, 4, 5], 2)
_.throttle
创建节流函数
this.logHello = _.throttle(this.logHello, 1000)
logHello函数一秒钟最多触发一次!
_.debounce
创建一个防抖函数
this.searchContent = _.debounce(this.searchContent, 1000)
当快速触发searchContent 函数时,会不断重置函数,直到停止触发长达1秒才会触发一次searchContent 函数。
歌单
ひげこれ!
author: unknow
published: 2020
progress: 专辑
rating: 4,
postTitle:
postLink:
cover: //fastly.jsdelivr.net/gh/starryiu/PicGo-jsDelivr/PicGo/eadac930d66eb64fff628cc1d61a3f16.jpg
link: https://agonies.lanzous.com/iwQVRmzk53a
description: HIGE DRIVER 角川动画歌曲精选辑 《 ひげこれ! 》,每首都是经典,个人非常喜欢,感谢漫音社 不晒太阳的青花鱼 大佬的分享。
声 〜 VOCALOID Cover Album 〜
author: H△G
published: 2017
progress: 专辑
rating: 3.5,
postTitle:
postLink:
cover: //fastly.jsdelivr.net/gh/starryiu/PicGo-jsDelivr/PicGo/c916a5b5c5895ca622ab9603086c95e7.jpg
link: https://agonies.lanzous.com/i2eAln22s0f
description: H△G在2017年发表的翻唱专辑,感觉还是不错的,顺便推荐一个音乐播放器 AIMP 。
远程连接mongodb
用服务器整了个远程mongodb,想要测试下,结果怎么都连不上,最后找到了这个解决办法。
- mongodb的配置文件中的bind_ip 默认为127.0.0.1,默认只有本机可以连接。 此时,需要将bind_ip配置为0.0.0.0,表示接受任何IP的连接。
- 防火墙阻止了27017端口。
aurora 主题的 vue3 版本 !
免费部署静态页面和 node
最近发现有很多免费托管网站服务,而且使用起来也是非常的方便。
github pages
github pages 的使用非常简单,建立一个 用户名.github.io github仓库,然后将你的 静态页面 目录上传就可以了。
优点
可以起到宣传的做用,大部分人看你的 github 页面都会看看你的 github pages。
缺点
- 只能托管一个静态页面。
- 如果使用 vue-cli 这类框架,虽然可以使用 deploy 快速上传,但仍需要建立一个仓库存放源代码。
netlify
netlify 可以关联 github 账号,可以选择 github 仓库直接进行静态页面的构建。
当部署了项目之后,每次向对应仓库的分支提交代码都会重新构建,非常方便。
缺点
只能构建静态页面。
vercel
vercel 部署静态页面和 netlify 一样的操作,不过 vercel 还可以构建 node 和 express 写的简单的 api。
考虑到用 express 的人比较多,所以只介绍 express 。
目录
代码
/** index.js */
const express = require('express')
const app = express()
app.use(express.json())
const user = [
{id:1,name:'xiaoming',age:1},
{id:2,name:'xiaohong',age:2},
{id:3,name:'xiaogang',age:3}
]
const setCacheControl = (res,maxAge=1) => {
// 不带参数的请求建议加上。
res.setHeader('Cache-Control', `s-max-age=${maxAge}, stale-while-revalidate`)
}
app.get('/api/queryUsers', (req, res) => {
setCacheControl(res,30)
res.json(user)
})
app.get('/api/queryUser/:name', (req, res) => {
const { name } = req.params
const findUser = user.find(item=>item.name === name)
res.json(findUser || '没有这个用户')
})
/**
* 和平时一样写,只不过要导出app,并且不用绑定 listen
*/
module.exports = app
/** vercel.json */
{
"rewrites": [{ "source": "/api/(.*)", "destination": "/api" }]
}
然后上传到 github 仓库,再使用 vercel 从 github 新建项目,不需要填写构建命令和目录。
之后每次推送 github 仓库都会自动构建。
这种方式只能提供简单的api。
缺点
- 目前好像只能使用 node express,经过个人测试,响应速度有点慢。
- 更多
参考
typecho 搭建博客
记录使用 typecho 搭建博客的过程,还是非常简单的,但是为了防止以后在用回 typecho 还需要重新看一遍文档,所以在此记录一下。
下载、安装
百度搜索typecho,打开网站后有个大大的立即下载按钮,点击按钮即可
在服务商购买服务器或虚拟主机,将下载后的文件放入网站目录
网站目录虚拟主机一般会帮你配置好,服务器则需要自己配置nginx或者也可以使用一些面板工具,如宝塔面板
除了网站目录需要配置之外还需要配置mysql数据库。
大多数虚拟主机数据库都是mysql数据库,不需要配置,服务器依然需要自己配置或者使用面板工具配置。
如果不想有那么多事,并且只想布置一个typecho博客程序还是虚拟主机比较好,而且价格也比服务器便宜。
然后解析域名,这个比较简单,百度一下或者很多云服务商在购买域名后都有如何解析域名的教程。
打开网站,安装步骤填写数据库信息和管理员信息,便可以来到控制台。
安装主题
在安装typecho完成之后,大多数使用者都不会使用默认主题,所以一般需要自己去找主题。
这里有一个官方的主题网站 点击进入
前几页的主题还是不错的,后几页的就比较老了,不推荐使用。
喜欢那个主题点击 模板下载 即可。
下载后一般是一个压缩包,把压缩包的文件上传到网站目录下的/usr/themes目录中即可。
有些不错的typecho主题并没有在官方主题网站,需要自己去找。
去掉网址中的index.php
仪表盘中 [设置]=>[永久链接]=>[是否使用地址重写功能] 点击启用
之后将以下代码添加到nginx配置文件中
if (!-e $request_filename){
rewrite ^(.*)$ /index.php$1 last;
}
如果使用的是Apache,则在网页目录下的.htaccess文件下加入以下代码
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php [L,E=PATH_INFO:$1]
</IfModule>
补充
使用wordpress搭建博客也是同样操作。
以撒表人物标记全红纪念
卡通样式的数字展示
写了一个简单的数字展示器,使用方法非常简单,直接调用函数便可返回相应的图片地址。
介绍
参数
- @param {Object} config
- @param {number} config.number - 数字:不超过 10 位
- @param {string} config.theme - 主题:默认 asoul,可选 ['asoul','gelbooru','gelbooru-h','moebooru','moebooru-h','rule34']
- @param {number} config.length - 长度:1 ~ 10
- @param {string} config.rootUrl - 根 url:通常不需要改,除非比 jsdelivr 更快
食用方法
引入
import {createImageSrc} from '@/untils'
调用
createImageSrc({
number:123456789,
length:10,
theme:'gelbooru'
})
返回
[
"//fastly.jsdelivr.net/gh/journey-ad/Moe-counter@master/assets/theme/gelbooru/0.gif",
"//fastly.jsdelivr.net/gh/journey-ad/Moe-counter@master/assets/theme/gelbooru/1.gif",
"//fastly.jsdelivr.net/gh/journey-ad/Moe-counter@master/assets/theme/gelbooru/2.gif",
"//fastly.jsdelivr.net/gh/journey-ad/Moe-counter@master/assets/theme/gelbooru/3.gif",
"//fastly.jsdelivr.net/gh/journey-ad/Moe-counter@master/assets/theme/gelbooru/4.gif",
"//fastly.jsdelivr.net/gh/journey-ad/Moe-counter@master/assets/theme/gelbooru/5.gif",
"//fastly.jsdelivr.net/gh/journey-ad/Moe-counter@master/assets/theme/gelbooru/6.gif",
"//fastly.jsdelivr.net/gh/journey-ad/Moe-counter@master/assets/theme/gelbooru/7.gif",
"//fastly.jsdelivr.net/gh/journey-ad/Moe-counter@master/assets/theme/gelbooru/8.gif",
"//fastly.jsdelivr.net/gh/journey-ad/Moe-counter@master/assets/theme/gelbooru/9.gif"
]
预览图
Vue 使用
<template>
<div class="show">
<div class="images-wapper">
<img v-for="(src,index) in imageSrc1" :key="index" :src="src" alt="">
</div>
<div class="images-wapper">
<img v-for="(src,index) in imageSrc2" :key="index" :src="src" alt="">
</div>
<div class="images-wapper">
<img v-for="(src,index) in imageSrc3" :key="index" :src="src" alt="">
</div>
<div class="images-wapper">
<img v-for="(src,index) in imageSrc4" :key="index" :src="src" alt="">
</div>
<div class="images-wapper">
<img v-for="(src,index) in imageSrc5" :key="index" :src="src" alt="">
</div>
<div class="images-wapper">
<img v-for="(src,index) in imageSrc6" :key="index" :src="src" alt="">
</div>
</div>
</template>
<script>
import { createImageSrc } from '@/untils'
export default {
name:'ShowView',
data:()=>({
imageSrc1:[],
imageSrc2:[],
imageSrc3:[],
imageSrc4:[],
imageSrc5:[],
imageSrc6:[],
}),
mounted(){
this.imageSrc1 = createImageSrc({
number:123456789,
length:10,
})
this.imageSrc2 = createImageSrc({
number:123456789,
length:10,
theme:'gelbooru',
})
this.imageSrc3 = createImageSrc({
number:123456789,
length:10,
theme:'gelbooru-h',
})
this.imageSrc4 = createImageSrc({
number:123456789,
length:10,
theme:'moebooru',
})
this.imageSrc5 = createImageSrc({
number:123456789,
length:10,
theme:'moebooru-h',
})
this.imageSrc6 = createImageSrc({
number:123456789,
length:10,
theme:'rule34',
})
}
}
</script>
vue scss 项目使用 stylelint
vue-cli 在创建项目可以选择使用 eslint 去格式化 vue 代码,但是无法对 .vue 文件样式进行格式,所以需要自己配置一下 stylelint。
安装包文件
npm i -g stylelint
npm i -D stylelint-config-standard stylelint-order postcss-html stylelint-config-recommended-vue stylelint-config-standard-scss
虽然包比较多,但是都比较小,所以安装的很快。
这些包大多都是一些事先配置好的规则。
创建 .stylelintrc.js 文件
直接下载放到根目录即可
然后修改 package.json 文件
"scripts": {
"serve": "vue-cli-service serve",
"build": "vue-cli-service build",
"lint": "stylelint src/**/*.vue src/**/*.scss --fix && vue-cli-service lint",
"lint:scss": "stylelint src/**/*.vue src/**/*.scss --fix"
},
之后执行 npm run lint
即可
配置 scss 全局变量
在 vue.config.js
文件中加入:
module.exports = defineConfig({
transpileDependencies: true,
lintOnSave: false,
css: {
loaderOptions: {
sass: {
additionalData: `
@import "~@/index.scss";
`,
},
},
},
});
如果不喜欢用 stylelint ,可以试试 tailwindcss
参考
https://juejin.cn/post/6995973631238995998
https://stylelint.io/migration-guide/to-14/#syntax-option-and-automatic-inferral-of-syntax
https://www.npmjs.com/package/stylelint-config-recommended-vue
不玩手游
不玩手游了,明日方舟和原神都停了,毕竟自己现实生活一团糟,不玩手游来给自己多腾出时间也是好事。
Vue 插槽使用
刚接触 vue,感觉有点难度,对 vue 插槽的基础用例记录下,其中有 vue 插槽的基础用法、编译作用域、后备内容、具名插槽、作用域插槽、解构插槽 prop 的使用用例。
基础例子
一个带有插槽的组件
Vue.component('navigation-link',{
props:{
url:{
type:String,
required:false,
default:'/'
}
},
template:`
<a
:href="url"
class="nav-link"
>
<slot></slot>
</a>
`
})
使用
<navigation-link :url="'/profile'">Your Profile</navigation-link>
编译作用域
父级模板里的所有内容都是在父级作用域中编译的;子模板里的所有内容都是在子作用域中编译的。
navigation-link不可以访问子组件的作用域,只能访问父级模板的作用域,比如接受的url是访问不到的。
后备内容
在标签内的为后备内容
Vue.component('submit-button',{
template:`
<button type="submit">
<slot>Submit</slot>
</button>
`
})
在使用组件时没有写内容,默认展示Submit
具名插槽
Vue.component('base-layout',{
template:`
<div>
<header>
<slot name="header"></slot>
</header>
<main>
<slot name="default"></slot>
</main>
<footer>
<slot name="footer"></slot>
</footer>
</div>
`
})
在使用时,建议使用具名插槽的缩写,并且不省略default插槽
模板的头部
模板的内容
模板的footer
作用域插槽
让插槽内容可以访问子组件数据
//组件
<slot name="default" :base-layout-data="baseLayoutData"></slot>
//使用
<template #default="slotProps" >
<h1>模板的内容{{slotProps}}</h1>
</template>
其中baseLayoutData是子组件的数据,slotProps是绑定到插槽的数据。
解构插槽prop
<template #default="{baseLayoutData}" >
<h1>模板的内容{{baseLayoutData}}</h1>
</template>
//将数据解构并重新命名
<template #default="{baseLayoutData:childrenData}" >
<h1>模板的内容{{childrenData}}</h1>
</template>
//将数据解构并重新命名并给予默认值以应对undefined的情况
<template #default="{baseLayoutData:childrenData='123'}" >
<h1>模板的内容----{{childrenData}}</h1>
</template>
Vue 中 ref 使用注意事项
之前在使用 ref 时,只知道可以获取 dom 元素,其实 ref 还有一些其他的用法,在此记录下。原文时间:2020-10-16 23:29
获取dom元素
<p ref="refP">我是一个简单的p标签</p>
console.log(this.$refs.refP.innerHTML)
//我是一个简单的p标签
获取子组件的实例,用来调用子组件的方法(这个用的非常多)
<child-component ref="childComponent"></child-component>
Vue.component('child-component', {
methods: {
logData() {
console.log('我是子组件的方法')
}
},
template: `<div>我是子组件</div>`
})
this.$refs.childComponent.logData()
配合 v-for 获取一组dom元素
获取使用v-for的li元素
<ul>
<li v-for="people in peoples" :key="people" ref="refPeoples">
<span>{{ people }}</span>
</li>
</ul>
获取使用v-for的li元素中的span
<ul>
<li v-for="people in peoples" :key="people">
<span ref="refPeoples">{{ people }}</span>
</li>
</ul>
获取手写的列表
<ul>
<li key="小明" ref="refPeoples">小明</li>
<li key="小红" ref="refPeoples">小红</li>
<li key="小刚" ref="refPeoples">小刚</li>
</ul>
关于网盘及如何白嫖
用过很多网盘,但感觉都差不多,用的最多的还是百度网盘,毕竟现在基本不可能绕过百度网盘,不过除了百度网盘还是有一些其他不错的网盘的。
百度网盘
目前已经无法绕过的一个网盘,建议配合IDM使用,在不开会员的情况下可以达到700k~2m/s的下载速度。
淘宝买年费会员198,最便宜的时候是178元一年。
用的人多了举报资源的人也多😏。
奶牛快传
不多说了,直接看图,强制付费,md还好我没存啥重要的东西。
文叔叔
不限速,免费20g,做任务最多扩到30g。
超过20g购买空间贼贵!感觉不是给个人用的,应该是给企业用的。
蓝奏云
个人非常推荐的一个"小"网盘,只能上传分享一些小文件(100m以内的)。
腾讯微云
最近没怎么关注过,身边用的人也不多。
在线浏览视频和听音乐比较慢,淘宝买年费大概100多点。
115网盘
自己没用过,不过听说功能很强大。
建议618、双11、双12买会比较便宜,最便宜的时候是500元三年。
曲奇云盘
免费2t空间,在不开会员的情况下配合IDM下载速度有1m/s左右。
用了下还是有点坑的,不是很推荐。
OneDrive
国内用起来不是很舒服。
免费5g,不限速,家庭1t套餐很便宜,据说有特殊优惠的话5t套餐也很便宜。
mega
免费15g,上传速度有点慢,下载不限速。
购买额外的空间很贵,毕竟是欧元换算过来的。
icloud
苹果的网盘服务,和ios、mac系统兼容性非常好。
性价比比较低,不能通过网址分享文件。
katfile等国外网盘
基本是必须付费的,不然你会享受到限速50k~100k/s、下载文件等30s、且两次下载时间间隔要1~3小时的优质限制服务。
付费且价格很贵,并且国内不好用。
如何白嫖
之前找到了个白嫖百度网盘的方法,不过现在又失效了,有点尴尬😅。
还有一种方法是可以免费注册 5t 的onedrive,注册方法自行谷歌,不过不能保证账号的稳定性。
总结
本来还挺想推荐一些小众的网盘的,但是还是算了,因为指不定哪天就和奶牛快传一样了,不敢说了😅。
如果你只是存储资源,不分享,可以将资源保存到u盘、移动硬盘、个人云存储,这是最稳的。
不推荐使用小众网盘,如果要使用,建议本地也要备份一下。
如果你分享一些违规或敏感资源,最好的是使用mega、onedrive、googledrive这类加密传输的网盘,或者可以百度网盘配合秒传链接(不能保证完全不炸),国内有些网盘甚至会直接把你的违规资源删掉。
个人认为网盘有一个很重要的功能就是在线播放音乐和视频,尤其是视频的加载速度。
快速下载百度网盘资源的方法
百度网盘非会员下载太慢了,介绍几种加快下载百度网盘的方法,都是个人亲测管用的。因为不能确保时效性,所以附上如何找这些快速下载的方法。
IDM下载
IDM正版本身是收费的,不过有大神制作了破解工具和可以直接使用的破解版。
备用
解压码: 7w28
下载之后会自动为google浏览器安装一个IDM Integration Module的插件,如果没有需要自行安装下。
安装油猴和百度网盘下载助理
油猴安装自行百度。
百度网盘下载助理安装需要在安装了油猴的前提下才可以安装。
下载地址
使用
安装了百度网盘下载助理之后打开pan.baidu.com就可以看到下载助手按钮。
然后 选择要下载的文件->下载助手->API下载获取下载地址->点击下载链接即可自动打开IDM下载文件。
IDM 下载的问题
不开会员仍然会被百度限速(大概10g之后),然后需要过一段时间解除。
解析下载
解析下载的问题
- 不能直接下载文件夹。
- 打开文件夹有时会报错。
- 多数解析站点不是很稳定,时好时坏是很正常的。
如何自己找下载方法呢?
- Telegram搜索 KinhDown 加群。
- 404搜索 下载百度网盘->看最近更新的方法。
yarn 命令和 npm 命令
npm、cnpm、yarn都是包管理工具,但是使用下来还是有些细微的差距的,使用下来个人感觉还是yarn更好用些。原文时间:2020-11-10 14:16
最近开始使用yarn管理,主要因为npm使用起来太慢了,cnpm下载文件不全。
不过yarn的命令和npm相比还是有点区别的.
命令 | yarn | npm |
---|---|---|
初始化 | yarn init | npm init |
安装packjson依赖 | yarn | npm install |
安装依赖 | yarn add moment [--save] | npm insall moment -S |
安装开发依赖 | yarn add webpack --dev | npm install webpack -D |
安装全局依赖 | yarn global add webpack | npm install webpack -D |
移除依赖 | yarn remove moment | npm uninstall moment |
更新依赖 | yarn upgrade moment | npm update moment |
运行scripts命令 | yarn start | npm run start |
如果觉得使用yarn下载很慢,也可以使用tyarn。
安装方式:
yarn global add tyarn
记录 typecho 添加 live2d
live2d 如今在网站中已经非常常见了,不过自己制作 live2d 还是很麻烦,所以通常需要用到大佬制作好的 live2d 配合一些插件来使用。
安装Pio插件
里面有很详细的安装方式就不说啦。
更换模型
模型站点 https://mx.paul.ren/
选择使用的模型下载,将文件放到插件目录下的 plugins/Pio/models/下,这样就可以在插件设置选择其他的模型了
交互提示扩展
这个可以看插件的文档的content,地址
文档中给了一个完整的例子
{ "welcome": ["你好,欢迎来到保罗的小窝", "我是从云,傲完就娇的从云~"], "touch": ["你这个绅士!", "别碰我!"], "skin": ["想看看我的新服装吗?", "新衣服真漂亮~"], "home": "点击这里回到首页!", "link": "https://paul.ren/about", "close": "QWQ 有缘再会吧~", "referer": "你通过 %t 来到了这里", "custom": [ { "selector": ".comment-form", "text": ["欢迎参与本文评论,别发小广告噢~", "快来参加本文的评论吧~"] } ] }
welcome表示默认进入,touch表示每次点击模型,其他的配置文档都有详细说明
2020-10-12 日常笔记
通过 APlayer-Typecho 为 typecho 博客添加音乐播放器并使用网易音乐的歌单,Vue 监听器 watch,Vue Router 简单的入门。
typecho添加音乐播放器
下载插件APlayer-Typecho
github地址
在文章页面点击插入音乐按钮,输入音乐链接即可,不过在使用时,qq音乐好像已经不管用了,网易音乐还可以使用,其他的音乐平台没有试。
[Meting]
[Music server="netease" id="35345760" type="song"/]
[/Meting]
Vue 监听器
watch监听路由
const BComponent = {
watch: {
$route:{
handler(to, from) {
console.log(to,from);
},
immediate:true
}
},
template:`<h1>B组件{{$route.params.id}}</h1>`
}
watch参数
handler
默认情况下,写的函数就是handler
handler(newVal,oldVal){}
immediate
默认为false,进入页面时,第一次绑定值,不会立刻执行监听,只有当数据发生改变才会执行handler中的操作
改为true之后,handler会在第一次绑定值的时候就触发
deep
默认为false
vue不能检测到对象属性的添加或删除,使用watch监听一个对象时,除非是直接重新给对象赋值,否则是不能监听到对象里的指的变化的。
将deep设置为true后,就可以监听到对象属性的变化
Vue Router
基础使用
<div id="app">
<router-link to="/a">A组件</router-link>
<router-link to="/b">B组件</router-link>
<hr>
<router-view></router-view>
</div>
<script src="https://unpkg.com/vue/dist/vue.js"></script>
<script src="https://unpkg.com/vue-router/dist/vue-router.js"></script>
<script>
const AComponent = {template:`<h1>A组件</h1>`}
const BComponent = {template:`<h1>B组件</h1>`}
const routes = [
{path:'/a',component:AComponent},
{path:'/b',component:BComponent},
]
const router = new VueRouter({
routes
})
const app = new Vue({
router,
}).$mount('#app')
</script>
动态路由匹配
const routes = [
{path:'/a',component:AComponent},
{path:'/b/:id',component:BComponent},
]
访问/b/123 ,通过this.$route.params.id可以得到匹配到的id
路由通配符
{
// 会匹配所有路径
path: '*'
}
{
// 会匹配以 `/user-` 开头的任意路径
path: '/user-*'
}
匹配优先级
有时候,同一个路径可以匹配多个路由,此时,匹配的优先级就按照路由的定义顺序:谁先定义的,谁的优先级就最高。
嵌套路由
嵌套路由的path不在以/开头,因为/代表根的意思。
嵌套的子路由在routes的children属性中配置。
<div id="app">
<router-link to="/home">首页</router-link>
<router-link to="/post-list">文章</router-link>
<hr>
<router-view></router-view>
</div>
<script src="https://unpkg.com/vue/dist/vue.js"></script>
<script src="https://unpkg.com/vue-router/dist/vue-router.js"></script>
<script>
const postList = [
{id:1,title:'文章1',content:'文章1内容'},
{id:2,title:'文章2',content:'文章2内容'},
{id:3,title:'文章3',content:'文章3内容'},
{id:4,title:'文章4',content:'文章4内容'},
]
const Home = {
template:'<h1>首页</h1>'
}
const notFoundPost = {
template:'<h1>请选择文章</h1>'
}
const PostListComponent = {
data(){
return {
postList
}
},
template:`
<div>
<router-link
v-for="post in postList"
:key="post.id"
:to="'/post-list/'+post.id"
>
{{post.title}}
</router-link>
<hr></hr>
<router-view></router-view>
</div>
`
}
const postContentComponent = {
data(){
return {
postList
}
},
computed:{
postTitle(){
return this.postList.find(item=>''+item.id === this.$route.params.id).title
},
postContent(){
return this.postList.find(item=>''+item.id === this.$route.params.id).content
}
},
template:`
<div>
<h1>{{postTitle}}</h1>
<p>{{postContent}}</p>
</div>
`
}
const routes = [
{path:'/home',component:Home},
{path:'/post-list',component:PostListComponent,
children:[
//当访问/post-list,PostListComponent出口渲染写什么
{
path:'',component:notFoundPost
},
{
path:':id',component:postContentComponent
}
]
},
]
const router = new VueRouter({routes})
const app = new Vue({
router,
}).$mount('#app')
</script>
提供空的子路由
const routes = [
{path:'/home',component:Home},
{path:'/post-list',component:PostListComponent,
children:[
//当访问/post-list,PostListComponent出口渲染写什么
{
path:'',component:notFoundPost
},
{
path:':id',component:postContentComponent
}
]
},
]
访问访问/post-list,PostListComponent出口是不会渲染任何东西,可以提供一个path为空字符串的子路由。
编程式导航
router.push
// 字符串
router.push('home')
// 对象
router.push({ path: 'home' })
// 命名的路由
router.push({ name: 'user', params: { userId: '123' }})
// 带查询参数,变成 /register?plan=private
router.push({ path: 'register', query: { plan: 'private' }})
如果提供了 path,params 会被忽略,上述例子中的 query 并不属于这种情况。取而代之的是下面例子的做法,你需要提供路由的 name 或手写完整的带有参数的 path
const userId = '123'
router.push({ name: 'user', params: { userId }}) // -> /user/123
router.push({ path: `/user/${userId}` }) // -> /user/123
// 这里的 params 不生效
router.push({ path: '/user', params: { userId }}) // -> /user
router.replace
router.replace和router.push很像,唯一不同的是router.replace不会向 history 添加新记录
router.go
在 history 记录中向前或者后退多少步
router.go(1) //前进一步
router.go(-1) //后退一步
router.go(100) //如果超出history记录,会执行失败
命名路由
如果使用命名路由,如果目的地和当前路由相同,只有参数发生了改变 比如从一个用户资料到另一个 /users/1 -> /users/2 ,需要使用watch监听$route 或 beforeRouteUpdate来响应这个变化。
routes: [
{
path: '/user/:userId',
name: 'user',
component: User
}
]
访问
{ name: 'user', params: { userId: 123 }}
命名视图
<div id="app">
<router-view></router-view>
<router-view name="a"></router-view>
<router-view name="b"></router-view>
</div>
<script src="https://unpkg.com/vue/dist/vue.js"></script>
<script src="https://unpkg.com/vue-router/dist/vue-router.js"></script>
<script>
const Bar = {template:`<h1>Bar区域</h1>`}
const Baz = {template:`<h1>Baz区域</h1>`}
const Foo = {template:`<h1>Foo区域</h1>`}
const routes = [
{
path:'/',
components:{
default:Foo,
a:Bar,
b:Baz
}
}
]
const router = new VueRouter({routes})
const app = new Vue({
router
}).$mount('#app')
</script>
重定向
在routes设置redirect
const routes = [
{path:'/news',name:'news',component:News},
//访问/a,会重定向到/news
// {path:'/a',redirect:'/news'}
// {path:'/a',redirect:{name:'news'}}
{path:'/a',redirect:to => {
console.log(to);
return {name:'news'}
}}
]
别名
在routes设置alias
const routes = [
//访问/a,URL仍会保持为/a,但显示和/news一样
{path:'/news',name:'news',component:News,alias:'/a'}
]
vuetify UI使用
记录一些 vuetify UI 使用方法。vuetify 作为 ui 框架非常简洁、而且官方也在持续不断的更新中,还是非常推荐学习的。原文时间:2020-10-20 22:01
vue-cli快速安装
vue add vuetify
使用中文
//引入中文文件
import { zhHans } from 'vuetify/lib/locale'
//添加到Vuetify配置中
export default new Vuetify({
lang: {
current: `zhHans`,
locales: { zhHans }
}
})
使用图标
Material icons
安装
yarn add material-design-icons-iconfont -D
在配置文件中引入
import 'material-design-icons-iconfont/dist/material-design-icons.css'
使用
local_hospital
Font Awesome
安装
yarn add [email protected] -D
在配置文件中引入
import 'font-awesome/css/font-awesome.min.css'
使用
fa-id-badge
#样式和动画
颜色
对于background-color
颜色: pink 亮度: lighten-4
对于字体color
颜色: pink--text 亮度: text--lighten-4
字体
对齐
<p class="text-left">Left aligned text on all viewport sizes.</p>
<p class="text-center">Center aligned text on all viewport sizes.</p>
<p class="text-right">Right aligned text on all viewport sizes.</p>
划线
删除线:text-decoration-line-through
text-decoration-overline
text-decoration-underline
不换行
.text-no-wrap
过渡效果
一个简单的x轴滑动过渡效果
<v-slide-x-transition>
<v-card outlined tile v-if="isShow">
<v-card-title>我是一个卡片标题</v-card-title>
</v-card>
</v-slide-x-transition>
<v-btn color="primary" @click="isShow = !isShow">切换</v-btn>
自带的组件提供了transition属性,可以直接写tranistion的name名称,以下是个例子
<div class="text-center" transition="slide-x-transition">
<v-menu offset-y>
<template v-slot:activator="{ on, attrs }">
<v-btn color="primary" dark v-bind="attrs" v-on="on">
Dropdown
</v-btn>
</template>
<v-list>
<v-list-item v-for="(item, index) in items" :key="index" @click="">
<v-list-item-title>{{ item.title }}</v-list-item-title>
</v-list-item>
</v-list>
</v-menu>
</div>
也可以自定义过渡效果
import Vue from 'vue'
import { createSimpleTransition } from 'vuetify/lib/components/transitions/createTransition'
const myTransition = createSimpleTransition(`my-transition`)
Vue.component(`my-transition`, myTransition)
//style
.my-transition-leave-active,
.my-transition-enter-active {
transition: all 1s;
}
.my-transition-enter,
.my-transition-leave-to {
opacity: 0;
}
//html
<my-transition>
<v-card outlined tile v-if="isShow">
<v-card-title>卡片标题</v-card-title>
</v-card>
</my-transition>
<v-btn color="primary" @click="isShow = !isShow">切换</v-btn>
组件
由于组件太多了,所以只介绍几个平时用的多的
栅格
vuetify 内置栅格位 12 点栅格系统
在手机屏幕下一行一个,其他情况一行两个卡片
<v-row no-gutters>
<v-col cols="12" sm="6" class="my-sm-0 my-2">
<v-card class="pa-2" outlined tile>
栅格
</v-card>
</v-col>
<v-col cols="12" sm="6" class="my-sm-0 my-2">
<v-card class="pa-2" outlined tile>
栅格
</v-card>
</v-col>
</v-row>
数据表格
数据表格使用起来非常简单,只要准备好渲染的数据就行了。
通常必要的数据是header和items,即表头数据和行数据。
headers: [
{ text: `姓名`, value: `name` },
{ text: `性别`, value: `gender` },
{ text: `年龄`, value: `age` }
],
items: [
{ name: `小明`, gender: `男`, age: 12 },
{ name: `小红`, gender: `女`, age: 22 },
{ name: `小刚`, gender: `男`, age: 34 }
],
行选择框
<v-data-table
show-select
item-key="name"
single-select
:headers="headers"
:items="items"
></v-data-table>
行选择框必须设置 item-key 属性
大大大 事件!Bmob 收费了!
Bmob 后端云竟然要开始收费,看了下公告好像是 4月5号 开始的,写的资源站直接废了,对此我的评价是:寄!只希望 leancloud 别收费了,不然可太麻烦了。
按住 ctrl + 左键
可以新开标签页打开链接
在线看番
age动漫 - 备用网址:www.agefans.vip
233动漫网
zzzfun
动漫岛 - 发布网址:dm55.cc
樱花动漫
NT动漫
acg在线工具
trace - 以图搜番
saucenao - 找插图
iqdb - 找galgame
yuc - 新番列表
图床
SM.MS - 国内慎用
Postimages - 国内不要用
catbox - 限制200m,可以传一些非图片文件,比如mp3等
图片处理
docsmall
Squoosh
picdiet - 只支持 jpg & jpeg 图片压缩
bigjpg - 图片无损放大
番剧下载
acg资源
琉璃神社
灵梦御所 - ⑨
星月号
e-hentai - e站
exhentai - e站里站
绅士会所
飞机场
机场测速 - 毒药大佬的机场测速
foxicloud
樱花云 - 不推荐
ABCloud - 不推荐
可莉 - 不错 小贵
番茄.V2航线 - 不推荐
在线本子
。。。
Jable
avbebe - 包含一些里番。
jav111 - 找nvyou。
hpjav
音乐
漫音社 - acg音乐
galgame
维咔
绅士天堂
2dfan
忧郁的弟弟 - 不再更新
GalWorld
天使二次元
导航
插图
konachan - k站
konachan - k站里站
pixiv - 插图界p站
yande - 竖屏图居多
同人音声
japaneseasmr - 可直接在线听
ASMR Online
EroVoice
在线工具
萌娘百科 - 超好用的二次元百科。
evozi - 下载google play apk。
多邻国 - 学外语。
youtubemy - 下载youtube视频。
Markdown 入门参考
ping chinaz - 查询 ip 各个地区的ping值
speedtest - 测试网速
下载工具相关
里fan
MMD
iwara - i站
电影 && 电视剧
茶杯狐 - 电影 动漫 综艺
其他
Switch520
台灣最佳網路資源網站
字体天下 - 免费字体下载
emojiall - Emoji大全
yodhcn的收藏夹
一些不错的字体处理工具
一些不错的字体处理工具
从今天开始,不在手游氪金!
从开始玩手游到现在已经一年了,今天粗略的计算了下氪金量,一年下来氪了 3000 块左右,感觉很是后悔,如果用这些钱去做其它事情会不会更好呢?🤔
💰是否由更好的用途
从开始玩手游到现在已经一年了,今天粗略的计算了下氪金量,一年下来氪了 3000 块左右,感觉很是后悔,如果用这些钱去做其它事情会不会更好呢?🤔
就吃饭而言:早餐10元,午餐20元,晚餐20元,3000块可以吃整整2个月。
氪金真的带来了快乐吗?
在手游中,有很多限时获取的物品,它会的让自己想到,如果错过了这个机会,那下个机会不知道什么时候才来啊。
但是仔细想了想,实际上那些限时获取的物品只不过是游戏厂商用来赚钱的工具罢了,所谓的限时只是为了能够获得更高的流水而已,即使获取不到也不会影响什么。
氪金获得与白嫖获得
自己 648 获得物品,别人白嫖一发十连也同样的得到了,这是不是很气,当然你说没必要跟别人比较,自己开心就好,但是自己648下去和别人白嫖得到的是一样的,我这个648冲了个💨。
白嫖的爽
-
可以很容易的弃游,如果花了很多钱玩这个游戏,想要弃游一定会舍不得吧,更何况现在手游账号贬值的特别厉害。
-
可以简单把手游当作休闲网游看待。
-
白嫖本身就很爽!
发誓
---以后再充钱玩手游我是🐕!!!---
04-28的小错误
TypeError [ERR_INVALID_CHAR]: Invalid character in header content 错误,可以使用 encodeURI 处理特殊字符解决
{
Bucket: s3Bucket,
CopySource: encodeURI(join(`${s3Bucket}`,`${sourcePath}`).replace(/\\/g,'/')),
Key: newPath, // 目标路径
}
2020-10-14 日常笔记
vue-devtools 调试工具安装。Vue 状态管理,包括 state、getter、mutation 、action、辅助函数以及命名空间的用法。
vue-devtools调试工具安装
下载地址
点击下载zip压缩包
解压之后npm intsall ,如果不成功用下 cnpm install 或 yarn
接着npm run build
打开谷歌浏览器,更多工具-扩展程序-开发者模式-加载已解压的扩展程序-选择目录下的\shells\chrome目录即可
简单的状态管理
store模式!
<div id="vmA">当前数据:{{sharedState.message}}
<button @click="setMessageAction('新数据')">更改数据</button>
<button @click="clearMessageAction()">清除数据</button>
</div>
<div id="vmB">当前数据:{{sharedState.message}}</div>
<script src="https://unpkg.com/vue/dist/vue.js"></script>
<script>
var store = {
debug: true,
state: {
message: 'Hello!'
},
setMessageAction (newValue) {
if (this.debug) console.log('setMessageAction triggered with', newValue)
this.state.message = newValue
},
clearMessageAction () {
if (this.debug) console.log('clearMessageAction triggered')
this.state.message = ''
}
}
var vmA = new Vue({
el:'#vmA',
data: {
privateState: {},
sharedState: store.state
},
methods:{
setMessageAction(newValue){
store.setMessageAction(newValue)
},
clearMessageAction(){
store.clearMessageAction()
}
}
})
var vmB = new Vue({
el:'#vmB',
data: {
privateState: {},
sharedState: store.state
}
})
</script>
注意点:
- 不应该在 action 中 替换原始的状态对象 - 组件和 store 需要引用同一个共享对象,变更才能够被观察到。
- 组件不允许直接变更属于 store 实例的 state,而应执行 action 来分发 (dispatch) 事件通知 store 去改变。
Vuex
如果是开发中大型单页面应用,应使用Vuex,如果应用足够简单,一个小型的store模式就可以了。
一个简单的计数器
<div id="app">
{{$store.state.count}}
<button @click="increment">增加</button>
<button @click="decrease">减少</button>
</div>
<script src="https://unpkg.com/vue/dist/vue.js"></script>
<script src="https://unpkg.com/[email protected]/dist/vuex.js"></script>
<script>
const store = new Vuex.Store({
state:{
count:0
},
mutations:{
increment(state){
state.count++
},
decrease(state){
state.count--
}
}
})
const app = new Vue({
el:'#app',
store,
computed:{
count(){
return this.$store.state.count
}
},
methods:{
increment(){
this.$store.commit('increment')
},
decrease(){
this.$store.commit('decrease')
}
}
})
</script>
State
从 store 实例中读取状态最简单的方法就是在计算属性 中返回某个状态
<div id="app">
{{message1}}
{{message2}}
{{message3}}
</div>
<script src="https://unpkg.com/vue/dist/vue.js"></script>
<script src="https://unpkg.com/[email protected]/dist/vuex.js"></script>
<script>
const store =new Vuex.Store({
state:{
message1:'消息1',
message2:'消息2',
message3:'消息3',
}
})
const app = new Vue({
el:'#app',
store,
computed:{
message1(){
return this.$store.state.message1
},
message2(){
return this.$store.state.message2
},
message3(){
return this.$store.state.message3
},
}
})
</script>
但是每一个状态都需要在computed写入太麻烦了,可以使用辅助函数 mapState
computed:{
//数组形式
...Vuex.mapState(['message1','message2','message3'])
//对象形式
...Vuex.mapState({
msg1:'message1',
msg2:'message2',
msg3:'message3',
}),
}
Getter
getter可以认为是 store 的计算属性
const store =new Vuex.Store({
state:{
todos: [
{ id: 1, text: '事项1', done: true },
{ id: 2, text: '事项2', done: false },
{ id: 3, text: '事项3', done: false },
{ id: 4, text: '事项4', done: true },
{ id: 5, text: '事项5', done: true },
]
},
getters:{
doneTodos(state){
return state.todos.filter(todo=>todo.done)
},
doneTodosCount: (state, getters) => {
return getters.doneTodos.length
}
}
})
const app = new Vue({
el:'#app',
store,
computed:{
doneTodos(){
return this.$store.getters.doneTodos
},
doneTodosCount(){
return this.$store.getters.doneTodosCount
}
}
})
你也可以通过让 getter 返回一个函数,来实现给 getter 传参。在你对 store 里的数组进行查询时非常有用。
getter 在通过方法访问时,每次都会去进行调用,而不会缓存结果。
getters:{
doneTodos(state){
return state.todos.filter(todo=>todo.done)
},
doneTodosCount(state, getters) {
return getters.doneTodos.length
},
getTodoById:(state) => (id)=>{
return state.todos.find(todo=>todo.id === id)
}
}
mapGetters辅助函数
//使用mapGetters
...Vuex.mapGetters(['doneTodos','doneTodosCount','getTodoById'])
Mutation
更改 Vuex 的 store 中的状态的唯一方法是提交 mutation。
const store = new Vuex.Store({
state: {
count: 1
},
mutations: {
increment (state) {
state.count++
}
}
})
const app = new Vue({
el:'#app',
store,
computed:{
...Vuex.mapState({
count:'count',
}),
},
methods:{
increment(){
this.$store.commit('increment')
}
}
})
提交载荷(Payload)
向 store.commit 传入额外的参数,即 mutation 的 载荷(payload)
通常情况下,载荷应该是一个对象。
const store = new Vuex.Store({
state: {
count: 1
},
mutations: {
increment (state,payload) {
state.count += payload.amount
}
}
})
const app = new Vue({
el:'#app',
store,
computed:{
...Vuex.mapState({
count:'count',
}),
},
methods:{
increment(){
this.$store.commit('increment' ,{
amount: 10
})
}
}
})
对象风格的提交方式
当使用对象风格的提交方式,整个对象都作为载荷传给 mutation 函数
this.$store.commit({
type: 'increment',
amount: 10
})
Mutation 需遵守 Vue 的响应规则
当需要在对象上添加新属性时,你应该
使用 Vue.set(obj, 'newProp', 123)
以新对象替换老对象。
state.obj = { ...state.obj, newProp: 123 }
//或者
state.obj = Object.assign({},state.obj,newProp:123)
mapMutations辅助函数
methods:{
//数组形式
...Vuex.mapMutations(['increment']),
//对象形式
...Vuex.mapMutations({
incre:'increment'
}),
}
Action
Action 类似于 mutation,不同在于:
Action 提交的是 mutation,而不是直接变更状态。
Action 可以包含任意异步操作。
一个简单的例子
const store = new Vuex.Store({
state: {
count: 1
},
mutations: {
increment (state,payload) {
state.count += payload.amount
}
},
actions:{
increment({commit},payload){
setTimeout(()=>{
commit('increment',payload)
},1000)
}
}
})
const app = new Vue({
el:'#app',
store,
computed:{
...Vuex.mapState({
count:'count',
}),
},
methods:{
increment(){
this.$store.dispatch('increment',{amount:10})
}
}
})
分发 Action
Action 通过 store.dispatch 方法触发
//以载荷的形式触发
this.$store.dispatch('increment',{amount:10})
//以对象的形式触发
this.$store.dispatch({
type: 'increment',
amount: 10
})
mapActions
//数组形式
...Vuex.mapActions(['increment']),
//对象形式
...Vuex.mapActions({
add:'increment'
}),
store.dispatch 可以处理被触发的 action 的处理函数返回的 Promise,并且 store.dispatch 仍旧返回 Promise
Module
关于模块的东西比较多,这里只记一些知识点,详细查看文档。
每个模块拥有自己的 state、mutation、action、getter、甚至是嵌套子模块。
模块的局部状态和根节点状态
对于模块内部的 action,局部状态通过 context.state 暴露出来,根节点状态则为 context.rootState
actions: {
incrementIfOddOnRootSum ({ state, commit, rootState }) {
if ((state.count + rootState.count) % 2 === 1) {
commit('increment')
}
}
}
对于模块内部的 getter,根节点状态会作为第三个参数暴露出来
getters: {
sumWithRootCount (state, getters, rootState) {
return state.count + rootState.count
}
}
命名空间
默认情况下,模块内部的 action、mutation 和 getter 是注册在全局命名空间的——这样使得多个模块能够对同一 mutation 或 action 作出响应。
如果希望你的模块具有更高的封装度和复用性,你可以通过添加 namespaced: true 的方式使其成为带命名空间的模块。
在带命名空间的模块内访问全局内容(Global Assets)
如果你希望使用全局 state 和 getter,rootState 和 rootGetters 会作为第三和第四参数传入getter,也会通过 context 对象的属性传入 action。
若需要在全局命名空间内分发 action 或提交 mutation,将 { root: true } 作为第三参数传给 dispatch 或commit 即可。
modules: {
foo: {
namespaced: true,
getters: {
// 在这个模块的 getter 中,`getters` 被局部化了
// 你可以使用 getter 的第四个参数来调用 `rootGetters`
someGetter (state, getters, rootState, rootGetters) {
getters.someOtherGetter // -> 'foo/someOtherGetter'
rootGetters.someOtherGetter // -> 'someOtherGetter'
},
someOtherGetter: state => { ... }
},
actions: {
// 在这个模块中, dispatch 和 commit 也被局部化了
// 他们可以接受 `root` 属性以访问根 dispatch 或 commit
someAction ({ dispatch, commit, getters, rootGetters }) {
getters.someGetter // -> 'foo/someGetter'
rootGetters.someGetter // -> 'someGetter'
dispatch('someOtherAction') // -> 'foo/someOtherAction'
dispatch('someOtherAction', null, { root: true }) // -> 'someOtherAction'
commit('someMutation') // -> 'foo/someMutation'
commit('someMutation', null, { root: true }) // -> 'someMutation'
},
someOtherAction (ctx, payload) { ... }
}
}
}
在带命名空间的模块注册全局 action
actions: {
increment:{
root:true,
handler({rootState}){
rootState.count++
}
}
},
带命名空间的绑定函数
...Vuex.mapState('a',{
aCount:'count'
})
一个简单模块的示例
import { getNewsList } from '@/api/News'
import Store from '@/store'
export default {
namespaced:true,
state:{
newsList:[]
},
getters:{
getNewsList(state){
if(state.newsList.length===0){
Store.dispatch(`news/getNewsList`)
}
return state.newsList
},
getNews: (state,getters) => (param)=>{
return getters.getNewsList.find(item=>``+item.id === ``+param.id)
},
getNewsbyTitle: (state,getters) => (param)=>{
return getters.getNewsList.filter((item) => {
return item.title.indexOf(param.key) !== -1
})
}
},
mutations:{
getNewsList(state,newsList){
state.newsList = newsList
}
},
actions:{
async getNewsList({commit}){
const newsList = await getNewsList()
commit(`getNewsList`,newsList)
}
}
}
VPS 搭建宝塔面板和 V2-UI
最近使用 vps 实现了科学上网和网站搭建,不过个人感觉如果只是为了科学上网使用 vps 并不是很划算。
注意事项
- 使用系统为 centos8
- vps 尽量不要买私人或月抛,尤其是很便宜的那种,分分钟翻车
- vps 的带宽实际能跑出的速度只有 1/8 左右,比如 1M 带宽 实际只能跑出不到 128kb/s 的速度
- vps 的线路和地区对速度的影响非常大,如果 vps 本身 “质量” 不够硬的话,翻墙体验会很糟糕
- vps 最好买可以退款的商家
购买 vps
最好买香港的,因为香港是最快的,其次是日本、新加坡、韩国、欧美地区的。
购买之后 win + r 输入 cmd 打开终端 ping 下 vps 的 ip
ping ip -t
机器刚购买后可能需要1~2分钟的启动时间,这时候 ping 不通很正常
多次 ping 测试,有一次 ping 不通就直接换个或退款吧,大多数 vps 商家都是支持退款的
购买域名
不要选择大陆的域名提供商,不要选择.cn和中文后缀的域名
我用的是 godaddy ,第一年比较便宜,后面就贵了,建议买一年的
然后解析域名
将你买到域名解析到你的 vps 的 ip 上
连接vps并更新
连接使用 putty xshell 都行
更新执行以下命令,时间可能有点长
yum update -y && yum install curl -y
关闭selinux
有些厂商默认就是关闭的,所以需要先看看 selinux 的状态
查看SELinux状态,enabled表示开启
/usr/sbin/sestatus -v
更改 selinux 的状态
修改/etc/selinux/config 文件
将SELINUX=enforcing改为SELINUX=disabled
//然后重启vps
搭建v2-ui
bash <(curl -Ls https://blog.sprov.xyz/v2-ui.sh)
然后放行65432端口,使用acme申请ssl证书
ACME申请ssl证书
安装acme
curl https://get.acme.sh | sh
设置 Cloudflare API 令牌
export CF_Key="Global API Key"
export CF_Email="cloudflare账号的emali"
验证 DNS 并申请证书
1. ~/.acme.sh/acme.sh --issue --dns dns_cf -d 域名 -d *.域名
2. mkdir /root/cert
3. ~/.acme.sh/acme.sh --installcert -d 域名 --key-file /root/cert/private.key --fullchain-file /root/cert/cert.crt
4. ~/.acme.sh/acme.sh --upgrade --auto-upgrade
5. chmod -R 755 /root/cert
查看/root/cert目录
这就是证书和密钥,建议在本地也保存起来
新建个节点
下载客户端试试行不行
设置客户端的路由
默认情况,所有的流量都是走代理的,你可能需要只代理非大陆的请求,这里需要简单的设置一下
这就可以了,然后打开youtube google等网站试试
宝塔面板
vps 除了搭建科学上网之外,cpu 内存足够的话完全可以在搭建个宝塔面板。
安装面板
yum install -y wget && wget -O install.sh http://download.bt.cn/install/install_6.0.sh && sh install.sh
有提示输入 y 然后 enter 即可
取消强制绑定手机号
sed -i "s|bind_user == 'True'|bind_user == 'XXXX'|" /www/server/panel/BTPanel/static/js/index.js
面板设置
主要是修改一下默认端口即可,至此宝塔面板就搭建完成
补充
启用bbr加速
提示:有些脚本会默认帮你启动bbr,不需要自行启动
启动命令
echo "net.core.default_qdisc=fq" >> /etc/sysctl.conf
echo "net.ipv4.tcp_congestion_control=bbr" >> /etc/sysctl.conf
sysctl -p
查看是否启动
sysctl -n net.ipv4.tcp_congestion_control
lsmod | grep bbr
关于端口的一些操作
查看端口占用信息:netstat -tunlp
- 显示状态: firewall-cmd --state
- 查看所有打开的端口: firewall-cmd --zone=public --list-ports
- 更新防火墙规则: firewall-cmd --reload
- 那怎么开启一个端口呢: firewall-cmd --zone=public --add-port=80/tcp --permanent (–permanent 永久生效,没有此参数重启后失效)
- 重新载入: firewall-cmd --reload 修改 firewall-cmd 配置后必须重启
- 查看: firewall-cmd --zone= public --query-port=80/tcp
- 删除: firewall-cmd --zone= public --remove-port=80/tcp --permanent
Syetemclt 管理服务常用命令
- 启动服务:systemctl start httpd
- 关闭服务:systemctl stop httpd
- 重启服务:systemctl restart httpd
- 查看一个服务的状态:systemctl status httpd
- 查看一个服务是否在运行:systemctl is-active httpd
- 查看当前已经运行的服务:systemctl list-units -t service
- 列出所有服务: systemctl list-units -at service
- 设置开机自启动: systemctl enable httpd
- 停止开机自启动: systemctl disable httpd
- 列出所有自启动服务:
- systemctl list-unit-files|grep enabled
- systemctl list-unit-files|grep disabled
- systemctl list-unit-files|grep disabled | grep httpd
google 无响应
在google 搜索后 www.googleadservices.com 无响应
游戏加速器使用体验
主要是比较各个加速器的区别,以个人使用体验为准,其中使用体验结果用表格列出;给出了个人的一些白嫖的方法(虽然不清除这些方法还管不管用😅)。
总结
-
差不多国内有名的加速器也就这些了,当然我自己使用体验极其糟糕的加速器并没有列出来。
-
建议首选网易uu,其次是海豚、小黑盒。
-
通常按月、季度、年付费的加速器加速效果比按时长付费的加速效果好。
使用体验结果
加速器名称 | 加速效果 | 价格 | 补充 |
---|---|---|---|
网易uu | 很稳 | 国内游戏免费,国外游戏付费 | 无 |
迅游加速器 | 不清楚 | 不清楚 | 手机端检测不到我玩的游戏😡。 |
奇游加速器 | 一般 | 不清楚 | 相对冷门的游戏加速效果不行;有些安装包有问题。 |
海豚加速器 | 很稳 | 分游戏免费和付费 | 用着还行。 |
小黑盒加速器 | 很稳 | 不清楚 | 优惠活动多,游戏较少。 |
biubiu加速器 | 不行 | 免费 | 有些游戏加速没效果😡。 |
战神加速器 | 可以 | 免费 | 个人认为是最稳的免费加速器了。 |
netch加速器 | 加速效果一般 | 需要梯子 | 加速效果取决于服务商提供的线路。 |
鲜牛加速器 | 一般 | 按时付费 | 游戏太少了,加速效果一般。 |
雷神加速器 | 不清楚 | 按时付费 | 游戏太少了,没有我想加速的游戏。 |
月轮加速器 | 可以 | 分游戏免费和付费,价格不便宜 | 有这钱为啥不用uu。 |
斧头(赛博)加速器 | 不行 | 不清楚 | 海外游戏加速没有用。 |
流星加速器 | 不行 | 不清楚 | 海外游戏加速没有用。 |
大多数的免费加速器 | 不行 | 免费 | 无 |
关于外服游戏的下载问题
大多数加速器只提供游戏内的加速(一部分是支持游戏下载加速的),游戏资源更新下载仍然需要梯子。
个人推荐免费畅玩游戏加速推荐
分为pc端和手机端
pc端:国内:uu加速器,国外:战神加速器(目前已收费)
手机端:国内:uu加速器,国外:挂梯子或biubiu
免费加速器存在的问题
- 游戏少。
- 即使有这个游戏,但加速之后没啥效果。
- 游戏的下载、更新、账号登录可能还是得要梯子才行。
- 指不定哪天就开始收费了。
- 加速效果一般。
个人推荐的非pvp游戏玩家的解决方法
- 国内游戏网易uu没什么好说的
- 国外游戏pc端使用战神加速器(目前免费),手机端的使用稳定点的梯子。
使用梯子做游戏加速怎么样?
如果服务商没有提供专门的游戏线路,那加速效果应该不会很好的。
友链
一些不错的网站及工具推荐
主要收集一些不错的网站(持续更新),大多是免费的,其中包括一些实用工具,免费电影、动漫观看下载网站,以及一些有趣的学习网站。
evozi
可以直接下载google play商店中的apk文件。
youtubemy
下载youtube视频
多邻国
在线学习外语,个人感觉挺好的,至于能不能通过网站学会就不知道了。
提醒一下不要去www.duolingo.cn这个网站,压根没法登录google账号的。
IDM下载器
极快的资源下载器,如果要下载网盘资源的话可以看看这篇文章。
winRAR压缩工具
除了操作压缩包之外还可以对压缩包进行 修复 等操作。
下载自行百度下载免费版本即可。
akinator
打开网站有一个阿拉丁神灯,你可以让他猜一个人物,可以是虚拟的也可以是真实的人物。
snipaste截图工具
一个非常不错的截屏软件,功能强大。
百度自行下载
明日方舟道具最优关卡记录
最近刷材料刷吐了,一管体力就两个蓝材料,在此记录一下个人认为的明日方舟道具掉率最优的关卡,当然参考了些其他网站的数据。原文时间:2020-10-11 21:04
道具名称 | 掉率最高的关卡 |
---|---|
扭转醇 | 6-11 |
轻锰矿 | 7-16 |
研磨石 | 5-7 |
RMA70-12 | 7-10 |
固源岩组 | 7-6 |
全新装置 | 7-15 |
聚酸酯组 | 7-4 |
糖组 | M8-7 |
异铁组 | 7-18 |
酮凝集组 | JT8-3 |
凝胶 | JT8-2 |
炽合金 | S3-6 |
晶体元件 | R8-11 |
git 学习
熟练git已经时现在程序员的标配了,然而在上手一段时间的git之后,发现git并不简单,所以特意写一篇文章用来记录git的知识点。原文时间:2020-10-25 15:40
在看了官方推荐的文档Git-book之后,可以说是懵的。
吐槽点:
- 我只想知道怎么用,我该怎么做。而Git-book讲解的更多是git的概念相关,作为小白自然就懵了。
- git命令非常的乱,一堆别名也非常让人头疼,而且在Git-book中还经常会在没有说明的情况下直接使用这些别名,然后用完了在告诉你,或者干脆不做讲解。
- git的log信息非常不友好,想要看到较直观的log,必须要加一堆参数。
总结:对于我这样的小白来说git相当不友好。
吐槽归吐槽,不论是公司要求还是未来的发展趋势,git在版本控制中占据主流,所以还是要硬着头皮学。
在网上搜寻了一番,找到了一些不错的文档
- git-recipes 一个实用主义的文档,主要教一些常用命令和少量的概念。
- 廖雪峰老师的git教程 讲的只是点不是很全,但循序渐进。
- coding的代码托管教程 由于github网速限制,现在很多公司都在用coding。
- 菜鸟教程 简洁,对于从来没有使用过git的新手非常不错。
- Git-book 官方推荐文档,比较难,有非常多概念性的东西。
git配置全局用户名和邮箱
git config --global user.name "John Doe"
git config --global user.email [email protected]
git查看全局配置
git config --list
创建空的git仓库
在所要创建的目录下git init
添加文件到Git仓库
git add <文件路径>
git commit -m "说明信息"
查看文件状态和比较文件差异
git status
git diff <文件路径>
查看最近提交的信息
git log
版本回退
//回退到上一个版本
git reset --hard HEAD^
//回退到上上个版本
git reset --hard HEAD^^
//回退到上100个版本
git reset --hard HEAD~100
//回退到指定版本
git reset --hard <指定版本号前几位>
HEAD指向的版本就是当前版本,因此,Git允许我们在版本的历史之间穿梭,使用命令git reset --hard commit_id。
穿梭前,用git log可以查看提交历史,以便确定要回退到哪个版本。
要重返未来,用git reflog查看命令历史,以便确定要回到未来的哪个版本。
提交修改
git add <文件路径>
撤销修改
##在工作区
撤销工作区的修改
git checkout -- readme.txt意思就是,把readme.txt文件在工作区的修改全部撤销。
一种是readme.txt自修改后还没有被放到暂存区,现在,撤销修改就回到和版本库一模一样的状态;
一种是readme.txt已经添加到暂存区后,又作了修改,现在,撤销修改就回到添加到暂存区后的状态。
##已经添加到暂存区
撤销暂存区的修改
git reset HEAD
创建ssh Key
ssh-keygen -t rsa -C "邮箱地址"
#远程仓库
添加远程仓库
git remote add
例子
git remote add pd
git push -u pd master 上传pd仓库的master分支,pd是远程仓库的一个别名,-u表示指定一个默认的远程仓库,之后再提交直接git push 即可
查看远程仓库
git remote
直接从远程仓库克隆
git clone
这是最常见的作法
#分支
新建分支
git checkout -b <分支名> 创建并切换分支
相当于
git branch <分支名> 创建分支
git checkout <分支名> 切换分支
查看分支
git branch
切换分支
git checkout <分支名> 切换分支
合并分支到当前分支
需要提交之后才可以合并
git merge <分支名>
删除分支
git branch -d <分支名>
新的切换分支命令switch
git switch -c dev
//创建并切换到dev分支、git switch dev
//切换到dev分支
储藏功能
工作只进行到一半,还没法提交,但是要修复bug分支
git stash 把当前工作现场“储藏”起来
git stash list 查看工作现场
git stash pop 恢复工作现场并删除
标签
创建普通标签
git tag
创建附注标签
git tag -a -m "备注"
查看标签
git tag
查看标签信息
git show
默认标签是打在最新提交的commit上的。
如果要对某个特定的commit打标签则需要指定commit id
git tag -a -m "备注"
##标签的其他操作
命令git push origin 可以推送一个本地标签;
命令git push origin --tags可以推送全部未推送过的本地标签;
命令git tag -d 可以删除一个本地标签;
命令git push origin :refs/tags/可以删除一个远程标签。
忽略特殊文件 .gitignore
/mtk/ 过滤整个文件夹
*.zip 过滤所有.zip文件
/mtk/do.c 过滤某个具体文件
推特验证和 google 账号注册
对于刚翻墙的小伙伴,有一个google账号真的很重要,但是注册账号会卡在最后一步手机验证上,甚至有些小伙伴放弃自己注册去买别人的账号,先不说花钱,账号本身的安全问题就很难保障。
推特:
不要使用邮箱的方式登录,使用手机号码的方式登录,注册时也是使用手机号注册,而不是邮箱。
google:
谷歌在注册时需要使用手机号码,但是当填写完手机号码发送验证时会报错:不支持手机号的格式。
解决方法:使用google浏览器,将google浏览器的语言切换成英文,将注册页面的语言切换成除简体中文以外的语言。
如果以上方法还不行,多换下不同梯子服务商或不同地区的梯子节点。
如果以上方法没用怎么办?
答:不好意思,我也不知道了。
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.