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>
 
