相关文章推荐
威武的菠菜  ·  奋进新时代的青年人--新闻报道-中国共产党新闻网·  1 年前    · 
鼻子大的牙膏  ·  疯批弟弟终于和太子哥哥有了实质性进展_哔哩哔 ...·  2 年前    · 
冷冷的橡皮擦  ·  世界最早截肢术:印尼婆罗洲3.1万年前的年轻 ...·  2 年前    · 
从容的莴苣  ·  1 我被开除了 - 地产女王 - 包子漫画·  2 年前    · 
彷徨的热水瓶  ·  【深蓝汽车SL03 ...·  2 年前    · 
Code  ›  vue-cli使用指南__vue-cli-service
token vue webpack vue-cli
https://blog.51cto.com/u_12462157/3796117
爱逃课的剪刀
2 年前
  • vue-cli:脚手架,用于快速搭建vue项目
  • vue-router:路由,单页应用的核心插件
  • vuex:状态管理,可管理全局数据。在小项目中用vuex有点繁琐,建议大项目用vuex,小项目用bus总线
  • axios:对ajax的封装
  • 使用vue-cli搭建Vue项目

    1、安装npm

    2、安装webpack

    npm install webpack -g
    

    3、使用vue-cli搭建vue项目

    #安装最新稳定版的vue-cli
    npm install @vue/cli -g
    #初始化项目
    vue create 项目名
    #选择自定义,空格键选中、取消选中
    #选择babel、router、vuex(根据需求)
    #使用history模式的路由
    #In dedicated config files,babel等配置写在单独的文件中
    

    4、项目根目录下新建 vue.config.js ,写自定义的配置。示例

    module.exports={
        configureWebpack:{
            devServer:{
                port:9000,  //使用的端口号,默认8080
                open:true,  //自动在浏览器中打开页面,默认false关闭
    

    项目启动时会自动加载根目录下的vue.config.js,vue.config.js中配置项的写法可参考
    https://cli.vuejs.org/zh/config/#vue-config-js

    单页的编写

    1、替换页面图标 public/favicon.ico,根据需要修改public/index.html

    2、在App.vue中写页面的公共部分

    3、在views中写分页,Xxx.vue

    4、要在多个分页中使用的部分,写成组件(Xxx.vue)放到components下,在分页中引用

    5、静态资源放在assets目录下,在assets新建css、js、img文件夹来存放
     

    Xxx.vue的基本骨架:<template>、<script>、<style>

    <template>
        <HelloWorld msg="hello"/>  <!-- 使用组件,父子组件之间可以通过属性传递数据 -->
      </div>
    </template>
    <script>
    // 引入components下的组件(相当于声明组件),@是/src的别名
    import HelloWorld from '@/components/HelloWorld.vue'
    //不需要new Vue,然后在里面写data、methods,直接在export default中写即可
    export default {
      name: 'Home',  //当前组件的名称
      components: {  //注册当前组件中要使用的其它组件
        HelloWorld  //有多个时逗号分隔
      data(){
      methods:{
    </script>
    <!-- <style scoped> 如果加了scoped属性,则定义的样式只在当前.vue中有效 -->
    <style>
    </style>
    

    vue代码提示常用插件:Vue 2 Snippets(推荐)、VueHelper
     

    4、在router/index.js中配置路由(分页)

    //引入分页
    import Login from '../views/Login.vue'
    //配置分页的路由
    const routes = [
        path: '/',   //首页
        name: 'Login',
        component: Login   //这里直接写的组件名,所以要在开头import导入
        path: '/register',
        name: 'Register',
        component: () => import('../views/Register.vue')  //除了首页,分页都使用路由懒加载,防止加载首页时卡顿
    axios的使用 
    

    安装axios

    npm install axios --save
    

     
    在main.js中导入axios

    import axios from 'axios'
    // 挂载到Vue原型上,属性名常用$axios、$http
    Vue.prototype.$http=axios
    //设置axios请求中url的默认前缀
    axios.defaults.baseURL = 'http://localhost:8080/msg'
    //如果前后端部署时使用相同的域名,比如使用的是模板引擎,可以使用 window.top.location.origin 直接获取当前js文件所在域名
    //axios.defaults.baseURL = window.top.location.origin + '/msg'
    

     
    axios使用示例

    this.$http
      .get("/task/send", { username: "chy", age: 20 })  //第二个参数指定要传递的数据
      .then(resp => {
        console.log(resp.data);
      .catch(error => {
        console.log(error);
      });
    

    使用axios上传文件并携带其它参数

    // 配置请求头,允许上传文件。默认的Content-Type是 'application/json'
    let config = {headers:{'Content-Type':'multipart/form-data'}}
    let param=new FormData();
    param.append("file",this.uploadFile);
    //要携带的其它参数
    param.append("username",this.username);
    //FormData不能直接添加一个数组,只能逐个添加数组中的元素,append(key,value),key相同时会把value放在一个数组中
    this.friendList.forEach(ele => {
    	param.append("friendList",ele);
    });
    // 向后端发起请求
    this.$http
        .post("/task/add", param, config)  //参数、请求头配置
        .then(resp => {
            console.log(resp.data);
        .catch(error => {
            console.log(error);
        });
    
    • 参数是(url,param,config),url必需,param,config可选
    • 支持get、post、put、delete、head等多种请求方式

    如果用post,数据在请求体中,后端接收参数时要用 @RequestBody或@RequestParam 标注形参;但使用axios上传文件时,后端接收参数时不能用 @RequestBody、@RequestParam 标注形参。
     

    有时候图方便,直接把其它组件或路由携带的整个对象赋给this.xxx,然后把整个this.xxx提交给后端,这种方式可能会提交一些多余的、没有值的字段,导致后端参数接收、转换出错。

    比如后端实体有createTime这个Date类型的字段,本来不需要传这个字段,前端传了一个值为null或空串的createTime,后端解析参数会报错。

    不传xx字段,和传了值是null或空串的这个字段,这是2个概念。不传这个字段,后端实体直接初始化这个字段为对应类型的初始值;传了一个值null的字段,后端转换参数容易出错。前端初始化要提交的字段时,慎用null,尽量用空串之类的,尽量只提交需要的字段。

    vuex的使用

    vuex是一个状态仓库,用于存储、管理全局数据,常用于组件、页面之间的数据传递、共享。

    store/index.js

    import Vue from 'vue'
    import Vuex from 'vuex'
    Vue.use(Vuex)
    export default new Vuex.Store({
      state: {  //在state中写要存储的变量
        token:'',
        cart:[]
      mutations: {  //在mutations中写操作变量(数据)的方法。state会自动传入
        setToken(state,token){  
          state.token=token
      actions: {
      modules: {
    

    此种写法了解即可,下面介绍了更常用的写法。
     

    main.js中自动引入了vuex的store,可以在项目中直接用store

    import store from './store'
    
    //存储到vuex中,第一个参数指定方法名,后续的参数指定实参
    this.$store.commit('setToken',resp.data.token); 
    this.$store.state.xxx
    

    如果要清空vuex中的某个变量,可以this.$store.commit()传入空值,也可以在store/index.js的mutations中写一个清空变量的方法,给外部调用。

    比如对象赋为{ },数组赋为[ ],空对象、数组。
     

    vuex中数据的保存

    通过vue路由进行跳转时,vuex中的数据不会丢失,但刷新单页中的某个页面时vuex中的数据会全部丢失,通常要把vuex中的数据保存在浏览器的本地存储中。

    store/index.js

    import Vue from 'vue'
    import Vuex from 'vuex'
    Vue.use(Vuex)
    let store = new Vuex.Store({
      state: { 
        token:'',
        cart: JSON.parse(localStorage.getItem('cart')) || [], //先从本地存储中获取,如果没有才置为空数组
      mutations: {
        setToken(state,token){  
          state.token=token
      actions: {
      modules: {
    //监听mutations中的方法调用,每次调用mutations中的方法时,都会将指定数据更新、保存到本地存储中
    store.subscribe((mutations,state)=>{
      //可以缺省window
      window.localStorage.setItem('cart',JSON.stringify(state.cart))
    //将store模块暴露出去
    export default store
    axios的全局拦截 
    

    前后端分离的项目,一般是用ajax交互,有时候需要拦截请求、响应做一些额外的处理。

    src下新建setaxios.js

    import axios from 'axios'
    import store from './store'
    import router from './router'
    //http全局拦截
    //token要放在我们请求的header上面带回去给后端
    export default function setAxios(){
        //拦截请求,使用axios发起请求时拦截,在请求头中加入token
        axios.interceptors.request.use(
            config=>{
                if(store.state.token){
                    config.headers.token=store.state.token
                return config
        //拦截响应
        axios.interceptors.response.use(
            response=>{
                if(response.status==200){
                    const data=response.data
                    if(data.code==-1){  //假设后台校验token,发现token已过期,返回的code为-1
                        //登录过期 需要重新登录 清空vuex的token和localstorage的token
                        store.commit('settoken','')
                        localStorage.removeItem('token')
                        //跳转到login页面。使用replace(),不插入到历史记录中
                        router.replace({path:'/login'})
                    return data
                return response
    

     
    在main.js中设置axios的拦截

    import setaxios from './setaxios'
    setAxios()
    axios的跨域问题 
    

    参考:javascript:void(0)

    使用Mock模拟后端接口返回数据

    mock常用于前后端分离的项目,后端还没写好暴露给前端的接口时,前端可以用mock模拟后台接口返回数据进行调试,使前端可以独立开发,不必停下开发进度等后端。

    嵌套路由用于在一个页面中再嵌套页面

    eg. ,/phone/apple,/phone/huawei,/phone/xiaomi

    <!-- 在一级路由中给二级路由预留位置 -->
    <router-view />
    
    {  //一级路由
        path: '/phone',
        name: 'Phone',
        component: Phone,
        children:[  //二级路由(嵌套路由),path不加/
    		    path: 'apple',
    		    name: 'Apple',
    		    component: () => import('../views/Apple.vue')
    		    path: 'huawei',
    		    name: 'Huawei',
    		    component: () => import('../views/Huawei.vue')
    

    路由守卫可以在单页的路由跳转(包括刷新当前页面)时做一些前处理。

    eg. 跳转到某些页面时,先校验用户是否已登录、是否有指定权限,满足条件才跳转

    router.js

    {  //一级路由
        path: '/msg',
        name: 'Index',
        component: Index,
        meta:{
        	requireAuth: true,  //自定义的标志,为true时需要登录才能访问该页面
    

     
    main.js

    //路由守卫,beforeEach()是路由前置钩子函数。next指定要执行的方法
    router.beforeEach((to,from,next)=>{
    	//刷新页面时vuex的数据会丢失,需要重新设置
      store.commit('settoken',localStorage.getItem('token'))
      if(to.meta.requireAuth){
        if(store.state.token){
          next()  //跳转到目标页面,()中可以传递参数
        }else{
          next({  //跳转到登录页面
            path:'/login',
            query:{redirect:to.fullPath} 
      }else{
        next()
    

    执行的都是next(),不设置参数的next()默认是跳转到目标页面;设置了参数的可以跳转到指定页面

    引入jq(不推荐)

    1、安装jq的依赖

    npm install jquery --save
    

     
    2、在vue.config.js中添加配置
    vue-cli使用指南_vue-cli

    const webpack = require('webpack')
    module.exports = {
        configureWebpack:{
            devServer:{
                port:9000,
                open:true,
        //声明jq的$、jQuery
        chainWebpack: config => {
            config.plugin('provide').use(webpack.ProvidePlugin, [{
                $: 'jquery',
                jQuery: 'jquery'
            }])
    

     
    3、在main.js中引入jq

    import $ from 'jquery'
    

     
    4、使用示例

    <script>
    $(function () {
    	//jq代码
        $('#btn').click(function () {
            alert('ok');
        });
    });
    export default {
    </script>
    

    注意:需要把jq代码放在$(function () { }中才有效,因为vue使用的是虚拟dom,jq代码要在dom加载完成后才能执行。在vue中使用jq有点鸡肋。

    运行、调试

    cd到项目根目录下

    #如果是刚从 svn|git 拉取的项目,先安装所需依赖
    #npm install
    npm run serve
    

    chrome安装插件 Vue.js devtools用于调试vue-cli项目,此插件只能调试vue-cli项目,如果只是在模板引擎之类的页面中使用Vue,则无法使用此插件进行调试。

    在vue.config.js中配置publicPath、assetsDir

    const webpack = require("webpack");
    module.exports = {
        publicPath: "/mall-admin/",   //部署到哪个应用中,即项目url的根目录
        assetsDir: "static",  //静态资源打包到哪个目录下
        configureWebpack: {
            devServer: {
                port: 9000,
                open: true,
        chainWebpack: (config) => {
            config.plugin("provide").use(webpack.ProvidePlugin, [
                    $: "jquery",
                    jQuery: "jquery",
            ]);
    
    • publicPath:要部署到域名下的哪个目录(应用)中,默认/ 直接部署到域名下。
    • outputDir:输出目录,默认dist
    • assetsDir:静态资源的打包输出目录,输出到outputDir的哪个目录下,默认’’ 直接输出到outputDir下

    配置参考:https://cli.vuejs.org/config
     

    #构建生产版,会输出到dist文件夹
    npm run build
    

    https://cli.vuejs.org/zh/guide/deployment.html#%E6%9C%AC%E5%9C%B0%E9%A2%84%E8%A7%88

    Uncaught RangeError: Maximum call stack size exceeded

    常见原因:UI框架的标签和我们自定义的vue组件重名了,修改我们自定义的组件名称即可

    使用history模式的路由时,重复点击路由到同一页面,虽然页面显示正常,但控制台会报错

    vue-router.esm.js?8c4f:2062 Uncaught (in promise) Error: Avoided redundant navigation to current location: “/xxx”.

    解决方式:在router/index.js中添加

    // 解决history模式,路由重复的问题
    const originalPush = VueRouter.prototype.push
    VueRouter.prototype.push = function push(location) {
      return originalPush.call(this, location).catch(err => err)
    

    可以加在router/index.js中,也可以加在其它文件中,只要该文件导入了VueRouter即可

    import VueRouter from 'vue-router'
    手动调用methods中的方法时,提示方法未定义 
    

    需要通过this来调用methods中的方法

    mounted() {
       // 加this
       this.getTaskList();
    methods: {
       getTaskList() {
       toAdd() {
           // 加this
       	   this.getTaskList();
    配置生效问题 
    

    修改src/main.js、vue.config.js后,需要重启项目才会生效

    vue-cli 3.x及之后的项目中没有webpack的配置文件

    从vue-cli 3.x开始,用vue.config.js代替了webpack的配置文件,可以把webpack的配置写在vue.config.js中。

    配置写法参考:https://cli.vuejs.org/zh/guide/webpack.html

    axios传到后端的参数都是null

    参考:javascript:void(0)

    版本控制与依赖

    一般不把 node_modules 上传到svn或者git仓库中,拉取项目后需要先安装项目依赖

    #安装项目依赖
    npm install
    过渡(滑动)效果 
    

    页面切换时,一般不直接切换,写一个过渡效果(滑动),使用户体验更好

 
推荐文章
威武的菠菜  ·  奋进新时代的青年人--新闻报道-中国共产党新闻网
1 年前
鼻子大的牙膏  ·  疯批弟弟终于和太子哥哥有了实质性进展_哔哩哔哩_bilibili
2 年前
冷冷的橡皮擦  ·  世界最早截肢术:印尼婆罗洲3.1万年前的年轻人切除了左脚_手术_研究人员_遗骸
2 年前
从容的莴苣  ·  1 我被开除了 - 地产女王 - 包子漫画
2 年前
彷徨的热水瓶  ·  【深蓝汽车SL03 纯电版】深蓝汽车_深蓝汽车SL03 纯电版报价_价格_深蓝汽车SL03 纯电版图片_参数_搜狐汽车
2 年前
今天看啥   ·   Py中国   ·   codingpro   ·   小百科   ·   link之家   ·   卧龙AI搜索
删除内容请联系邮箱 2879853325@qq.com
Code - 代码工具平台
© 2024 ~ 沪ICP备11025650号