利用vue-cli配合vue-router搭建一个完整的spa流程
好文章备忘录:
转自:https://segmentfault.com/a/1190000009160934?_ea=1849098
demo源码:https://github.com/1590123375...
demo未安装依赖,下载完成,npm install
后再npm run dev
运行。
利用vue-cli配合vue-router搭建一个完整的spa流程(一)
前言:
Ⅰ. demo所用vue-router的一些基本操作。vue-router中文文档,快速浏览一遍即可 http://router.vuejs.org/zh-cn/
Ⅱ. 整个demo所用到的技术栈 vueJS(2.0) vue-cli vue-resource es6
Ⅲ. 所需构建工具 nodeJS Git
第一步:安装
OK,正题开始,首先保证nodeJS,Git,webpack已安装完毕。打开项目文件夹,安装vue-cli。
全局安装 vue-cli$ npm install --global vue-cli
创建一个基于webpack的模板vue init webpack my-project
创建过程中,vue-router为必须,其他语法检测,单元测试等按需求安装。
创建完成后进入项目文件夹,安装依赖$ npm install
安装到此结束,运行如下代码,显示为图片所示,则安装成功。$ npm run dev
第二步:项目文件及运行流程
Ⅰ: 项目文件
打开已经创建好的模板
如图所示,只会用到,src,static,index.html这三个文件。首先解释一下三个文件的作用:
Ⅰ: src 存放路由JS,模板.vue文件,入口JS,以及一个入口.vue文件
Ⅱ: static 存放静态文件
Ⅲ: index 入口html文件
这里解释一下xxx.vue文件是什么,官网叫其为单文件组件,通过webpack源码转换,会全部转换为对应的文件。
说白了就是一个包裹,里边含有三部分 一部分模板template
,一部分样式style
,一部分JSjavascript
,他们封装在一起。
如下图所示:
Ⅱ: 运行流程
写起来比较麻烦,做了一张图,直截了当。
第三步:搭建基本路由框架
项目文件明了之后,我们开始搭建一个简单的SPA路由构架:
Ⅰ: 页面中有俩个及俩个以上的分类
Ⅱ: 每个分类中可以点击进入到详情页面
Ⅲ: URL输入错误后展示404页面
Ⅳ: 在页面中刷新,根据URL重新获取数据,渲染页面
根据基础框架创建对应的文件。
文件详解:
Ⅰ: src中components文件夹里新建三个xxx.vue文件,
①error.vue 此为404页面
②showone.vue 此为第一个分类页面
③showtwo.vue 此为第二个分类页面
Ⅱ: src中zjapp.vue这是路由入口文件
Ⅲ: static中img为详情页面大图,thumbnail为分类页面缩略图
Ⅳ: 俩个JSON文件,分别代表分类一和分类二的数据来源
Ⅴ: bootstrap.css 样式CSS
到此路由的基本框架搭建完成,后面开始代码的填充。
第四步:主页面代码编写
Ⅰ: index.html
作为页面入口文件,先引入Bootstrap.CSS,如果是本地文件放在static文件夹里。可以使用CDN或者npm安装。
为了方便后面阅读将id="app"更改为id="index"。当然,也可以不更改,main.js中有多个为app的名字,避免混淆。
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>spa-vue-demo</title>
<link rel="stylesheet" href="static/bootstrap.min.css" />
</head>
<body>
<div id="index"></div>
<!-- built files will be auto injected -->
</body>
</html>
Ⅱ: main.js
main.js为入口JS文件,Vue的实例在这里书写。el 挂载在 index.html 中 id="index" 的标签上。
import Vue from 'vue'
import App from './zjapp'
import router from './router'
Vue.config.productionTip = false
new Vue({
el: '#index',
router,
template: '<App/>',
components: { App }
})
Vue 开始渲染时,加载 components: { App } 组件替换生成在 id="index" 内的 <App></App> 标签,那么{ App }来自哪里呢?
答案在 import App from './zjapp' 这里是ES6语法,引入zjapp.vue模块中暴露出来的接口,后缀可以不写。
Vue 实例中的 router 属性也是ES6中对象的字面量写法,等于router:router。同理 import router from './router' 这里引入router。
因为,router中index.js暴露接口时没有署名,这里也可以改一个名字,比如:
import Vue from 'vue'
import App from './zjapp'
//修改名字一样可以。
import changeES6 from './router'
Vue.config.productionTip = false
new Vue({
el: '#index',
//修改在这里
router:changeES6,
template: '<App/>',
components: { App }
})
最后,可能有人会问 Vue.config.productionTip = false 是做什么用的,其实这里是关闭了生产模式即部署到服务器后给出的提示。
Ⅲ: zjapp.vue
这个文件是 Vue 一开始渲染组件时的文件,首先贴出全部代码,很多,但是会全部讲解作用,含义。
<template>
<div class="container">
<div class="row">
<div id="index" class="col-xs-12 col-lg-12 col-md-12" style="padding: 0;">
<transition name='animate' appear mode='out-in'>
<router-view v-bind:router-data="allData" v-bind:key="change"></router-view>
</transition>
<transition name='btn' appear mode='out-in'>
<div class="app-btn" v-show="allData.mainShow">
<button class="btn btn-success app-btn-back" v-show="back==0?false:true" v-bind:key="back" v-on:click="dosom('back')">上一页</button>
<button class="btn btn-success app-btn-next" v-show="next==0?false:true" v-bind:key="next" v-on:click="dosom('next')">下一页</button>
</div>
</transition>
<div class="app-loading" v-show="loading">
<img src="../static/loading/loading.gif" style="margin:0 auto;display: block;" alt="loading" />
</div>
</div>
</div>
</div>
</template>
<script>
import router from './router'
export default{
data(){
return{
allData:{
showData:null,
detailedData:{},
num:0,
mainShow:true
},
loading:false,
change:true,
back:0,
next:1,
}
},
created(){
this.routePath();
},
watch:{
"$route"(to){
this.routePath();
}
},
methods:{
buttonToggle(){
var nowNum=this.allData.num;
this.back=nowNum;
this.next=2-nowNum;
},
dosom(str){
str=="next"?this.allData.num++:this.allData.num--;
this.buttonToggle();
//当前user/当前页面/当前页面路由
router.push(this.$route.path.slice(0,8)+this.allData.num);
},
routePath(){
if(this.$route.fullPath=="/"){
router.push("/user/0/0");
this.load();
}
else if(this.$route.fullPath.length==9 || this.$route.fullPath.length==20){
this.load();
}
else{
router.push("/user/error");
this.back=0;
this.next=0;
}
},
load(){
var numData=null,
listData=null;
// /user/lisData/numData
numData=this.$route.path.slice(8,9);
listData=this.$route.path.slice(6,7);
// 初始化
this.allData.num=numData;
this.buttonToggle();
this.change=!this.change;
if(this.$route.path.indexOf("con")>0){
//获取list中第几个
var typeData=this.$route.query.type;
this.$nextTick(e=>{
this.$http.get("static/data-"+listData+".json").then(rea=>{
this.loading=true;
setTimeout(e=>{
//vue-resource加载数据存在于data.body中
var listNum=rea.body.allData.slice(numData*6,numData*6+6);
//详细显示页面数据来源
this.allData.detailedData=listNum.slice(typeData,typeData+1)[0];
this.loading=false;
},700);
});
});
this.allData.mainShow=false;
}else{
this.$nextTick(e=>{
this.loading=true;
setTimeout(e=>{
this.$http.get("static/data-"+listData+".json").then(rea=>{
this.allData.showData=rea.body.allData.slice(numData*6,numData*6+6);
this.loading=false;
});
},700);
});
this.allData.mainShow=true;
}
}
}
}
</script>
<style>
/*切换中动画*/
.animate-enter-active,.animate-leave-active{
transition: all 0.5s ease;
}
.animate-enter{
transform: translateX(-80px);
opacity: 0;
}
.animate-leave-active{
transform: translateX(80px);
opacity: 0;
}
/*底部按钮简单动画*/
.btn-enter-active,.btn-leave-active{
transition: all 1s ease;
}
.btn-enter{
opacity: 0;
}
.btn-leave-active{
opacity: 0;
}
/*back,next btn-class*/
.app-btn{
overflow: hidden;
width: 140px;
height: 34px;
position: relative;
margin-top: 15px;
}
/*back btn-class*/
.app-btn-back{
position: absolute;
top: 0;
left: 0;
}
/*next btn-class*/
.app-btn-next{
position: absolute;
bottom: 0;
right: 0;
}
/*loading*/
.app-loading{
background-color: tan;
position: fixed;
height: 100%;
width: 100%;
left: 0;
top:0;
}
</style>
Ⅰ: HTML部分(即template)
大体分为三部个分
第一部分:
<transition name='animate' appear mode='out-in'>
<router-view v-bind:router-data="allData" v-bind:key="change"></router-view>
</transition>
第一部分为页面中内容路由入口,其中:v-bind:router-data="allData"
是对模板中传输数据用的v-bind:key="change"
是页面切换动画绑定的变值,用来使页面被复用时触发切换动画
第二部分:
<transition name='btn' appear mode='out-in'>
<div class="app-btn" v-show="allData.mainShow">
<button class="btn btn-success app-btn-back" v-show="back==0?false:true" v-on:click="dosom('back')">上一页</button>
<button class="btn btn-success app-btn-next" v-show="next==0?false:true" v-on:click="dosom('next')">下一页</button>
</div>
</transition>
第二部分为页面中上一页,下一页按钮部分,其中:v-show="allData.mainShow"
是控制俩个按钮显示,隐藏(详情页隐藏)v-show="back==0?false:true"
是控制单个按钮显示,隐藏(最后一页时,下一页按钮隐藏)v-on:click="dosom('back')"
是绑定的点击事件
第三部分:
<div class="app-loading" v-show="loading">
<img src="../static/loading/loading.gif" style="margin:0 auto;display: block;" alt="loading" />
</div>
第三部分为页面中内容更新数据时loading画面,其中:v-show="loading"
是用来显示,隐藏 loading 动画
好了,到此主要的HTML模块已经布局完毕,现在开始JS功能的开发
Ⅱ: javascript
JS这里的整体流程:watch router.path的变化,从URL中读取数据,从新获取数据。(因为本地JSON文件,获取JSON后对JSON进行剪切)
import router from './router'
ES6语法,引入router模块下暴露的接口,这里引入router实例为后续编写编程式导航铺垫。
data(){
return{
allData:{
showData:null,
detailedData:{},
num:0,
mainShow:true
},
loading:false,
change:true,
back:0,
next:1,
}
}
showData 为当前页面渲染数据,即router-view被替换为showone.vue模板中的数据来源,每次点击下一页等操作导致router.path变化时,此数据更新对应的子模板中(showone.vue)数据也更新。(后面讲到路由页面时会解释)
detailedData 为详情页面渲染数据,即router-view被替换为showtwo.vue模板中的数据来源,同上。
num 这个是用来每次打开或者刷新页面时读取当前为第几页的number,因为这个数值用了很多次,故将它放到了初始化函数里
mainShow 控制俩个按钮(下一页,上一页)总体显示,隐藏
loading 控制loading动画的显示,隐藏
change 页面复用时的Key值
back 返回按钮的number,因为按钮的判断为v-show="back==0?false:true"
当为0是隐藏
next 同上
以上为这个demo中数据的含义,下面是方法的解释,从methods开始说起:
buttonToggle(){
var nowNum=this.allData.num;
this.back=nowNum;
this.next=2-nowNum;
}
这是俩个按钮的控制函数,因为JSON数据不多,一个分类中只有2页数据,所以 this.next=2-nowNum;
最后一页时隐藏。
dosom(str){
str=="next"?this.allData.num++:this.allData.num--;
this.buttonToggle();
// http://localhost:8080/#/user/0/1
// http://localhost:8080/#/user/0/this.allData.num
router.push(this.$route.path.slice(0,8)+this.allData.num);
}
这是按钮点击时触发的方法,点击后判断是上一页,还是下一页,因为会动态的隐藏按钮所以不用关注++或者--的上下界。随后进行url的更改(url更改后会触发watch,watch中执行的函数为 routePath() ,下一个说到)
routePath(){
if(this.$route.fullPath=="/"){
router.push("/user/0/0");
this.load();
}
else if(this.$route.fullPath.length==9 || this.$route.fullPath.length==20){
this.load();
}
else{
router.push("/user/error");
this.back=0;
this.next=0;
}
}
this.$route.fullPath
返回的是全部 url 字符串,这是当前url判断函数:
当读取到的url为“/”时,此为第一次打开页面,跳转到首页也就是 http://localhost:8080/#/user/0/0
然后 执行load()方法,load() 方法下一个说到。
当读取到this.$route.fullPath.length==9 || this.$route.fullPath.length==20
,其实就是 this.$route.fullPath
为/user/x/x
的主页面中,或者为 /user/x/x/con?type=x
的详情页面中,此时直接进行 load() 方法更新数据即可
最后其他任何 url 都被认为是错误的 http 请求,返回404页面,当然俩个翻页按钮隐藏。
load(){
var numData=null,
listData=null;
// /user/lisData/numData
listData=this.$route.path.slice(6,7);
numData=this.$route.path.slice(8,9);
// 初始化num值
this.allData.num=numData;
this.buttonToggle();
// 页面复用时Key值
this.change=!this.change;
if(this.$route.path.indexOf("con")>0){
// 获取list中第几个
var typeData=this.$route.query.type;
this.$nextTick(e=>{
this.$http.get("static/data-"+listData+".json").then(rea=>{
this.loading=true;
setTimeout(e=>{
//vue-resource加载数据存在于data.body中
var listNum=rea.body.allData.slice(numData*6,numData*6+6);
//详细显示页面数据来源
this.allData.detailedData=listNum.slice(typeData,typeData+1)[0];
this.loading=false;
},700);
});
});
this.allData.mainShow=false;
}else{
this.$nextTick(e=>{
this.loading=true;
setTimeout(e=>{
this.$http.get("static/data-"+listData+".json").then(rea=>{
this.allData.showData=rea.body.allData.slice(numData*6,numData*6+6);
this.loading=false;
});
},700);
});
this.allData.mainShow=true;
}
}
这个方法的作用是交互数据,demo 有俩个分类,首页,和第一页,所以对应的数据也是俩个JSON。定时器的作用是模拟数据请求延时。
以上就是 methods 方法里全部函数,下面解释一下Vue实例里其他的方法。
created(){
this.routePath();
}
这是一个生命周期钩子代表Vue实例被创建好了,创建好之后进行url解析,这是初始化的步骤,第一次打开这个demo执行的函数。官方文档:Vue生命周期
watch:{
"$route"(to){
this.routePath();
}
}
说到 watch 了这是监控url变化时触发的函数,说白了就是执行 router.path("/user/x/x")
之后Vue会检测到变化,从而进行回调函数,这里执行 routerPath() 分析 url 是属于哪个页面从而进行数据更新。
好了,javascript的编写到此结束,主要部分还是在 routerPath() 这个函数,再通过 url 重新获取数据。
style 部分就不说了,简单的css3动画
利用vue-cli配合vue-router搭建一个完整的spa流程(二)
在(一)中写到了主要页面的编写,现在开始三个路由页面的编写。
第一步: 路由实例index.js
先贴出代码。
import Vue from 'vue'
import Router from 'vue-router'
import VueResource from 'vue-resource'
import tem from '@/components/showone'
import tem_cont from '@/components/showtwo'
import tem_error from '@/components/error'
//安装插件
Vue.use(Router)
Vue.use(VueResource)
export default new Router({
routes:[
{
path:"/user/:list/:listNum",
component:tem,
children:[
{
path:"con",
component:tem_cont
}
]
},
{
path:"/user/error",
component:tem_error
}
]
})
代码很短,一一解释下。
import Vue from 'vue'
import Router from 'vue-router'
import VueResource from 'vue-resource'
import tem from '@/components/showone'
import tem_cont from '@/components/showtwo'
import tem_error from '@/components/error'
↑ 这里是引入所有使用的数据,参数。
//安装插件
Vue.use(Router)
Vue.use(VueResource)
↑ 这里说下 vue-resource 这个一开始没有安装,打开项目右键打开Git 键入 npm install vue-resource --save
这是一个ajax插件,使用起来比较方便而且很简单。
routes:[
{
path:"/user/:list/:listNum",
component:tem,
children:[
{
path:"con",
component:tem_cont
}
]
},
{
path:"/user/error",
component:tem_error
}
]
↑ 路由配置,详情页面是主页面的子路由。
第二部: 三个路由xxxx.vue文件编写
Ⅰ: showone.vue
先贴出代码,有些复杂,慢慢解释。
<template>
<div style='cursor:pointer;height: 867px;' >
<div v-show='routerData.mainShow'>
<nav class='navbar navbar-default'>
<div class='container' style="padding: 0;">
<div class='collapse navbar-collapse' style="padding: 0;">
<ul class='nav navbar-nav userNav'>
<li><a v-bind:class="{activeBg:isActive==0}" v-on:click='link(0)'>首页</a></li>
<li><a v-bind:class="{activeBg:isActive==1}" v-on:click='link(1)'>页面一</a></li>
</ul>
</div>
</div>
</nav>
<div class='media' v-for='(item,index) in routerData.showData' v-on:click='go(item,index)'>
<div>
<div class='media-left'>
<img class='media-object' v-bind:src='item.thumbnail'>
</div>
<div class='media-body'>
<h2 class='media-heading' v-text='item.title'></h2>
<span style='font-size:25px;color:#ccc'>{{item.content | more}}</span>
</div>
</div>
</div>
</div>
<router-view v-bind:router-nesting='routerData'></router-view>
</div>
</template>
<script>
import router from '.././router'
export default{
props:["routerData"],
data(){
return {
isActive:this.$route.path.slice(6,7)
}
},
methods:{
go(obj,index){
router.push({path:this.$route.path+"/con",query:{type:index}});
},
link(num){
var listNum=this.$route.path.slice(6,7);
if(listNum!=num){
router.push("/user/"+num+"/0");
this.isActive=this.$route.path.slice(6,7);
}
}
},
filters:{
more(value){
var newMessage=value.slice(0,40)+"........点击查看更多";
return newMessage;
}
}
}
</script>
<style>
.activeBg{
background-color: teal;
color: white !important;
transition: 0.5s all ease-in;
}
.userNav :hover{
background-color: cornsilk;
color: black !important;
}
</style>
template有俩部分组成:
<div v-show='routerData.mainShow'>
<nav class='navbar navbar-default'>
<div class='container' style="padding: 0;">
<div class='collapse navbar-collapse' style="padding: 0;">
<ul class='nav navbar-nav userNav'>
<li><a v-bind:class="{activeBg:isActive==0}" v-on:click='link(0)'>首页</a></li>
<li><a v-bind:class="{activeBg:isActive==1}" v-on:click='link(1)'>页面一</a></li>
</ul>
</div>
</div>
</nav>
<div class='media' v-for='(item,index) in routerData.showData' v-on:click='go(item,index)'>
<div>
<div class='media-left'>
<img class='media-object' v-bind:src='item.thumbnail'>
</div>
<div class='media-body'>
<h2 class='media-heading' v-text='item.title'></h2>
<span style='font-size:25px;color:#ccc'>{{item.content | more}}</span>
</div>
</div>
</div>
</div>
↑ 这是第一部分,包含导航与当前分类中全部内容的一个列表。
①: v-show='routerData.mainShow'
这个控制整体部分显示隐藏,与 上一页,下一页按钮为相同的控制数据,因为二者显示,隐藏逻辑是一样的。都是在详情页隐藏,主页显示。
②: v-on:click='link(0)'
导航按钮跳转绑定的函数。
③: v-for='(item,index) in routerData.showData'
循环数据,渲染列表。
④: v-on:click='go(item,index)'
每个列表绑定跳转到详情页的函数。
⑤: {{item.content | more}}
渲染简介,并且通过一个过滤器使内容中数字过多时,进行剪切
<router-view v-bind:router-nesting='routerData'></router-view>
↑ 这是第二部分,子路由入口。v-bind:router-nesting='routerData'
给子路有中渲染页面的数据。
接下来是script部分
首先引入router实例 import router from '.././router'
再接收 zjapp.vue 传输过来的数据 props:["routerData"]
methods方法里函数解释:
go(obj,index){
router.push({path:this.$route.path+"/con",query:{type:index}});
}
↑ 这是列表中内容点击时执行的函数,从 template 中传过来 index 值,添加到 url 中,从而获取这是列表中第几个。
link(num){
var listNum=this.$route.path.slice(6,7);
if(listNum!=num){
router.push("/user/"+num+"/0");
this.isActive=this.$route.path.slice(6,7);
}
}
↑ link(num)函数是导航点击绑定的函数,通过传志 num 将 url 转换为对应的分类,从而触发 watch 重新获取数据。这里加了一个判断,重复点击,无效。
filters:{
more(value){
var newMessage=value.slice(0,40)+"........点击查看更多";
return newMessage;
}
}
↑ 过滤器,剪切字数。
style就不解释了
Ⅱ: showtwo.vue
这个是文件是详情页面,即主页面中的列表内容点击后,跳转的页面。
<template>
<div style='height:700px;padding-top:100px'>
<div>
<img v-bind:src='routerNesting.detailedData.src' style='display:block;margin:0 auto;width:500px'>
<br>
<h2 v-text='routerNesting.detailedData.title'></h2>
<p>{{routerNesting.detailedData.content}}</p>
<button v-on:click='back' class='btn btn-success'>返回</button>
</div>
</div>
</template>
<script>
import router from '.././router'
export default{
props:["routerNesting"],
methods:{
back(){
router.push(this.$route.path.slice(0,9));
}
}
}
</script>
<style></style>
↑ 数据与showone.vue相似,routerNesting
数据是通过ziapp.vue->showone.vue->showtwo.vue传递过来的。
back() 函数将url从/user/0/0/con?type=2
跳转到/user/0/0
触发watch更新数据。
Ⅲ: error.vue
<template>
<div style="margin-top: 150px;">
<h1 style="text-align: center;">遥远的404!</h1>
<div style="width: 150px;margin: 50px auto;">
<button v-on:click="jump(0)" class="btn btn-primary">首页</button>
<button v-on:click="jump(1)" class="btn btn-primary">第一页</button>
</div>
</div>
</template>
<script>
import router from '.././router'
export default{
methods:{
jump(num){
num==0?router.push("/user/0/0"):router.push("/user/1/0");
}
}
}
</script>
<style></style>
↑ 嗯~ o( ̄▽ ̄)o,这个比较简单,不做解释了。
结语
至此,全部都解清楚了,按照步骤来的话一个简单的spa也初见其形。
整体思想:通过watch监控url的变化,变化后执行routerPath()函数,随后重新获取数据。
利用vue-cli配合vue-router搭建一个完整的spa流程的更多相关文章
- [Vue CLI 3] vue inspect 的源码设计实现
首先,请记住: 它在新版本的脚手架项目里面非常重要 它有什么用呢? inspect internal webpack config 能快速地在控制台看到对应生成的 webpack 配置对象. 首先它是 ...
- 手把手搭建一个完整的javaweb项目
手把手搭建一个完整的javaweb项目 本案例使用Servlet+jsp制作,用MyEclipse和Mysql数据库进行搭建,详细介绍了搭建过程及知识点. 下载地址:http://download.c ...
- react全家桶从0搭建一个完整的react项目(react-router4、redux、redux-saga)
react全家桶从0到1(最新) 本文从零开始,逐步讲解如何用react全家桶搭建一个完整的react项目.文中针对react.webpack.babel.react-route.redux.redu ...
- 搭建一个完整的Java开发环境
搭建一个完整的Java开发环境 作为一个Java程序员,配置一个java开发环境是必备的技能,今天给广大菜鸟初学者补上一课.环境的配置,大概就分三个1,JDK 2,Tomcat(或者其他的)3,ecl ...
- asp.netmvc 三层搭建一个完整的项目
接下来用 asp.net mvc 三层搭建一个完整的项目: 架构图: 使用的数据库: 一张公司的员工信息表,测试数据 解决方案项目设计: 1.新建一个空白解决方案名称为Company 2.在该解决方案 ...
- 11. 搭建一个完整的K8S集群
11. 搭建一个完整的Kubernetes集群 1. kubectl的命令遵循分类的原则(重点) 语法1: kubectl 动作 类 具体的对象 例如: """ kube ...
- vue入门(三)----使用vue-cli搭建一个单页富应用
上面两节我们说了vue的一些概念,其实说的知识一点基础,这部分知识我觉得更希望大家到官网进行学习,因为在这里说的太多我觉得也只是对官网的照搬照抄而已.今天我们来学习一下vue-cli的一些基础知识,并 ...
- vue/cli 3.0脚手架搭建
在vue 2.9.6中,搭建vue-cli脚手架的流程是这样的: 首先 全局安装vue-cli,在cmd中输入命令: npm install --global vue-cli 安装成功: 安装完成 ...
- Vue-cli安装步骤,搭建一个完整的 Vue 项目
安装node环境下载 node.js 官网地址:https://nodejs.org/en/ 下载完成后打开然后一路next安装完成后打开 dos 窗口输入命令:node -v 回车会输出node的版 ...
随机推荐
- python3安装opencv及电子书籍(百度云)
不能直接 pip install opencv 正解: pip install opencv-python 记得:请确保网络良好!!!!! (1)这个是我学习的电子书籍:opencv-python ...
- How To:利用frm和idb文件进行数据恢复.txt
在另外一个机器上准备测试数据,并传输到dbadb05机器的/mysql/backup/reco/位置下.开始尝试恢复数据一.使用mysqlfrm获取表结构信息及DDL语句. [mysql@dbadb0 ...
- scrollfix.js插件:滚动固定在某个位置
插件文件在/文件 scrollfix.js 用法: var fix = $(".fix"), fixtop = $(".fix-top"), fixStartT ...
- 通过反编译小程序来学习前端:wxappUnpacker
小程序开发时,会有4种文件:.wxss .json .wxs .wxml. 正式上传到腾讯时,目录会被打包,使用时再发放给客户端. 这个文件包后缀是 .wxapkg.只要手机用过这个小程序,文件 ...
- ajax 传参数 数组 会加上中括号
解决办法 1,由于版本过高导致 我用的是1.9版本 2, 有三种选择. 一种是JSON.stringify([1,2,3]),到后端再解析. 另外一种是后端的接受的contentType改成appli ...
- better-scroll的使用
<template> <div> <div> <h2 class="h2">{{msg}}</h2> </div& ...
- 常见的awk内建变量
FS: 输入字段分隔符变量 语法: $ awk -F 'FS' 'commands' inputfilename 或者 $ awk 'BEGIN{FS="FS";}' OFS: 输 ...
- 《机器学习实战》-逻辑(Logistic)回归
目录 Logistic 回归 本章内容 回归算法 Logistic 回归的一般过程 Logistic的优缺点 基于 Logistic 回归和 Sigmoid 函数的分类 Sigmoid 函数 Logi ...
- 去面试Python工程师,这几个基础问题一定要能回答,Python面试题No4
今天的面试题以基础为主,去面试Python工程师,这几个基础问题不能答错 第1题:列表和元组有什么不同? 列表和元组是Python中最常用的两种数据结构,字典是第三种. 相同点: 都是序列 都可以存储 ...
- CODE【VS】 3160 最长公共子串 (后缀数组)
3160 最长公共子串 题目描述 Description 给出两个由小写字母组成的字符串,求它们的最长公共子串的长度. 输入描述 Input Description 读入两个字符串 输出描述 Outp ...