一、路由

1、概念

​ 路由本质上来说就是一种对应关系,比如说我们在浏览器中输入不同的 url 地址,我们就能访问不同的资源,那么这 url 地址与资源之间的对应关系,就是路由。

2、分类

① 后端路由

​ 后端路由是通过服务器实现的,根据不同的用户 url 请求,返回不同的资源,本质上就是 url 地址与服务器资源之间的对应关系。

② 前端路由

​ 前端路由是通过页面 hash 值(锚链接) 的变化实现的,根据不同的页面事件来显示不同的页面内容,本质上是用户事件与事件处理函数之间的对应关系。

​ 前端路由的核心就是监听事件并分发执行事件处理函数,所以需要依靠 window.onhashchange 事件来监听 hash 值的变化,以及 location.hash 获取目前页面的 hash 值。

3、SPA

​ SPA(Single Page Application)单页面应用程序,整个页面只有一个页面,内容的变化通过 ajax 局部更新实现,同时支持浏览器地址栏的前进与后退操作,又称单页面多视图。其实现原理是基于 url 地址的hash变化,hash变化会导致浏览器访问记录的变化,但不会触发新的url请求。SPA最核心的技术点就是前端路由。

​ SPA 还有后端路由渲染和ajax前端渲染两种解决方案,但是后端路由渲染的性能很低,ajax前端渲染,虽然性能高,但不支持浏览器的前进后退操作。

SPA 单页面应用的优点:

​ ① 良好的交互体验

​ 内容的改变不需要重新加载整个页面,页面数据的获取通过ajax异步获取,没有页面之间的跳转,不会出现跳转白屏现象。

​ ② 良好的前后端分离的工作模式

​ 前端只需要专注于页面的渲染,更利于前端工程化的发展。

​ 后端只需要专注于API接口的提供,更易实现API接口的复用。

​ ③ 减轻服务器的压力

​ 服务器只提供数据,不负责页面的合成和逻辑的处理,吞吐能力提高几倍。

SPA 单页面应用的缺点:

​ ① 首屏加载慢

​ 解决方案:路由懒加载、代码压缩、CDN加速、网络传输压缩

​ ② 不利于SEO(搜索引擎优化)

​ 解决方案:SSR服务器端渲染

4、前端路由案例

         <!-- 导入 vue 文件 --><script src="./lib/vue_2.5.22.js"></script><!-- 被 vue 实例控制的 div 区域 --><div id="app"><!-- 切换组件的超链接 --><a href="#/zhuye">主页</a> <a href="#/keji">科技</a> <a href="#/caijing">财经</a><a href="#/yule">娱乐</a><!-- 根据 :is 属性指定的组件名称,把对应的组件渲染到 component 标签所在的位置 --><!-- 可以把 component 标签当做是【组件的占位符】 --><component :is="comName"></component></div><script>// #region 定义需要被切换的 4 个组件// 主页组件const zhuye = {template: '<h1>主页信息</h1>'}// 科技组件const keji = {template: '<h1>科技信息</h1>'}// 财经组件const caijing = {template: '<h1>财经信息</h1>'}// 娱乐组件const yule = {template: '<h1>娱乐信息</h1>'}// #endregion// #region vue 实例对象const vm = new Vue({el: '#app',data: {comName: 'zhuye'},// 注册私有组件components: {zhuye,keji,caijing,yule}})// #endregion// 监听 window 的 onhashchange 事件,根据获取到的最新的 hash 值,切换要显示的组件的名称window.onhashchange = function() {// 通过 location.hash 获取到最新的 hash 值console.log(location.hash);// 获取的hash值为 #/xxx 形式  所以使用 slice 去除 #switch(location.hash.slice(1)){case '/zhuye':vm.comName = 'zhuye'breakcase '/keji':vm.comName = 'keji'breakcase '/caijing':vm.comName = 'caijing'breakcase '/yule':vm.comName = 'yule'break}}</script>

二、Vue Router

1、概念

​ Vue Router 是一个 Vue 官方提供的路由管理器,功能十分强大。与 Vue 十分契合,可以一起方便的实现SPA(single page web application,单页应用程序)应用程序的开发。在页面中,想要使用Vue Router 需要跟Vue一样引入库文件,但Vue Router依赖于Vue,所以需要先引入Vue,再引入Vue Router。

2、特性

① 支持H5历史模式或者hash模式
 默认为hash模式,URL中带 # 。可以通过mode来设置为历史模式(借助于HTML5的 history API实现):
const router = new VueRouter({mode: 'history',routes: [...]
})
② 支持嵌套路由
③ 支持路由参数
④ 支持编程式路由
⑤ 支持命名路由
⑥ 支持路由导航守卫
⑦ 支持路由过渡动画特效
⑧ 支持路由懒加载
⑨ 支持路由滚动行为

3、基本使用

 <!-- 导入 vue 文件 --><script src="./lib/vue_2.5.22.js"></script><!-- 导入 vue router 文件 Vue Router依赖于Vue,所以需要先引入Vue,再引入Vue Router --><script src="./lib/vue-router_3.0.2.js"></script><!-- 被 vm 实例所控制的区域 --><div id="app"><!-- <router-link>是路由中提供的标签,默认会被渲染为a标签,to属性默认被渲染为href属性,to属性的值会被渲染为#开头的hash地址 --><router-link to="/user">User</router-link><router-link to="/register">Register</router-link><!-- 路由占位符 路由规则匹配到的组件将会被渲染到这个位置 --><router-view></route-view></div><script>// 定义路由组件const User = {template: '<h1>User 组件</h1>'}const Register = {template: '<h1>Register 组件</h1>'}// 创建路由实例对象const router = new VueRouter({// 配置路由规则routes: [//每一个路由规则都是一个对象,对象中至少包含path和component两个属性//path表示  路由匹配的hash地址,component表示路由规则对应要展示的组件对象{ path: '/user', component: User },{ path: '/register', component: Register }]})// 创建 vm 实例对象const vm = new Vue({// 指定控制的区域el: '#app',data: {},// 挂载路由实例对象router: router// 可简写为:// router})</script>

4、路由重定向

​ 路由重定向是指:在用户访问某个地址A时,强制用户跳转到地址 B,并展示相关内容。想要实现重定向,需要使用路由规则的 redirect 属性。我们一般通过路由重定向为页面设置默认展示的组件。

var myRouter = new VueRouter({//routes是路由规则数组routes: [//path设置为/表示页面最初始的地址 / ,redirect表示要被重定向的新地址,设置为一个路由地址即可{ path:"/",redirect:"/user"},{ path: "/user", component: User },{ path: "/login", component: Login }]
})

5、路由嵌套

​ 路由嵌套是指:当我们点击父级路由链接,在路由占位符显示的组件内容中有子级路由链接,点击子级路由链接时,在子级路由占位符显示子级组件内容。子级路由规则,由父级路由的 children 属性来配置。

// 父级路由
const Register = {template: `<div><h1>Register 组件</h1><hr/><!-- 子路由链接 --><router-link to="/register/tab1">tab1</router-link><router-link to="/register/tab2">tab2</router-link><!-- 子路由的占位符 --><router-view /><div>`
}
// 两个子级组件
const Tab1 = {template: '<h3>tab1 子组件</h3>'
}
const Tab2 = {template: '<h3>tab2 子组件</h3>'
}// 创建路由实例对象
const router = new VueRouter({// 所有的路由规则routes: [{ path: '/', redirect: '/user'},{ path: '/user', component: User },// children 数组表示子路由规则{ path: '/register', component: Register, children: [{ path: '/register/tab1', component: Tab1 },{ path: '/register/tab2', component: Tab2 }] }]})

补充:

①、 在嵌套路由中,子路由和父路由之间如何传值?

虽然是通过路由嵌套的方式展示的页面,当其形式还是相当于父子组件的的关系,所以我们可以通过父子组件传值的方式来传值,只不过是将router-view视为子组件在父组件中的载体,具体如下:

// 子路由 通过 this.$emit 向父路由传递数据
this.$emit('other-tab', 4)// 父路由 通过绑定事件来接受值
<router-view @other-tab="toOthersTab($event)" />
// 取值事件
toOthersTab (val) {console.log(val) // 4
}

那么同理,父路由也可以给子路由传递数据:

// 父路由传参
<router-view :id="12138" @other-tab="toOthersTab($event)" />// 子路由通过 props 接收props: {id: {type: Number,default: 0}},mounted () {console.log(this.id)}
②、在子路由中如何调用父路由的方法和变量?

如果我们想要在子路由中直接去调用父路由的方法和参数,而且不想借用this.$emit 这种麻烦的方法,我们可以通过this.$parent来实现:

// 父路由中的方法和变量
data () {return {father: 'me'}
},
methods: {toLog () {console.log('这是父路由中的方法')  }
}// 在子路由中调用父路由的方法和变量
data () {return {son: 'you'}
},
methods: {toFather () {console.log('子路由调用父路由中的变量')this.son = this.$parent.fatherconsole.log('son=' + this.son)console.log('子路由调用父路由中的方法')  this.$parent.toLog()}
}
③在父路由中调用子路由的变量和方法

如果我们想要在父路由中,直接调用子路由的方法和变量,我们可以通过$ref来引用router-view这个dom元素的方式,去调用对应的变量和方法。
这种方法唯一要注意的就是在调用子路由的属性和方法的时候,子路由必须已经加载完成,否则无法访问到变量和方法,推荐在父路由的mounted阶段以后再调用,因为此时子路由必定已经加载完成:

// 子组件定义变量和方法
data () {return {son: 'son'}
},
methods: {test () {console.log('这是子路由中方法,尝试是否能被父路由调用')}
}// 在父路由中通过ref调用子路由的变量和方法
<reouter-view ref='son' />mounted () {// 在mounted阶段调用 因为子路由此时已经加载完成console.log('调用子路由中的方法')console.log(this.$refs.son.test())console.log('调用子路由中的变量')console.log(this.$refs.son.son)
}

6、动态路由匹配(路由传参)

① $route.params.参数

​ 设置路由规则时,在路径path里,通过 /:参数 的形式,设置参数。然后在组件中通过 {{ $route.params.参数 }} 的形式,获取参数。该方法耦合度高,不够灵活,很少使用。

<!-- 被 vm 实例所控制的区域 --><div id="app"><router-link to="/user/1">User1</router-link><router-link to="/user/2">User2</router-link><router-link to="/user/3">User3</router-link><!-- 路由占位符 --><router-view></router-view></div><script>const User = {template: '<h1>User 组件 -- 用户id为: {{$route.params.id}}</h1>'}// 创建路由实例对象const router = new VueRouter({// 所有的路由规则routes: [{ path: '/', redirect: '/user'},{ path: '/user/:id', component: User },]})</script>
② props 的值为 true

​ 在路由规则中,将props的值设置为 true,使 $route.params 成为组件属性。在路径path里,通过 /:参数 的形式,设置参数,然后在组件中,使用 props 接收参数即可。

// 使用 props['参数'] 来接收参数
const User = {props: ['id'],template: '<h1>User 组件 -- 用户id为: {{id}}</h1>'
}
// 创建路由实例对象
const router = new VueRouter({// 所有的路由规则routes: [{ path: '/', redirect: '/user'},{ path: '/user/:id', component: User, props: true },]})
③ props 的值为对象

​ 我们将props 的值设置为一个对象,就相当于将对象中的所有属性传递给组件,组件使用 props[‘属性名1’,‘属性名2’] ,即可接收数据。

const User = {// 接收对象中的数据,但id接收不到,因为传递的对象中没有这个属性props: ['id', 'uname', 'age'],template: '<h1>User 组件 -- 用户id为: {{id}} -- 姓名为:{{uname}} -- 年龄为:{{age}}</h1>'
}
// 创建路由实例对象
const router = new VueRouter({// 所有的路由规则routes: [{ path: '/', redirect: '/user'},// 传递的是静态对象{ path: '/user/:id', component: User, props: { uname: 'lisi', age: 20 } }]})
④ props 的值为函数

​ 如果既想获取路径传递的参数值,又想获取传递的对象数据,那么props应该设置为函数形式。

// 组件
const User = {props: ['id', 'uname', 'age'],template: '<h1>User 组件 -- 用户id为: {{id}} -- 姓名为:{{uname}} -- 年龄为:{{age}}</h1>'
}// 创建路由实例对象const router = new VueRouter({// 所有的路由规则routes: [{ path: '/', redirect: '/user' },{// 路径传递的参数path: '/user/:id',component: User,// 以函数的形式 传递数据到组件props: route => ({ uname: 'zs', age: 20, id: route.params.id })},{ path: '/register', component: Register }]})

7、命名路由

​ 为了更加方便的表示路由的路径,我们可以给路由规则起一个别名,即为命名路由。

<!-- to属性动态绑定一个对象  name属性 表示要绑定的路由规则  params 表示要传递的参数 参数名必须与路由规则定义的相同 -->
<router-link :to="{ name: 'user', params: {id: 3} }">User3</router-link>
<!-- <router-link to="/user/3">User3</router-link> -->
<script>// 声明组件const User = {props: ['id', 'uname', 'age'],template: '<h1>User 组件 -- 用户id为: {{id}} -- 姓名为:{{uname}} -- 年龄为:{{age}}</h1>'}// 创建路由实例对象const router = new VueRouter({// 所有的路由规则routes: [{ path: '/', redirect: '/user' },{// 命名路由name: 'user',path: '/user/:id',component: User,props: route => ({ uname: 'zs', age: 20, id: route.params.id })}]})
</script>

8、编程式导航

​ 页面导航分为两种方式:声明式导航和编程式导航。通过点击链接实现导航的方式,叫做声明式导航,比如:网页中的 a 超连接 或者 vue router 里面的 标签。通过调用 JavaScript 形式的API实现导航的方式,叫做编程式导航,比如:网页中的location.href 。

vue Router 中常用的编程式导航 API 有:

this.$router.push()

​ 该API的参数形式有很多:

​ ① 路径字符串,例如:this.$router.push(‘/user’)。

​ ② 路径对象,例如:this.$router.push({path: ‘/user’})。

​ ③ 命名路由对象,例如:this.$router.push({name: ‘/user’})

​ ④ 带查询参数,变成 /user?uname=lisi的形式,例如:this.$router.push({ path: ‘/user’,query: { uname } })

this.$router.replace()

​ 该API与this.$router.push() 作用基本相同。只不过它在跳转到指定 hash 地址,不会增加新的历史记录,只会替换掉当前的历史记录。

this.$router.go(n)

​ 该 API 参数是数字,数字的大小表示浏览器历史中前进或后退的页数,可以为负值,负值代表后退,正值代表前进。

综合案例:
<router-link :to="{ name: 'user', params: {id: 3} }">User3</router-link>
<router-link to="/register">Register</router-link><script>const User = {props: ['id', 'uname', 'age'],template: `<div><h1>User 组件 -- 用户id为: {{id}} -- 姓名为:{{uname}} -- 年龄为:{{age}}</h1><button @click="goRegister">跳转到注册页面</button></div>`,methods: {// 代码中用到的方法goRegister() {this.$router.push('/register')}},}const Register = {template: `<div><h1>Register 组件</h1><button @click="goBack">后退</button></div>`,methods: {goBack() {// 后退this.$router.go(-1)}}}// 创建路由实例对象const router = new VueRouter({// 所有的路由规则routes: [{ path: '/', redirect: '/user' },{// 命名路由name: 'user',path: '/user/:id',component: User,props: route => ({ uname: 'zs', age: 20, id: route.params.id })},{ path: '/register', component: Register }]})// 创建 vm 实例对象const vm = new Vue({// 指定控制的区域el: '#app',data: {},// 挂载路由实例对象// router: routerrouter})</script>

9、导航守卫

​ 导航守卫是用来控制路由的访问权限,比如可以结合token 检查用户是否登录,当未登录的用户想要访问某些页面时,通过路由导航将其跳转到登录页面。vue-router 的导航守卫有全局前置守卫、全局解析守卫、路由独享的守卫等等等。我目前只学习了全局前置守卫,所接下来就总结一下全局前置守卫。剩下的后续补充。

① 全局前置守卫:

​ 当给项目设置了全局前置守卫之后,在每次发生路由的导航跳转时,都会触发。所以开发者可以在全局前置守卫中,对路由的访问权限进行控制。

基本语法:
// 创建路由实例对象
const router = new VueRouter({....})// 设置全局前置守卫
router.beforeEach((to,from,next) => {// to 是将要访问的路由对象,包含路由地址等相关信息。// from 是将要离开的路由对象,包含路由地址等相关信息。// next 是一个内置函数,调用 next() 表示允许通过,// next('路由地址') 表示强制跳转到某个页面// next(false) 表示不允许跳转
})
基本使用:
// 创建路由实例对象
const router = new VueRouter({....})// 需要权限才能访问的页面路由地址,以数组的形式
const pathArr = ['/home', '/home/users', '/home/rights']// 设置全局前置守卫
router.beforeEach(function(to, from, next) {// to将要访问的路由的地址 是否需要权限if (pathArr.indexOf(to.path) !== -1) {// 验证权限const token = localStorage.getItem('token')// 根据结果不同 进行不同的操作if (token) {next()} else {next('/login')}} else {next()}
})
② 组件内的守卫钩子函数

组件内的守卫钩子函数是指写在某一页面组件内的钩子函数,只有当页面的路由变化与该组件相关时才会调用执行。一同提供了三种钩子函数,适用于各种不同的场景:
beforeRouteEnter(to,from,next)
该守卫钩子函数是在要跳转该组件对应的路由(或该组件对应路由的子路由)并且在该组件渲染之前调用执行的。第一个参数 to表示要跳转到的路由信息对象,常用属性为 to.path 可以获取到要跳转到的路由地址。第二个参数form表示要跳转离开的路由信息对象。因为该守卫函数执行时,组件实例还没有被创建,所以不能获取组件的this ,也就是无法获取或改变组件中的数据,但我们可以通过给第三个参数 next 传递一个回调函数,该函数的参数就是组件实例,通过这种方式来操作组件中的数据:

// 守卫钩子函数1
beforeRouteEnter (to, from, next) {next((vm) => {// 通过 vm 访问组件实例console.log(vm.a); // 1})
},
data() {return {a: 1}
}

beforeRouteUpdate(to,from)
该守卫钩子函数是在当前路由发生了改变但该组件被复用时调用执行,经过我的实验,只有在动态路由这一种情况下,该方法才会被执行,举例来说就是:如果一个路由地址定义为:/course/:id,当路由地址从/course/1 跳转到 /course/2时,该守卫钩子函数才会被执行。函数的两个参数与beforeRouteEnter(to,from)意义相同,但此时组件实例已经创建好了,所以在该守卫钩子函数里面可以操作组件中的数据:

// 守卫钩子函数2
beforeRouteUpdate(to,from){// 通过this访问组件实例console.log(this.a); // 1
},
data() {return {a: 1
}
}

beforeRouteLeave(to,from)
该守卫钩子函数是在跳转离开该组件时调用执行,也可以直接操作组件中的数据。函数的两个参数与beforeRouteEnter(to,from)意义相同,这个守卫钩子函数通常用来预防用户在还未保存修改前突然离开的情况,可以通过return false 来取消路由跳转,让页面不变:

// 守卫钩子函数3
beforeRouteUpdate(to,from){// 提示用户有未保存的内容,是否要离开const answer = window.confirm('你还有未保存的内容,是否要离开本页面?')// 如果不离开 则取消路由跳转if (!answer) return false
}
③ 完整的路由跳转解析流程
  • 导航被触发,路由进行跳转。
  • 在要离开的组件里调用 beforeRouteLeave 守卫。
  • 调用全局的 beforeEach 守卫。
  • 在复用的组件里调用 beforeRouteUpdate 守卫(2.2版本新增)。
  • 调用路由配置里的 beforeEnter 守卫。
  • 解析异步路由组件。
  • 在被激活的组件里调用 beforeRouteEnter。
  • 调用全局的 beforeResolve 守卫(2.5版本新增)。
  • 导航被确认。
  • 调用全局的 afterEach 钩子。
  • 触发 DOM 更新。
  • 调用 beforeRouteEnter 守卫中传给 next 的回调函数,创建好的组件实例会作为回调函数的参数传入。
  • 结束。

10、路由跳转时在新窗口打开页面

① router-link 标签

vue-router的 router-link 标签最后会被转换成 a 标签,所以我们可以在 router-link 标签上增加 target="_blank" 属性,这样就能实现在路由跳转的时候实现在新窗口打开页面的效果。

// 在新窗口打开页面<router-link target="_blank" :to="{path:'/myInfo'}">新页面打开myInfo页</router-link>
// 可以传递参数,与原来 router-link 路由传参方式相同<router-link target="_blank" :to="{path:'/myInfo',params:{id:'8'}}">新页面打开myInfo页</router-link>
② 编程式导航

当我们需要在点击事件或者某个函数中实现在新窗口中打开某个页面的效果,我们可以借助编程式导航来实现,但是在Vue2.0以后,只有$router.resolve() 支持这种操作,$router.push()$router.go() 都不支持。

// 事件函数
function () {let routeData = this.$router.resolve({path: '/myInfo'// 或者 path 和 name 都可,没有什么不同// name: '/myInfo'});// 在新窗口  打开页面window.open(routeData.href, '_blank');
}
// 也可传递参数
function () {let routeData = this.$router.resolve({path: '/myInfo'// 或者 path 和 name 都可,没有什么不同// name: '/myInfo'query: {id: 12138}});// 在新窗口  打开页面window.open(routeData.href, '_blank');
}
// 新页面中取参数的方式this.$route.query.id

Vue学习笔记(六)--- 前端路由 Vue Router相关推荐

  1. Vue学习笔记1-什么是Vue

    Vue学习笔记1-什么是Vue 一.什么是 Vue? 渐进式 JavaScript 框架,一款用于构建 Web 界面,易学易用,性能出色且功能丰富的框架. Vue (发音为 /vjuː/,类似 vie ...

  2. Vue学习笔记(六) 表单输入绑定

    v-model 指令在表单元素上创建双向数据绑定,它负责用于监听用户输入事件以更新数据 注意,v-model 会忽略所有表单元素特性的初始值,而总是将 Vue 实例的数据作为数据来源 1.输入框 &l ...

  3. vue全套笔记,前端工程化+vue指令+脚手架

    文章目录 一. 前端工程化 webpack 的基本使用 webpack 中的插件 webpack 中的 loader 打包发布 Source Map的使用 注意,实际开发不需要自己配置webpack ...

  4. 阿瑶的Vue学习笔记(2)Vue 组件化编程

    2.非单文件组件 2.1 模块与组件.模块化与组件化 2.1.1模块 理解:向外提供特定功能的js程序,一般就是一个js文件 为什么:js文件很多很复杂 作用:复用js,简化js的编写,提高js运行效 ...

  5. Vue 学习笔记(2)Vue 生命周期、组件

    Vue Vue 生命周期 Vue 中组件(Component) 全局组件的开发 局部组件的开发 组件中 props 的使用 在组件上声明静态数据传递给组件内部 在组件上声明动态数据传递给组件内部 pr ...

  6. Vue 学习笔记(1) Vue 基础语法 + Axios 基本使用

    Vue Vue 简介 下载 Vue {{}}:插值表达式 v-text:显示文本 v-html:显示解析html标签的文本 v-on:事件绑定 v-show:控制页面元素隐藏与显示(display控制 ...

  7. Vue 学习笔记(六) P41-P43

    文章目录 P -- 最终效果图 P40 19-购物车案例-界面搭建 1. books.js 2. style.css 3. index.html 4. 初次运行问题 5. 界面定制化 P41 20-购 ...

  8. Vue学习笔记(二)—— vue项目中使用axios

    一.文档链接 axios文档 vue开发插件 二.axios 简介 axios 是一个基于Promise 用于浏览器和 nodejs 的 HTTP 客户端,它本身具有以下特征: 从浏览器中创建 XML ...

  9. Vue学习笔记:创建一个Vue实例

    目录 1.访问Vue官网https://cn.vuejs.org,进入学习模块下的教程 2.创建页面index.html 3.通过script标签在head部分引入vue.js 4.在body部分创建 ...

  10. vue学习笔记(一) ---- vue指令(过滤器)

    一.什么是过滤器 官方文档:https://cn.vuejs.org/v2/guide/filters.html 二.过滤器的使用 没有使用过滤器之前: <div id="app&qu ...

最新文章

  1. 用python做一些excel的事情,实现数据自动化
  2. [转帖]虚拟内存探究 -- 第二篇:Python 字节
  3. 面试必备Linux基础知识
  4. 电脑用linux命令大全,电脑操作时常用的一些Linux命令
  5. java线程池案例_使用Executors 和 ThreadPoolExecutor实现Java线程池案例
  6. 【mysql安装】阿里云centos7环境mysql安装
  7. Spring 无缝整合 quartz
  8. 阶段3 1.Mybatis_05.使用Mybatis完成CRUD_6 Mybatis的CRUD-保存操作的细节-获取保存数据的id...
  9. Alfred插件之有道翻译配置过程
  10. python公开直播课_今晚Python与人工智能直播课来袭,Mars喊你快上车
  11. Distributing Ballot Boxes(HDU1490)
  12. Java——面向对象(1)
  13. iOS提交应用至App Store流程
  14. yum clean all 是什么意思
  15. 漫谈程序员系列:怎样成为技术达人
  16. 001 Figuring in C/C++
  17. 记忆化搜索例题 记忆化搜索
  18. 欺骗的艺术——第二部分(11)
  19. python 使用爬虫下载京东图片
  20. 小米 9 SE 获取Root 和 安装Magisk

热门文章

  1. english - word - 20110129
  2. 思维模型 STAR原则
  3. java留言板_java实现留言板功能实例
  4. 数组面试题-大力出奇迹?
  5. IDEA下,如何在java项目中新增jsp模板文件
  6. k8s探针检测php,K8S教程(7)使用探针对容器进行健康检查
  7. 贤者之路,Tensorrt的int8 calibration创建
  8. Xilinx GT学习
  9. 服务器ghost备份后无法进入系统还原,使用Ghost备份/还原系统的速度很慢原因分析与解决...
  10. 牛逼!百度大佬深度分享AI助力RNA二级结构预测!