1.安装node.js
https://nodejs.org/en/
node.js自带npm工具,如果觉得npm下载资源太慢,可继续安装cnpm
npm install -g cnpm
2.安装webpack
npm install webpack -g
验证是否安装成功
webpack -v
3.安装vue-cli脚手架
vue-cli 是用 node 编写的命令行工具,我们需要进行全局安装。
npm install --global vue-cli
验证是否安装成功
vue -V//命名可以得到vue的版本号信息
4.初始化一个vue项目
Vue2.0:使用cd命令找到项目需要放置的文件夹,这里以D盘的【Project/web】为例子
D:
cd Project/web
vue init webpack itemname[项目名]
项目的参数设置
Project name 可不设置,初始化时已经定义了【项目名】项目名不能大写,不能使用中文
Project description 【项目描述】
Author【作者】
Vue build【】https://www.jianshu.com/p/466510d84e36 根据文章描述,推荐使用‘Runtime-Only’
https://blog.csdn.net/qq_37339364/article/details/82931180 根据该文章,Runtime Only相比Runtime+Compiler更加轻量,但是缺点是不能够编译jsx,在vue源码中,无论是render函数,还是template最终都是编译成render函数进行渲染的,所以,使用Runtime Only有时需要自己手动配置webpack对模板语法进行编译。常用的就是Runtime+Compiler,不需要自己手写render。
Install vue-router【安装 vue-router路由管理工具】选yes,vue-router用于单页面应用控制页面跳转
Use ESLint to lint your code?【使用ESLint检查语法错误】新手对ES6不熟一般选No,不然一直报错,调试很费事
Set up unit tests【创建单元测试】选yes;单元测试主要运用在大型项目或者多人合作开发的情况,暂定先安装
Pick a test runner【选择单元测试的工具】一般选jest
Setup e2e tests with Nightwatch【E2E(End To End)即端对端测试(用户真实场景),属于黑盒测试】,选yes
should we run ‘npm install’?选yes,use NPM,关于yarn,可参考https://www.jianshu.com/p/254794d5e741
Vue3.0
vue create hello-world
5.安装jquery
npm install jquery --save
下载完成后,检查node_modules发现自动生成jquery文件夹
检查根目录下的package.json,看是否有jquery依赖,没有的话加上(必须添加)
注:此处用了save安装,所以dependencies中有jquery依赖,而devDependencies中不存在
"dependencies": {
"vue": "^2.5.2",
"vue-router": "^3.0.1",
"jquery":"^3.3.1"//版本号在jquery安装成功后,cmd上自动显示
},
save和save-dev的区别
如果你的项目是发布到npm的一个包,
那么这个包的package.json中的dependencies中的依赖是会被下载下来到这个包的node_modules文件夹中的(如果你的项目本身没有这个依赖),而devDependencies不会。
举个例子:
我发布了一个组件A,它有dependencies:lodash和devDependencies:moment。
那么,如果你的项目npm install 了组件A。
除非你的项目也依赖了lodash并且版本一致,那么项目的node_modules/A下会有一个node_modules,里面会有lodash。
而 moment,则无论如何也不会出现在你的项目中。
至于一般的项目,不管你是安装在dev还是dependencies中,安装的时候都会安装,打包的时候都会被打进去的,区分依赖只是为了让项目看起来更加清晰。
编辑webpack.base.conf.js
‘use strict’前添加
var webpack=require('webpack')
在module.exports里面加入plugins项:
plugins: [
new webpack.ProvidePlugin({
$:"jquery",
jQuery:"jquery",
"windows.jQuery":"jquery"
})
]
在main.js中引用
import $ from 'jquery'
测试jquery是否成功,在app.vue中
$(function(){
alert('123')
})
6.安装bootstrap
npm install bootstrap@3.3.0 -save-dev
main.js中引入
import 'bootstrap/dist/css/bootstrap.min.css'
import 'bootstrap/dist/js/bootstrap.min.js'//js文件按需引入,如果不需要使用则不必引入
也可将css、fonts、js三个文件夹取出,放入src/assets路径中
import './assets/css/bootstrap.min.css'
import './assets/js/bootstrap.min.js'//js文件按需引入,如果不需要使用则不必引入
7.引入less
安装
npm install less less-loader --save-dev
检查package.json devDependencies是否有less依赖,没有的话加上
"less": "^3.9.0",
"less-loader":"^4.1.0"
为什么安装less选择save-dev?
因为less是我们在开发中使用的而非在生产中使用,所以就不将之记录在 dependencies .在开发过程中我们需要使用less-loader将less文件编译成css文件,编译完成后发布到生产环境(服务器)后就不需要使用了。
附
dependencies和devDependencies的区别?
- devDependencies:生产环境使用
- dependencies:线上环境使用
例如:比如 我们安装 js的压缩包gulp-uglify 时,我们采用的是 “npm install –save-dev gulp-uglify ”命令安装,因为我们在发布后用不到它,而只是在我们开发才用到它。webpack,gulp等打包工具,这些都是我们开发阶段使用的,代码提交线上时,不需要这些工具,所以我们将它放入devDependencies即可,但是像jquery这类插件库,如果我们不把他打入线上代码中,那么项目就可能报错,无法运行,所以类似这种项目必须依赖的插件库,我们则必须打入dependencies中
测试less是否引入成功
//在asset里新建theme.less文件
//测试内容为
@color:orange;
.hello {
color: @color;
font-size: 0.45rem;
h2 {
color: @color;
}
}
//在main.js中引入
import './assets/theme.less'
在浏览器中观察效果
注:
由于已经在webpack中配置了,所以这里不需要引入任何less文件,包括less.js
参考链接:
vue-cli构建项目使用 less
初次接触less,引入时出现一些错误,解决方法记录如下
npm install style-loader --save-dev
main.js中引入less文件书写方式改为
import '!style-loader!css-loader!less-loader!./assets/文件名.less'
8.引入Mock.js做接口数据测试使用
npm install mockjs --save-dev
npm install axios --save-dev
axios的作用是拦截ajax请求,并返回mock构造的数据,达到模拟后台接口的目的
步骤:
1.建立目录结构
src>axios>api.js
【定义请求拦截、响应拦截,自定义一个axios的“ajax响应”】
components>mock.vue
【需要使用模拟接口数据的组件】
mock.js
【定义接口数据、Mock.mock()生成简单的api文档】
api.js:
import axios from 'axios'
axios.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded'
// 请求拦截器
axios.interceptors.request.use(function(config) {
return config;
}, function(error) {
return Promise.reject(error);
})
// 响应拦截器
axios.interceptors.response.use(function(response) {
return response;
}, function(error) {
return Promise.reject(error);
})
// 封装axios的post、get、put、patch请求
export function fetch(url,params,method) {
if(method.toLowerCase() === 'get'){
return new Promise((resolve, reject) => {
axios.get(url, params)
.then(response => {
resolve(response.data);
})
.catch((error) => {
reject(error);
})
})
}
else if(method.toLowerCase() === 'post'){
return new Promise((resolve, reject) => {
axios.post(url, params)
.then(response => {
resolve(response.data);
})
.catch((error) => {
reject(error);
})
})
}
else if(method.toLowerCase() === 'put'){
return new Promise((resolve, reject) => {
axios.put(url, params)
.then(response => {
resolve(response.data);
})
.catch((error) => {
reject(error);
})
})
}
else if(method.toLowerCase() === 'patch'){
return new Promise((resolve, reject) => {
axios.patch(url, params)
.then(response => {
resolve(response.data);
})
.catch((error) => {
reject(error);
})
})
}
}
export default {
mockdata(url,params,method) {
return fetch(url,params,method);
}
}
mock.js:
// 'Boolean': Random.boolean,
// 可以生成基本数据类型
// 'Natural': Random.natural(1, 10),
// 生成1到100之间自然数
// 'Integer': Random.integer(1, 100),
// 生成1到100之间的整数
// 'Float': Random.float(0, 100, 0, 5),
// 生成0到100之间的浮点数,小数点后尾数为0到5位
// 'Character': Random.character(),
// 生成随机字符串,可加参数定义规则
// 'String': Random.string(2, 10),
// 生成2到10个字符之间的字符串
// 'Range': Random.range(0, 10, 2),
// 生成一个随机数组
// 'Date': Random.date(),
// 生成一个随机日期,可加参数定义日期格式
// 'Image': Random.image(Random.size, '#02adea', '缩略图'),
// Random.size表示将从size数据中任选一个数据
// 'Color': Random.color(),
// 生成一个颜色随机值
// 'Paragraph': Random.paragraph(2, 5),
//生成2至5个句子的文本
// 'Name': Random.name(),
// 生成姓名
// 'Url': Random.url(),
// 生成web地址
// 'Address': Random.province()
// 生成地址
import Mock from 'mockjs' // 引入mockjs
const Random = Mock.Random // Mock.Random 是一个工具类,用于生成各种随机数据
let data = [] // 用于接受生成数据的数组
let size = [
'300x250', '250x250', '240x400', '336x280',
'180x150', '720x300', '468x60', '234x60',
'88x31', '120x90', '120x60', '120x240',
'125x125', '728x90', '160x600', '120x600',
'300x600'
] // 定义随机值
for(let i = 0; i < 10; i ++) { // 可自定义生成的个数
let template = {
'Id':i.toString(),//编号
'Name': Random.name(), // 生成姓名
'Boolean': Random.boolean, // 可以生成基本数据类型
'Integer': Random.integer(1, 100), // 生成1到100之间的整数
'Date': Random.date(), // 生成一个随机日期,可加参数定义日期格式
'Address': Random.province() // 生成地址
}
data.push(template)
}
let destroyData = function(options){
let rtype = options.type.toLowerCase();
console.log(options)
switch (rtype) {
case 'get':
break;
case 'post':
let ids = JSON.parse(options.body); // 获取请求的ids,将options.body转换为JSON对象
console.log("ids",ids)
ids.map(function(item){
data = data.filter(function (val) {
return val.Id != item; // 过滤掉前台传过来的id对应的相应数据,并重新返回
});
})
return true;
break;
}
}
Mock.mock('/data/query', /get|post/i, data) // 根据数据模板生成模拟数据
Mock.mock('/data/destroy', 'post', destroyData) // 根据数据模板生成模拟数据
mock.vue
<template>
<div>
<input type="text">
<button @click="">增加</button>
<button @click="">查询</button>
<button @click="destroyData()">删除</button>
<button @click="">修改</button>
<ul>
<li v-for="item in lists">{{item.Id}}--{{item.Address}}
<button @click="addArrItem(item.Id,destroyArr);destroyFunc();">删除</button></li>
</ul>
</div>
</template>
<script>
import api from './../axios/api.js'
export default {
name: 'Mock',
data () {
return {
lists:"",
api:{
query:'/data/query',
create:'/data/create',
destroy:'/data/destroy',
modify:'/data/modify'
},
destroyArr:[],
createArr:[],
modifyArr:[]
}
},
created () {
this.queryFunc(this.api.query,this)
console.log('this.destroyArr',typeof(this.destroyArr))
// this.destroyData()
// console.log('this.list',this.list)
},
methods: {
addArrItem:function(item,arr){
if(arr.includes(item)){
}
else {
arr.push(item)
}
},
queryFunc: function(url,obj) {
queryData(url,obj)
},
createFunc:function(){
},
destroyList:function(arr){
var lists =this.lists
arr.map(function(item){
lists = lists.filter(function (val) {
return val.Id != item; // 过滤掉前台传过来的id对应的相应数据,并重新返回
});
})
this.lists = lists;
this.destroyArr = [];
},
destroyFunc:function(){
let url = this.api.destroy;
let arr = this.destroyArr;
let callback = this.destroyList
if(this.destroyArr.length>0){
destroyData(url,arr,callback)
}
else {}
}
}
}
function queryData(url,obj){
api.mockdata(url,'','get')
.then(res => {
console.log('queryData结果',res);
obj.lists = res
})
}
function destroyData(url,params,callback){
api.mockdata(url,params,'post')
.then(res => {
if(res===true){
callback(params)
}
else{
console.log('删除不成功,请检查网络')
}
return res;
})
}
</script>
<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>
</style>
最后,别忘了在main.js里引入mock.js
require('./mock.js')
以下步骤是根据项目需求引入UI框架如 ant design、element ui 、kendo ui
可根据实际情况操作或跳过
9.引入element-ui
npm i element-ui -S
main.js中引入
完整引入:
import ElementUI from 'element-ui'
import 'element-ui/lib/theme-chalk/index.css'//注意源文件夹及源文件名有些是theme-default
Vue.use(ElementUI)
按需引入(推荐):
安装babel-plugin-component
npm install babel-plugin-component -D
修改.babelrc文件【原plugins里插入该数组值即可】
{
"presets": [["es2015", { "modules": false }]],
"plugins": [
[
"component",
{
"libraryName": "element-ui",
"styleLibraryName": "theme-chalk"
}
]
]
}
{
"presets": [
["env", {
"modules": false,
"targets": {
"browsers": ["> 1%", "last 2 versions", "not ie <= 8"]
}
}],
"stage-2"
],
"plugins": ["transform-vue-jsx", "transform-runtime", [
"component",
{
"libraryName": "element-ui",
"styleLibraryName": "theme-chalk"
}
]
]
}
建立路径 src>element>index.js
index.js:
// 导入自己需要的组件
import { Select, Option, OptionGroup, Input, Tree, Dialog, Row, Col ,Button} from 'element-ui'
const element = {
install: function (Vue) {
Vue.use(Select)
Vue.use(Option)
Vue.use(OptionGroup)
Vue.use(Input)
Vue.use(Tree)
Vue.use(Dialog)
Vue.use(Row)
Vue.use(Col)
Vue.use(Button)
}
}
export default element
main.js中引入
import element from './element/index'
Vue.use(element)
在所有页面可以直接使用特定标签调用组件
10.引入ant-design-vue
npm install ant-design-vue --save
配置按需加载
引入【babel-plugin-import】
npm i babel-plugin-import -D
修改.babelrc文件 ,plugin插入设置项
["import", { "libraryName": "ant-design-vue", "libraryDirectory": "es", "style": "css" }]
建立路径src>antd>index.js
import { DatePicker ,Button} from 'ant-design-vue';
const antd = {
install: function (Vue) {
Vue.use(DatePicker)
Vue.use(Button)
}
}
export default antd
main.js中
import antd from './antd/index'
Vue.use(antd)
11.引入kendo ui(kendo for vue)
npm install --save @progress/kendo-ui
npm install --save @progress/kendo-theme-default//安装默认的主题,主题可选其他
按项目需要引入相应的组件,
kendo UI for Vue所有组件链接
如,项目需要使用kendo 的grid
npm install --save @progress/kendo-grid-vue-wrapper
npm install --save @progress/kendo-datasource-vue-wrapper
在main.js中引入依赖
import '@progress/kendo-ui'
//考虑到客户端加载速度,可不全部引入,只引入项目需要的js文件如
import '@progress/kendo-ui/js/kendo.grid.js'
引入样式文件
import '@progress/kendo-theme-default/dist/all.css'
在需要的运用该组件的地方引入组件,如,test.vue里引入
import Vue from 'vue'
import '@progress/kendo-ui/js/kendo.grid.js'
import { Grid, GridInstaller} from '@progress/kendo-grid-vue-wrapper'
import { DataSource,DataSourceInstaller} from '@progress/kendo-datasource-vue-wrapper'
Vue.use(GridInstaller)
Vue.use(DataSourceInstaller);
测试kendo ui for vue在页面上的效果
<template>
<el-tabs type="border-card">
<el-tab-pane>
<span slot="label"><i class="el-icon-date">已完成</i></span>
<div id="vueapp" class="vue-app">
<kendo-datasource ref="datasource1"
:transport-read-url="'https://demos.telerik.com/kendo-ui/service/Products'"
:transport-read-data-type="'jsonp'"
:transport-update-url="'https://demos.telerik.com/kendo-ui/service/Products/Update'"
:transport-update-data-type="'jsonp'"
:transport-destroy-url="'https://demos.telerik.com/kendo-ui/service/Products/Destroy'"
:transport-destroy-data-type="'jsonp'"
:transport-create-url="'https://demos.telerik.com/kendo-ui/service/Products/Create'"
:transport-create-data-type="'jsonp'"
:transport-parameter-map="parameterMap"
:schema-model-id="'ProductID'"
:schema-model-fields="schemaModelFields"
:batch='true'
:page-size='20'>
</kendo-datasource>
<kendo-grid :height="600"
:data-source-ref="'datasource1'"
:pageable='true'
:editable="'inline'"
:filterable="true"
:sortable="true"
:groupable="true"
:selectable="'row'"
:change="showDetails"
:excel-all-pages ="true"
:toolbar= '[
"create",
"excel",
"pdf",
"表单填写链接",
"协同",
"分派",
"批量导出附件"
]'
:excel-file-name="'Kendo UI Grid Export.xlsx'"
:excel-proxy-URL="'https://demos.telerik.com/kendo-ui/service/export'"
:excel-filterable="true"
>
<kendo-grid-column :field="'ProductName'"
:width="220"></kendo-grid-column>
<kendo-grid-column :field="'UnitPrice'"
:title="'Unit Price'"
:format="'{0:c}'"
:width="220"
></kendo-grid-column>
<kendo-grid-column :field="'UnitsInStock'"
:title="'Units In Stock'"
:width="220"
></kendo-grid-column>
<kendo-grid-column :field="'Discontinued'"
:width="220"
></kendo-grid-column>
<kendo-grid-column :command="['edit', 'destroy',{ text: '重做',click: showDetails }]"
:title="'操作'"
:width="240"
:locked="true"
:lockable="false"
></kendo-grid-column>
</kendo-grid>
</div>
</el-tab-pane>
<el-tab-pane>
<span slot="label"><i class="el-icon-date">未完成</i></span>未完成收集列表
</el-tab-pane>
</el-tabs>
</template>
<script>
import Vue from 'vue'
import '@progress/kendo-ui/js/kendo.grid.js'
import { Grid, GridInstaller} from '@progress/kendo-grid-vue-wrapper'
import { DataSource,DataSourceInstaller} from '@progress/kendo-datasource-vue-wrapper'
Vue.use(GridInstaller)
Vue.use(DataSourceInstaller);
export default {
data() {
return {
activeName: 'second',
schemaModelFields: {
ProductID: { editable: false, nullable: true },
ProductName: { validation: { required: true } },
UnitPrice: { type: 'number', validation: { required: true, min: 1 } },
Discontinued: { type: 'boolean' },
UnitsInStock: { type: 'number', validation: { min: 0, required: true } }
}
};
},
methods: {
showDetails:function(e){
e.preventDefault();
var grid = this.$refs.grid.kendoWidget();
// var dataItem = grid.dataItem($(e.currentTarget).closest("tr"));
alert(grid);
},
parameterMap: function(options, operation) {
if (operation !== 'read' && options.models) {
return { models: kendo.stringify(options.models) };
}
}
}
};
</script>
<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped></style>
11. kendo for vue汉化
main.js中引入
import '@progress/kendo-ui/js/cultures/kendo.culture.zh-CN.js'
import '@progress/kendo-ui/js/messages/kendo.messages.zh-CN.js'
刚接触kendo时遇到汉化不成功的情况,解决方案是main.js中添加
kendo.culture("zh-CN")
12.配置kendo ui的excel导出功能
可根据项目实际情况决定是否略过此步骤
常规方法(不起作用)
安装jszip.js并引入
npm install jszip
import 'jszip/dist/jszip.js'
解决方案:index.html中引入
<script src="http://cdnjs.cloudflare.com/ajax/libs/jszip/2.4.0/jszip.js"></script>
或下载到本地引入
<script src="../static/jszip.js"></script>