vue项目经验(一)

首先,贴一张vue脚手架的目录

创建组件及引用组件

【创建组件】要在项目目录的components文件夹下(建议新建组件文件命名时,首字母大写)
--------新建User.vue组件--------
<template>   <!-- 当前组件的具体内容 -->
  <div class="Users">
      <ul>
          <li v-for="every in arr" :key="every.id">
            {{every}}
          </li>
      </ul>
  </div>
</template>

<script>
  export default {
    name: "Users",   //当前组件暴露出去的名称
    data(){
      return {
        arr:["亚索","剑姬","卡萨","露露"]
      }
    },
  }
</script>

<style  scoped></style>   //scoped--域,使css样式仅在当前组件生效


【引用组件】引用User.vue组件
***引用组件方法一:在App.vue中直接引用(一般用这种方法)
<template>
  <div id="app">
    <c-users></c-users>   //3、使用组件
  </div>
</template>

<script>
  import Users from './components/Users'   //1、引入组件
  export default {
    name: 'App',
    data(){
      return {

      }
    },
    components:{
      "c-users":Users,    //2、在components中注册当前组件,可以在注册的同时命名,如这里的"c-users":Users,也可以直接注册组件如直接写Users,
    },
  }
</script>

<style></style>

***引用组件方法二:在main.js中将当前组件注册为全局组件再引用(方法二用的少)
import Vue from 'vue'
import App from './App'
import router from './router'
import Users from './components/Users.vue'   //1、引入Users组件

Vue.config.productionTip = false

Vue.component("c-users",Users);  //2、注册为全局组件并命名为c-users,之后在App.vue中调用<c-users></c-users>即可

new Vue({
  el: '#app',
  router,
  components: { App },
  template: '<App/>'
})

属性传值(父组件向子组件传值。传值:string boolean number 传引用:array object)

当一组数据有多个子组件复用的时候,我们可以在父组件中定义,并在子组件需要的时候传递给子组件,以简化代码
【父组件App.vue】
<template>
  <div id="app">
    <c-users v-bind:transValue="oldValue"></c-users>   <!-- 1、绑定oldValue数据,并将数据命名为transValue,绑定后传递到子组件 -->
  </div>
</template>

<script>
  import Users from './components/Users'
  export default {
    name: 'App',
    data(){
      return {
        oldValue:[Jack,Honey,Tandin,Lucy] ,     
      }
    },
    components:{
      "c-users":Users,
    },
  }
</script>

<style></style>

【子组件User.vue】
<template>   
  <div class="Users">
      <div>{{newValue}}</div>
  </div>
</template>

<script>
  export default {
    name: "Users", 
    props:{   /*2、子组件拿取父组件传递的数据 */
      transValue:{    
        type:Boolean,      /*多种可能的类型[Array,String],type可以是String,Number,Boolean,Array,Object,Date,Function,Symbol*/
        required:true,    /*是否必需*/
        default:true,   /*设置默认值(可不写)*/
      },
      list:{
        type: Array,
        required:false,
        default: ()=>[],   //注:类型为Object/Array的必须使用函数返回默认值,()=>[a,b,c]或function(){return [a,b,c]}
      }
    },  
    data(){
      return {
        newValue:this.transValue,    /*【这里传的是引用,所以赋值给新变量以解决传引用引起的问题】*/
      }
    },
  }
</script>

<style></style>


******提个醒儿******:因为vue的父子组件数据传递是单向的数据流。故子组件应避免直接改变父组件传入的数据,否则会引起报错(虽然功能上没什么问题)
通过【传引用】方式传入的数据在当前子组件中更改后,在其他子组件中也会相应改变。而通过【传值】方式传入的数据则各自独立互不干扰。
引用类型:保存在堆中,占用空间不固定,保存和复制的是指向对象的一个指针;值类型:保存在栈中,占用空间固定,保存和复制的是值本身
当数据格式是Number Boolean String时,是传值。当数据格式是Array Object时,是传引用

******如何解决******:将父组件传递过来的值赋值给一个新的变量,在子组件中操作新的变量即可。

******解决异步传值问题******
问题:子组件从父组件拿到的是空值
原因:父组件的值是需要通过异步请求拿到的,但在异步请求还未获取到结果时,已经初始化加载了子组件,所以传了data里定义的空值。
解决:在父组件未拿到值之前,不执行子组件的初始化加载,异步请求成功后,再执行加载,如下
<Son v-if="flag" :datalist="datalist"></Son>

data(){
    return{
        flag:false,
        datalist:[],
    }
}

this.$axios.get(`${api.base}/getdata`).then(res=>{
    if(res.data.code==200){
        this.datalist=res.data.data
        this.flag=true  //在异步请求拿到值后,设置flag为true,此时开始加载子组件
    }
}).catch(err=>{})

属性传值(子组件向父组件传值)

即子组件改变父组件的值,父组件反过来又影响子组件
【User.vue】子组件
<template>   
  <div class="Users">
      <button v-on:click="dataTrans">子向父传值</button>    <!-- 1、定义子向父传值的dataTrans点击事件 -->
  </div>
</template>

<script>
  export default {
    name: "Users",  
    data(){
      return {
        
      }
    },
    methods:{
      dataTrans:function(){   /* 2、dataTrans子向父传值事件执行,开始去往父组件寻找dataSend事件 */
        this.$emit("dataSend","我是一个值")
      }
    },
  }
</script>

<style></style>

【App.vue】父组件
<template>
  <div id="app">
    <c-users v-on:dataSend="dataChange($event)" ></c-users>  
    <!-- 3、寻找到dataSend事件,再往下寻找dataChange事件,dataChange中的$event必须要这么写 -->   
  </div>
</template>

<script>
  import Users from './components/Users'
  import Mans from './components/Mans'
  export default {
    name: 'App',
    data(){
      return {
        title:"我是父组件原本的title"
      }
    },
    components:{
      "c-users":Users,
    },
    methods:{
      dataChange(val){   /* 4、寻找到dataChange事件,将步骤2中的数据"我是一个值"传递进来(val是形参,命名随意) */
        this.title=val  /* 5、将步骤2中的数值赋值给父组件中的title,此时title就改变了,子向父传值完成 */
      }
    }
  }
</script>

<style></style>

解决vue跨域请求的问题,以及使用fetch,axios请求数据

当浏览器报类似于这样的错误时:localhost/:1 Failed to load http://www.thenewstep.cn/test/testToken.php: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:8080' is therefore not allowed access. If an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled.
1、我们需要找到config/index.js页面,然后搜索proxyTable
2、将proxyTable重设:
proxyTable: {
      '/apis': {
        // 测试环境
        target: 'http://www.thenewstep.cn/',  // 接口域名,改成自己请求的接口域名即可
        changeOrigin: true,  //是否跨域
        pathRewrite: {
            '^/apis': ''   //需要rewrite重写的,
        }              
      }
3、我们去使用fetch写请求:
在如App.vue中请求数据
<script>
    export default{

        created(){
            fetch {"/apis/test/testToken.php",{  /*这里的apis就是proxyTable里定义的代理*/
                method:"post",
                headers:{
                    "Content-type":"application/json",
                    token:"32erqwdf3rtw3rwef313ewet",
                },
                body:JSON.stringify({username:"二狗子",password:"123456"})
            }}.then(result=>{
                return result.json()
            }).then(data=>{
                console.log(data)
            })
        }

    }
</script>
我们也可以使用axios写请求:
安装xios包:npm install axios
在main.js中引入axios, import axios from "axios"
在main.js中重定义axios,Vue.prototype.$axios=axios (这样做是为了能够全局使用)
在main.js中设置axios的请求头和content-type:
        axios.default.headers.common['token']="32ed3wqefd432442f231ewq"
        axios.default.headers.post['Content-type']="application/json"

在如App.vue中请求数据
<script>
    export default{

        created(){
            this.$axios.post("/apis/test/testToken.php",{username:"二狗子",password:"123456"}).then(data=>{
                console.log(data)
            })
        }

    }
</script>

4、一定一定要重新启动项目
    
</script>

vue-cli3.0关于webpack的配置文件config,build已经被删除,若是需要进行配置需要自己手动建立一个vue.config.js

具体参考官方文档:https://cli.vuejs.org/zh/config/#vue-config-js

示例【vue.config.js】
module.export={

    publicPath:'/',    /*根路径*/
    outputDir:  'dist1',    /*构建输出目录*/
    assetsDir: 'assets',  /*静态资源目录(js,css,img,fonts)*/
    lintOnSave:false,   /*是否开启eslint保存检测(严格模式),有效值:true||false||'error'*/
    devServer:{
        open:true,   /*项目启动时是否自动打开网页*/
        host:'127.0.0.0',  /*域名*/
        port:9000,   /*端口号*/
        https:false,  /*https设置*/
        proxy:{   /*跨域配置*/
            'apis':{
                 target: 'http://www.thenewstep.cn/',  // 接口域名,改成自己请求的接口域名即可
                 changeOrigin: true,  //是否跨域
                 pathRewrite: {
                     '^/apis': ''   //需要rewrite重写的,
            }
        }
    },

}

vue-cli2.0使用less

1、安装less依赖:npm install less less-loader --save
2、修改webpack.base.conf.js文件,配置loader加载依赖,让其支持外部的less,在原来的代码上添加:
module:{
    rules:[
        /*添加less配置代码*/
        {    
            test: /.less$/,
            loader: "style-loader!css-loader!less-loader",
            options: { sourceMap: true }   // 可以在控制台中看到当前标签样式来自于哪个less文件
        },
        {
            test:/.vue$/,
            loader:'vue-loader',
            options:vueLoaderConfig
        },
        。。。。。。
    ]
}    
3、在style中使用,添加lang="less"
<style scoped lang="less"></style>

除vue定义好的按键修饰符(如enter,space等)之外,自定义按键修饰符

<template>
    <input  type="text" @keyup.f6="add()"  />
</template>

<script>
    Vue.config.keyCodes.f6=117
</script>

针对vue中外部样式不生效问题

使用>>>操作符穿透scoped。
但有些Sass,less之类的预处理器无法正确解析 >>>。可以使用 /deep/ 操作符( >>> 的别名)
如
<style scoped lang="less">
    /deep/ .demo{
                margin-bottom:10px;
                color:#ccc;
            }
</style>

解决浏览器缓存导致异步请求后页面不更新的问题

一般在请求静态资源的时候,浏览器检测不是新数据的话,则会从缓存中读取而不会去进行更新,从而导致后台提交数据后前台不更新的问题。
解决方法1:ctrl+shift+delete呼出浏览器缓存选项,清除缓存即可。但这样的操作对用户不友好,不推荐
解决方法2:控制台中Network里选中Disable cache使浏览器不保存缓存,仅适合开发人员用。
解决方法3:在请求接口的时候带上随机数或者时间戳即可(推荐使用)
getContent(content){
    this.$axios.get(`${common.base}/getDemoList?t=${Math.random()}`).then(res=>{   //添加随机数 `t=${Math.random()}` 或 时间戳 `t=${new Date().getTime()}`
        this.demoList=res.data.list
    }).catch(err=>{})
},
原文地址:https://www.cnblogs.com/huihuihero/p/11420482.html