脚手架
node是用c++写的
chrome借助于v8引擎(c++编写,是node里面的核心),将js直接转为二进制供浏览器使用
一般的js代码想要执行:js-字节码-浏览器(js需要先转为字节码,然后浏览器执行),因此chrome的执行js代码的速度>firfox>IE
node执行文件
node xx.js
项目中使用vue-cli的主要作用:生成webpack配置文件
一.区别
vue-cli3基于webpack4打造,vue-cl2基于webpack3
vue-cli3设计原则是“0配置”,移除配置文件根目录下的build和config等目录
vue-cli3提供了vue ui命令,提供了可视化配置,更加人性化,移除了static文件夹(文件夹中的图片如果小于规定的数据,打包到dist下时会自动转为base64,大于的话会原封不动),新增了public文件夹,并且index.html移动到public中
vue-cli4和vue-cli3区别不大
二.vue-cli安装
vue-cli2:
全局安装:npm install -g vue-cli 或 cnpm install -g vue-cli
卸载:npm uninstall -g vue-cli 或 cnpm uninstall -g vue-cli
#安装完脚手架安装webpack:npm install -D webpack-cli
vue-cli3:
全局安装:npm install -g @vue/cli@版本号 或 cnpm install -g @vue/cli@版本号
卸载:npm uninstall -g @vue/cli@版本号 或 cnpm uninstall -g @vue/cli@版本号
注:原cli3的安装指令为@vue/cli,因为cli4的出现同样使用了@vue/cli,所以想要安装3的版本,就需要在@vue/cli后面加上@版本号(例:npm install -g @vue/cli@3.11.0)。
查看版本号:https://github.com/vuejs/vue-cli/blob/dev/CHANGELOG.md#.
vue-cli4:
全局安装:npm install -g @vue/cli 或 cnpm install -g @vue/cli
卸载:npm uninstall -g @vue/cli 或 cnpm uninstall -g @vue/cli
上面三种方式安装成功之后会在node_global下生成对应的vue模块,使用vue --version
查看
三.创建项目
vue-cli2:
vue init webpack demo //webpack是最常用的,demo 为项目名称,项目名称不能出现大写字母
#如果下载不了模板,需要配置代理,参考:https://blog.csdn.net/qq_42951499/article/details/118485218
vue-cli3/vue-cli4**:
vue create demo //demo 为项目名称
四.项目目录结构
vue-cli2
vue-cli3
vue-cli4
五.run build和run dev入口解析
使用脚手架打包后,会在dist文件夹生成对应的index.html和static文件夹,直接点开index.html一些内容无法加载出来,全局搜索 asstsPublicPath 中的“/”,改为 “./” 即可,在前面加一个点。 如果看到图片不在静态文件夹,设置下打包时图片的大小limit即可。
六.runtime-compile和runtime-only
七.路由
在理解路由之前,先要搞清楚后端渲染、前端渲染、前后端分离、前端路由、后端路由
基本分为三个阶段:
1.后端渲染:后端代码和前端代码全部由后端工程师来写,后端渲染完html返回给浏览器
2.前后端分离:html和python分开写,前端调用后台的api接口
3.前端渲染:
前端路由:
前端路由的核心是:改变url,界面不刷新
1.实现前端路由的两种方法
1.url的hash
console中输入location.hash="s2",浏览器中url也会跟着改变,且界面不会刷新,hash模式很容易判断:看浏览器url中是不是带了#号,如果带“#”,证明是hash模式
2.html5的history
console中:
history.pushState({},"","hh1") #结构类似于栈,先push的后出来
history.pushState({},"","hh2")
history.replaceState{{},"","hh3"} #替代
history.forward() #==history.go(1) #正向查找
history.back() #==history.go(-1) #反向
2.vue-router
vue-router是vue.js的官方插件,是基于路由和组件的,路由改变组件相应地进行切换
1.安装和使用
-
安装vue-router
npm install vue-router --save
-
在模块化的工程中使用
1.导入路由对象,并调用Vue.use(VueRouter) 2.创建路由实例,并传入路由映射配置 3.在vue实例中挂载创建的路由实例
创建项目时候默认选择router路由,会在项目src目录下生成router目录,router下index.js如下
import Vue from 'vue' import Router from 'vue-router' import HelloWorld from '@/components/home' //1.导入路由对象 Vue.use(Router) //2.创建路由实例并导出 export default new Router({ routes: [ { path: '/home', name: 'home', component: home } ] })
main.js挂载路由实例
import Vue from 'vue' import App from './App' import router from './router' //只写目录,会去找目录下找index.js文件 Vue.config.productionTip = false /* eslint-disable no-new */ new Vue({ el: '#app', router, //3.挂载路由实例 render: h => h(App) })
App.vue中使用router-link、router-view
<template> <div id="app"> <router-link to="/home">首页</router-link> //前端渲染为a标签 <router-view/> //渲染对应的组件 </div> </template> <script> export default { name: 'App' } </script> <style> </style>
2.路由重定向
一般初登网页,要默认显示首页内容,或者其他的重定向
export default new Router({
routes: [
{
path: '/',
redirect:"/home" //当url默认输入"/"时,重定向到路由"/home"下
}
]
})
3.改为history模式
在vue-router中,默认是hash模式,也就是浏览器中带"#",如果要改为history模式
export default new Router({
mode:"history", //routes同级目录下添加mode
routes: [
{
path: '/',
redirect:"/home"
}
]
})
4.router-link的属性
router-link和router-view的区别:router-view用来渲染视图,而router-link可改变渲染的标签名
tag:指定router-link渲染成什么标签
<router-link tag="button"></router-link> //渲染成button标签
replace:取消histroy,取消浏览器中后退键
<router-link tag="button" replace></router-link>
active-class:当router-link标签选中时,会自动添加如下图class属性,若要改变其值,在router/index.js:
//1.修改所有router-link标签
export default new Router({
linkActiveClass:"active",
})
//2.修改当前router-link标签
<router-link tag="button" replace active-class="active"></router-link>
//此时,会将下图router-link-active改为active
5.通过代码跳转
// app.vue
<template>
<div id="app">
<button @click="homeclick">首页button</button>
<router-view/>
</div>
</template>
<script>
export default {
name: 'App',
methods:{
homeclick(){
this.$router.push("/home") //== history.pushState("/home"),但代码中不这样写
//this.$router.replace("/home") //==history.replaceState("/home")
}
}
}
</script>
<style>
</style>
6.动态路由
router/index.js:动态路由用:userID来接受
import Vue from 'vue'
import Router from 'vue-router'
import user from '../components/user'
Vue.use(Router);
export default new Router({
linkActiveClass:"active",
mode:"history",
routes: [
{
path:"/user/:userID",
component:user,
}
]
})
app.vue
<template>
<div id="app">
<router-link :to="`/user/`+userId">用户</router-link> //绑定userID,动态给路由index.js中的:userID赋值
<router-view/>
</div>
</template>
<script>
export default {
name: 'App',
data(){
return{
userId:"zhangsan"
}
}
}
</script>
<style>
</style>
组件user.vue:this.$route获取处于活跃状态的路由(index.js下的routes中的某一个),params得到动态参数(:参数)
<template>
<div>
用户界面
<span>{{this.$route.params.userID}}</span>
<span>{{userid}}</span> //得到计算属性userid()
</div>
</template>
<script>
export default {
name: "user",
computed:{
userid(){
return this.$route.params.userID
}
}
}
</script>
<style scoped>
</style>
7.路由懒加载
打包后的文件会存放在如下文件夹中,当路由很多,要加载的文件也就越大,不能一下子加载一个很大的文件,这样可能会造成js加载不过来,造成界面短暂的空白。解决此问题是利用路由懒加载:根据不同路由将对应的js打包到不同的地方,当用到某个路由,再根据路由来加载对应的js
懒加载写法:注释原来的import .. from xx,改为箭头函数即可。
import Vue from 'vue'
import Router from 'vue-router'
// import home from '../components/home'
// import index from '../components/index'
// import user from '../components/user'
const home = () => import("../components/home");
const index = () => import("../components/index");
const user = () => import("../components/user");
Vue.use(Router);
export default new Router({
linkActiveClass:"active",
mode:"history",
routes: [
{
path: '/',
redirect:"/home"
},
{
path:"/home",
component:home,
},
{
path:"/index",
component:index
},
{
path:"/user/:userID",
component:user,
}
]
})
此时,会在js文件夹下生成如下图(有几个路由,就多生成几个js)
8.路由嵌套
在某一组件下还有子组件,需要用到路由嵌套,如果要想在当前界面调用到子组件,需要在当前父组件中加上router-view标签将子组件映射到父组件上,如下:home组件下的子组件
//index.js
import Vue from 'vue'
import Router from 'vue-router'
const home = () => import("../components/home");
const index = () => import("../components/index");
const user = () => import("../components/user");
const child1 = () => import("../components/child1");
const child2 = () => import("../components/child2");
Vue.use(Router);
export default new Router({
linkActiveClass:"active",
mode:"history",
routes: [
{
path: '/',
redirect:"/home"
},
{
path:"/home",
component:home,
children:[ //添加children
{
path:"", //路由重定向(/home => /home/news)
redirect: "news",
},
{
path:"news",
component:child1,
},
{
path:"message",
component:child2,
}
]
}
]
})
home.vue:使用router-link和router-view。
<template>
<div>
home页面
<router-link to="/home/news">消息</router-link>
<router-link to="/home/message">新闻</router-link>
<router-view></router-view>
</div>
</template>
<script>
export default {
name: "home"
}
</script>
9.路由传参
app.vue
<router-link :to="{path:'/user',query:{x:1,y:2}}">用户</router-link>
router/index.js:path只需要对应router-link中的path即可
{
path:"/user",
component:user,
}
user.vue:this.$route.query获取router-link对应的query参数
<template>
<div>
用户界面
<!-- <span>{{this.$route.params.userID}}</span>-->
<span>{{this.$route.query.x}}</span>
<span>{{userid}}</span>
</div>
</template>
<script>
export default {
name: "user",
computed:{
userid(){
// return this.$route.params.userID
return this.$route.query.x
}
}
}
</script>
10.路由嵌套项目中使用
在项目中不同界面之间的跳转用到路由,不能在app.vue中将组件界面全引入进去,这样会全部显示。解决方法:
在每一个父组件中添加router-view标签,这样会把router.js中的children全部加载进去(注:app.vue中加载的是第一层的路由)。
import Vue from "vue";
import Router from "vue-router";
// import HelloWorld from '@/components/HelloWorld'
import Layout from "@/components/layout";
import Login from "@/components/Login";
Vue.use(Router);
export const syncRouterMap = [
{
path: "/",
component: Layout,
redirect: "dashboard/",
meta: { name: "首页", icon: "el-icon-ice-cream" },
children: [
{
path: "dashboard",
name: "Dashboard",
meta: { name: "首页", icon: "el-icon-ice-cream" },
component: () => import("@/components/dashboard")
}
]
},
{
path: "/dashboard1",
component: Layout,
// redirect: "dashboard1/",
meta: { name: "首页", icon: "el-icon-ice-cream" },
children: [
{
path: "index/",
name: "Index",
meta: { name: "个人资料", icon: "el-icon-ice-cream" },
component: () => import("@/components/other/index")
},
{
path: "index2/",
name: "Index",
meta: { name: "个人资料1", icon: "el-icon-ice-cream" },
component: () => import("@/components/other/index2")
}
]
},
{
path: "/login",
name: "Login",
component: Login,
hidden: true //不参与sysncRouterMap的规则
}
];
export default new Router({
mode: "history",
routes: syncRouterMap
});
11.一个界面中同时加载显示多个组件
#index.js
export default new Router({
routes: [
{
path: '/',
name: 'base-page',
components:{
base1: base1,
base2: base2
}
// .default,
},
]
})
app.vue
<template>
<div id="app">
<router-view name="base1"></router-view>
<router-view name="base2"></router-view>
</div>
</template>
<script>
export default {
name: 'electron-project'
}
</script>
<style>
/* CSS */
</style>
八.axios使用
参考: https://www.jianshu.com/p/f12cf6e0547d
1.安装及其方法
-
下载
#npm安装 npm install axios #引用cdn <script src="https://unpkg.com/axios/dist/axios.min.js"></script>
-
主入口main.js中使用
import axios from 'axios' import VueAxios from 'vue-axios' Vue.use(VueAxios,axios);
-
get请求
axios.get('url',{ params:{ id:'接口配置参数(相当于url?id=xxxx)', }, }) .then((res)=>{ console.log(res); // 处理成功的函数 相当于success }) .catch((error)=>{ console.log(error) // 错误处理 相当于error })
-
post请求
const data = { name:'张三', age:23 } axios.post('url',data) .then((res)=>{ console.log(res); // 处理成功的函数 相当于success }) .catch((error)=>{ console.log(error) // 错误处理 相当于error })
-
delete请求
// 如果服务端将参数作为java对象来封装接受 axios.delete('demo/url', { data: { id: 123, name: 'Henry', }, timeout: 1000, }) // 如果服务端将参数作为url参数来接受,则请求的url为:www.demo/url?a=1&b=2形式 axios.delete('demo/url', { params: { id: 123, name: 'Henry', }, timeout: 1000 })
-
put请求
axios.put('demo/url', { id: 123, name: 'Henry', sex: 1, phone: 13333333 })
2.请求放入同一文件中(应用)
src同级目录下新建api文件夹,文件夹下新建api.js
//api.js
import axios from 'axios';
export const getTask = (params) =>{
return axios.get("http://127.0.0.1:8000/test/",{params:params})
};
export const updateTask = params => {
return axios({
method: "post",
url: "http://127.0.0.1:8000/update/",
data: params
})
};
某个组件中应用
sonfun(index,row){
let params = {
name :row.name,
address: row.address
};
getTask(params).then(res =>{
console.log(res);
})
}
//post请求无法上传数据到后台,用URLSearchParams
ensure(){
console.log(this.form.name,this.form.address);
let params = new URLSearchParams();
params.append("index","1");
params.append("name",this.form.name);
params.append("address",this.form.address);
updateTask(params).then(function (response) {
console.log(response);
});
this.dialogFormVisible = false;
}
或者下面方法
#js文件中
import axios from 'axios';
const http = axios.create({ baseURL: 'http://xxx.yyy.zzz:3000/' });
export default {
getXXX(para) {
return http.get(`url/${para}`)
},
setYYY() {
return http.post('other/url');
}
};
#应用
import api from './api';
actions: {
setXXX({ commit }, para) {
return api.getXXX(para).then(({ data }) => {
commit('XXX', data);
});
}
}