vue-cli-service不是内部或外部命令 找不到相关的依赖包
npm/cnpm install
yarn run build
npm run serve
public 内生成
yarn install
yarn run serve
yarn run build
安装包下载地址:https://nodejs.org/en/
安装包下载安装完成后,在命令行使用 node -v 查看node版本,判断是否安装成功。
安装淘宝镜像:
npm install -g cnpm --registry=https://registry.npm.taobao.org
安装webpack:
npm install [email protected] -g
webpack -v 查看版本号
安装vue-cli脚手架工具
npm install vue-cli -g
vue -V 查看版本号(注意这里是大写的“V”)
第三步,创建项目
使用sever管理器 (不推荐):
vue create project-name
使用webpack管理器 (推荐):
vue init webpack “项目名”
y,y,n,回车,回车,回车,回车,y
第四步,运行
cd 到你的项目文件夹
运行项目 npm/cnpm run dev
安装依赖 npm install (谨慎使用)
复制网址至浏览器即可
内容:
其中src是我们写的东西,包含大概以下文件!
在components 里直接创建新的.vue文件即可
####### 写新的路由:
组件想要使用(在页面渲染)必须要配置路由才可以
在 router 文件中 按照上面的格式,写上自己的组件名和路由名即可
项目打包:
输入 npm/cnpm run build 即可将项目打包(压缩包)
vue 脚手架 组件用法:
! 注意: vue组件中的全部html都存在于一个块元素中,就是app.vue中的 id名字为app的div。
所以,一个模板中,值允许存在一个块元素,也就是说,不可以在app.vue中,添加其他的div
新建组件之后,写法与html一致
其中:
vue脚手架 功能更加强大 包含 v-xx等一系列功能
渐进式 框架 MVVM
npm i logo --registry=https://registry.npm.taobao.org
npm config set registry https://registry.npm.taobao.org
npm install -g @vue/cli
清node_modules
npm cache clean --force
npm install
npm run build/dev/server/init
npm init -y
npm install eslint --save-dev
cd ./node_modules/.bin/
eslint --init
vue init webpack xxxx
npm install -g xxx
vue create xxx
选择 Router vueX 等插件 选择版本
选择特性 feature Jest
选择配置项 package.json
cd 到项目目录
npm run server
Element UI
axios.post()
— 注意有 跨域 vue.config.js 配置 devServer{ }
用来监控自己定义的变量
该变量不在data里面声明,直接在computed里面定义,然后就可以在页面上进行双向数据绑定展示出结果或者用作其他处理;
比较适合对多个变量或者对象进行处理后返回一个结果值
watch
主要用于监控vue实例的变化,它监控的变量当然必须在data里面声明才可以,
它可以监控一个变量,也可以是一个对象
插槽用于决定将所携带的内容
模块化 模板分块 插槽显不显示、怎样显示是由父组件来控制
插槽在哪里显示就由子组件来进行控制
Props
Usage
< slot > 元素
Shadow DOM 使用 元素将不同的 DOM 树组合在一起
Slot 是组件内部的占位符,用户可以使用自己的标记来填充
通过定义一个或多个 slot,您可将外部标记引入到组件的 shadow DOM 中
alt + shift +F 格式化
格式化代码之后会将单引号变为双引号,最后还会加上逗号,末尾的分号于是会导致三种错误:
1.Strings must use singlequote quotes—双引号
2.Extra semicolon semi ----末尾分号
3.error Unexpected trailing comma comma-dangle—逗号
rules: {
"space-before-function-paren": 0,
'no-console': process.env.NODE_ENV === 'production' ? 'warn' : 'off',
'no-debugger': process.env.NODE_ENV === 'production' ? 'warn' : 'off',
'quotes': 'off',
'semi': 'off',
'comma-dangle': 'off',
'eslint eol=last': 0, 實在不行 就 script空出來一行 末尾空一行
}
npm uninstall less-loader
npm install [email protected]
npm init -y
npm install eslint --save-dev
cd ./node_modules/.bin/
eslint --init
vue ui
一个html文件中 直接可以通过script标签引入Vue.js
(1)el表明我们的Vue需要操作哪一个元素下的区域,'#demo’表示操作id为demo的元素下区域。
(2)data表示Vue 实例的数据对象,data 的属性能够响应数据的变化。
(3)created表示实例生命周期中创建完成的那一步,当实例已经创建完成之后将调用其方法。
(1)v-text: 用于更新绑定元素中的内容,类似于jQuery的text()方法
(2)v-html: 用于更新绑定元素中的html内容,类似于jQuery的html()方法
(3)v-if: 用于根据表达式的值的真假条件渲染元素,如果上图P3为false则不会渲染P标签
(4)v-show: 用于根据表达式的值的真假条件 显示隐藏元素,切换元素的 display CSS 属性
(5)v-for: 用于遍历数据渲染元素或模板,如图中P6为[1,2,3]则会渲染3个P标签,内容依次为1,2,3
(6)v-on: 用于在元素上绑定事件,图中在P标签上绑定了showP3的点击事件
·····················
·····``除了Vue.js我们还需要用到:
(1)vue-cli:Vue的脚手架工具,用于自动生成Vue项目的目录及文件。
(2)vue-router: Vue提供的前端路由工具,利用其我们实现页面的路由控制,局部刷新及按需加载,构建单页应用,实现前后端分离。
(3)vuex:Vue提供的状态管理工具,用于同一管理我们项目中各种数据的交互和重用,存储我们需要用到数据对象。
(4)ES6:Javascript的新版本,ECMAScript6的简称。利用ES6我们可以简化我们的JS代码,同时利用其提供的强大功能来快速实现JS逻辑。
(5)NPM:node.js的包管理工具,用于同一管理我们前端项目中需要用到的包、插件、工具、命令等,便于开发和维护。
(6)webpack:一款强大的文件打包工具,可以将我们的前端项目文件同一打包压缩至js中,并且可以通过vue-loader等加载器实现语法转化与加载。
(7)Babel:一款将ES6代码转化为浏览器兼容的ES5代码的插件
(1)npm install -g vue-cli:全局安装vue-cli
(2)vue init webpack my-project: 利用vue-cli在目录地址生成一个基于webpack的名为’my-project‘的Vue项目文件及目录
(3)cd my-project:打开刚刚创建的文件夹
(4)npm intall:安装项目所依赖的包文件
(5)npm run dev:利用本地node服务器在浏览器中打开并浏览项目页面
VUE下载
https://nodejs.org/en/download/ nodejs 下载
npm install -g cnpm --registry=https://registry.npm.taobao.org
$emit
来实现子组件向父组件传递数据。当然如果是较为复杂和普遍的数据交互,建议大家使用vuex来同一管理数据。 this.$emit('事件',参数)
详情请见:https://vuefe.cn/guide/components.html#使用Props传递数据
基于webpack的vue项目中我们是如何使用插件的
(一)全局使用
(1)在index.html引入:
这样的方式不推荐使用,因为存在先后加载顺序的问题
有些插件不支持这一方式。
(2)通过webpack配置文件引入:
主要通过plugin配置webpack.ProvidePlugin()方法实现,
不过只适合支持CommonJs规范并提供一个全局变量的插件,
如jQuery中的$。
(3)通过import + Vue.use()引入:
这种方式需要在全局.vue文件中import需要加载的插件,
然后通过Vue.use(‘插件变量名’)来实现,不过此方法只支持遵循Vue.js插件编写规范的插件使用,
如vue-resourece。
(二)单文件使用
(1)通过import直接引入:
这种方式可以在需要调用插件的.vue文件中使用,
不过需要注意和实例的创建顺序问题,或者也可以通过require引入。
(2)import + components注册:
此方式为Vue组件的使用方式,
可以在一个组件中注册并使用一个子组件。
(1)使用webpack的DefinePlugin指定生产环境:
通过plugin中的DefinePlugin配置,我们可以声明’process.env’属性为’development’(开发环境)或者’production’(生产环境),
结合npm配置文件package.json中scripts的命令来切换环境模式十分方便。
(2)使用UglifyJs自动删除代码块内的警告语句:
一般在生产环境的webpack配置文件中使用,
通过newwebpack.optimize.UglifyJsPlugin()来进行配置,
删除警告语句可以缩减文件的体积。
(3)使用Webpack hash处理缓存:
当我们需要对发布到线上的文件进行修改时,重新编译的文件名如果和之前版本的相同会引起浏览器无法识别而加载缓存文件的问题。
这样我们需要自动的生成带hash值的文件名来阻止缓存。详见:https://segmentfault.com/a/1190000006178770#articleHeader7
(4)使用v-if减少不必要的组件加载:
v-if指令其实很有用处,
它可以让我们项目中暂时不需要的组件不进行渲染,
等需要用到的时候在渲染,比如某个弹窗组件等。
这样我们可以减少页面首次加载的时间和文件量。
除了以上几点的优化,还有很多优化选择,
有兴趣的童鞋可以好好地了解下webpack的API文档,
毕竟webpack的功能十分强大。
- 对比
vue-cli github地址
import Vue from 'vue' //引入 文件
import App from './App' //APP.vue
import router from './router'
Vue.config.productionTip = false
new Vue({ //实例化vue 依赖APP
el: '#app', //挂载点
router,
components: { App }, //注册 插件 APP:APP
template: ' '
})
vue组件
vue 源码资源打包 - webpack 编译 ---->html + app.js
开发webpack 配置解析
从入口看 dev webpack如何编译
各种依赖
文件路径 操作方法
nodejs框架
express 启动webserver
webpack 核心编译工具
node.js 开放API (支持引入)
引入一个 运行开发配置文件
proxymiddleware HTTP代理转发中间件
webpackconfig webpack配置
dev 开发时
merge 合并配置文件用的
untils 用的一些工具方法
basewebpackconfig webpack配置文件 (开发/编译共享文件)
htmlwebpackplugin 操作html插件
output 输出配置
path 文件路径 对应assetsroot (在当前目录下 创建一个dist 当作输出目录)
extensions 自动补全 文件后缀
fallback 指向node_modules模块
alias 提供别名 require路径缩短字符串长度
功能跟fallback类似
类似文件处理 loader 做编译
扫描工程目录 根据后缀名 匹配文件
文件内容 输入 loader输出
preloaders 在loader 之前处理eslint
loaders 不同loader处理
include 检查目录里的文件 处理编译
exclude 排除目录
limit 限定图片文件大小 小于10kb 生成字串
name 小于:base64字符串打包到 编译好的 js文件里
大于 :单独生成一个文件
生成 命名规则assetspath方法 对应
又指向
拿到assetsubdirectory 这个字串 拼接path 这个参数
生成 static/img/filename+file hash + ext (拓展名)
字典文件 规则同上
eslint formatter 检查到错误提示错误信息 并提供规则链接
vue loader css处理文件 loader
指向
返回各种css预处理器对象
根据generateloaders 生成值
传入 名称数组 通过判断字符数组的 元素 字符串
拼接 生成 各种预处理器loader
dev conf 这个文件
entry -> dev client 入口文件 --> 数组
加上
启动 hot-reload 热加载技术代码
(当改变源码是 浏览器不用刷新 也可浏览到变化的页面)
(过程失败 自动刷新浏览器)
合并
指向
同是 css loader
遍历 扩展名 拼接再调用 cssloader 处理
用express 启动 拿到app 对象
webpack 编译 传入config 参数
上文 compiler 主要是给 middleware 中间件用
指定了 静态资源的 访问目录
调试运行 express 中强大中间件
编译好 文件 放在内存中
hotmiddleware express 配合中间件、
访问 从当前的 static目录取
是vue全局的导航钩子函数,我个人的理解是,进入某个路由之后触发的钩子函数
this. s t o r e . d i s p a t c h ( ) c o m m i t ( ) 与 store.dispatch()commit()与 store.dispatch()commit()与store.getters和storage.get
this.$store.dispatch() 与 this.$store.commit()方法的区别总的来说他们只是存取方式的不同,两个方法都是传值给vuex的mutation改变state
this.$store.dispatch() :含有异步操作,例如向后台提交数据,写法:this.$store.dispatch(‘action方法名’,值)
this.$store.commit():同步操作,,写法:this.$store.commit(‘mutations方法名’,值)
commit: 同步操作
存储 this.$store.commit('changeValue',name)
取值 this.$store.state.changeValue
dispatch: 异步操作
存储 this.$store.dispatch('getlists',name)
取值 this.$store.getters.getlists
1、then()方法是异步执行。
当.then()前的方法执行完后
再执行then()内部的程序,这样就避免了,数据没获取到的问题。
通常用在ajax请求后面
2、catch()方法防止因为错误而造成系统崩溃
在程序逻辑中, 需要在易出现问题的逻辑代码片段上,
加持catch方法, 这样做可以捕获错误, 但是不会影响整个程序运转;
第一个是成功时的回调方法,默认给这个方法传递了成功的数据,
另一个是失败的方法,以及失败的数据
<script>
export default {
name: 'demo',
data() {
return {}
},
methods: {
testDemo(data) {
// ajax请求
testAjax(url, params).then(data => {
// 处理成功
console.log(data)
}, data => {
// 处理失败
console.log(data)
})
}
}
}
</script>
一般情况下,为了不报错,会在then()后面调用.catch(),相当于类似try{}catch(e){} ,可以理解为省略了try()
<script>
export default {
name: 'demo',
data() {
return {}
},
methods: {
testDemo(data) {
// ajax请求
testAjax(url, params).then(data => {
// 处理成功
console.log(data)
}).catch(err => {
// 报错
console.log(err)
})
}
}
}
</script>
如果在then的第一个函数里抛出了异常,后面的catch能捕获到,
而then的第二个函数捕获不到。
因此,建议总是使用catch方法,而不使用then方法的第二个参数。
// 解码用
decodeURIComponent(str)
// 编码用
encodeURIComponent(str)
vue-element-admin-router.addRoutes
https://panjiachen.github.io/vue-element-admin-site/zh/
router.addRoutes
函数签名:
router.addRoutes(routes: Array<RouteConfig>)
动态添加更多的路由规则。参数必须是一个符合 routes 选项要求的数组。
更多动态规则?符合routes选项的要求的数组又长什么样?
const routes = [
{
path: '/',
name: 'Home',
component: Home
},
{
path: '/pageA',
name: 'pageA',
component: pageA,
}
]
const router = new VueRouter({
routes
});
export default router
使用router.addRoutes改造上面的配置,实现
const router = new VueRouter([
{
path: "/",
name: "Home",
component: Home
}
]);
let route=[
{
path: '/pageA',
name: 'pageA',
component: pageA,
}]
router.addRoutes(route);
export default router
把原来的routes配置照搬到一个新的数组中,
就可以作为addRoutes的参数使用,
经验证,通过addRoutes动态配置的方式和普通配置无差异。
你可能会问,这有什么用?那么接下来,我们来谈谈它的应用:
网页有[普通用户,管理员…]等多种角色类型,不同的角色能看到的页面应该是不同的,
比如普通用户不应该看到管理员的控制台,那么这个时候,动态路由就非常有用了
可以这么做
let pageA,pageB,pageC;
let route=[
{
path: '/pageA',
name: 'pageA',
component: pageA,
},
{
path: '/pageB',
name: 'pageB',
component: pageB,
},
{
path: '/pageC',
name: 'pageC',
component: pageC,
}
]
let commonUser=['pageA','pageB'];
let commonUserRoute=route.filter(function(page){
return commonUser.includes(page.name)
})
console.log(commonUserRoute);
router.addRoutes(commonUserRoute);
//结果
// (2) [{…}, {…}]
// 0: {path: "/pageA", name: "pageA", component: pageA}
// 1: {path: "/pageB", name: "pageB", component: pageB}
// length: 2
// __proto__: Array(0)
to:进入到哪个路由去
from:从哪个路由离开
next:路由的控制参数,常用的有next(true)和next(false)
首先判断进入的是否是login页面
然后再判断是否已经登陆
已经登陆了
就进入你要跳转的页面
没登录就进入login页面
Login.vue是登陆页面
Index.vue是全局页面(包含公共导航组件)
A.vue是普通页面(此处我做为首页)
B.vue是普通页面
//router.js
import Vue from 'vue'
import Router from 'vue-router'
Vue.use(Router);
const children = [
{
path: 'a',
name: 'a',
component: () => import('./views/A.vue'),
meta: {
title: 'a页面',
keepAlive: false // 无缓存
}
},
{
path: 'b',
name: 'b',
component: () => import('./views/B.vue'),
meta: {
title: 'b页面',
keepAlive: true // 有缓存
}
},
{
path: '404',
name: '404',
component: () => import('./components/404.vue')
}
];
const router = new Router({
mode: 'history',
base: process.env.BASE_URL,
routes: [
{ path: '/', redirect: '/a' },
{ path: '*', redirect: '/404' },
{
path: '/login',
name: 'login',
component: () => import('./components/Login.vue')
},
{
path: '/',
component: () => import('./components/Index.vue'), //index是上图左边的公共菜单
children //此处是站内页面,页面在右侧container里展示
}
]
});
router.beforeEach((to, from, next) => {
const isLogin = sessionStorage.getItem('isLogin'); //获取本地存储的登陆信息
if (to.name == 'login') { //判断是否进入的login页
if (isLogin == "true") { //判断是否登陆
next({ name: 'a'}); //已登录,跳转首页(a页面)
} else {
next(); //没登录,继续进入login页
}
} else { //如果进入的非login页
if (isLogin == "true") { //同样判断是否登陆
next(); //已登录,正常进入
} else {
next({ name: 'login'}); //没登录,跳转到login页
}
}
});
export default router;
npm install --save nprogress
//导入进度条插件\js与css
import Nprogress from 'nprogress'
import 'nprogress/nprogress.css'
<link rel="stylesheet" type="text/css" href="nprogress.css"/>
<script src="nprogress.js"></script>
NProgress最重要两个API就是start()和done(),基本一般用这两个就足够了。
·
NProgress.start(); //显示进度条
NProgress.done(); //完成进度条
//在request拦截器中显示进度条Nprogress.start()
axios.interceptors.request.use(config => {
//请求开始时显示进度条
Nprogress.start()
return config
})
//response中完成进度条Nprogress.done()
axios.interceptors.response.use(config => {
//服务响应时完成进度条
Nprogress.done()
return config
})
ajaxStart()
ajaxStop()
全局事件代码实现加载效果
<body>
<button id="btn">请求</button>
<script src="nprogress.js"></script>
<script src="jquery.js"></script>
<script>
$(document)
.ajaxStart(function () {
//请求开始了
NProgress.start();
})
.ajaxStop(function () {
//请求结束了
NProgress.done();
})
$('#btn').on('click', function () {
$.get('time.php')
})
</script>
</body>
切成单图
css 拼图 合成 减少数量 性能优化
svg 色彩单一 -----> 图标字体文件
页面整体设计—>根据切图 组件拆分(组件化开发)
整体组件
header组件
导航组件
eslink 不能用分号 强加分号