Vue材料清单

作者: Yet_Barclay | 来源:发表于2019-05-09 10:40 被阅读2次

    Vue问题整理

    @mouseover

    第三方组件例如el-button中使用类似api失效,此时需要使用@mouseover.native,其它事件类比。

    element文档里没有列出的组件

    el-scrollbar,默认有水平滚动条,可通过设置.el-scrollbar__wrapoverflow-x:hidden隐藏,这里可能需要使用到深度选择器/deep/,>>>才能生效

    data恢复初始值

    Object.assign(this.$data,this.$options.data())
    this.$data是目前DOM中现有的data值,this.$options.data()是初始的data值,这里用到的是Object.assign(target, source)(MDN),即是将source源数据拷贝到target目标值并返回target。和Object.keys,Object.values, Object.hasOwnProperty配合使用起来都比较方便

    $refs 和 ref

    常用功能类似于选择器,使用ref注册引用信息string,使用$refs选中该对象object,相比于id或class选择器减少了获取dom节点的消耗

    v-show / v-if / v-else / v-else-if / v-for

    v-show判断语句是CSS操作,我还在,只不过display:none了,依然存在于dom中
    v-if判断是动态渲染,不合指令就鸿飞冥冥,只存在于JS里,dom里会有一个空注释行< !-- -- >表示可能存在的足迹,elseelse-if的操作一如JS的if else语句
    v-for这里列出了一种配合使用的方法,在v-for语句里可以添加条件判断,list里的某一项符合既定指令的话会添加dom节点,例如对列出的某一项做出解释或提示。写个例子吧

    <div v-for="user in userList" :key="user.id">
        <span v-if="user.name == 'me'">++{{ user.id }}:{{ user.name }}++</span>
        <span v-else>--{{ user.id }}:{{ user.name }}--</span>
        <!--这里用了v-else,3:me只出现一次-->
    </div>
    <!--shows like this-->
    -- 1:him --
    -- 2:you --
    ++ 3:me ++
    -- 4:her --
    

    axios的全局配置

    主要记录一下axios在配置时可以自己添加参数

    axios.defaults.baseURL = 'http://url'
    //baseURL类似实际url的前缀,发起请求时候添加的url会添加至baseURl尾部
    axios.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded'
    //axios默认是application/json的类型,这里全局设置了POST的请求头
    
    // 配置拦截器,可设置token信息
    axios.interceptors.request.use(config => {
      //这里调用了登录时存入session里的token
      let token = window.sessionStorage.getItem('token')
      if (token) {
        config.headers.Authorization = token
        //有token就在请求头里加入授权
      }
      if (config.method == 'post') {
      //post请求里会有其他类型的需求,例如上传文件时用的FormData
        if (!config.typeFlag) {//在config里加了一个自定义的Boolean来判断
          config.data = qs.stringify(config.data)
          //如果没有这个typeFlag,就统一使用qs转换格式,有的话就不做全局设置
        }
      }
      return config
    }, error => {
      return Promise.reject(error)
    })
    
    // 配置响应拦截器
    axios.interceptors.response.use(res => {
      if (res.data.code == '401') {
        window.sessionStorage.removeItem('token')
        //自己常用的401判断
        router.push('/')
        return {data: {
            code: 401,
            msg: '登录超时'
        }}
        //这里重新回了一个data,这样请求实际收到的是这个return的值
      }
      return Promise.resolve(res)
    }, error => {
      return Promise.reject(error)
    })
    
    export default axios
    

    上传文件的实现

    为了排版方便,未使用el-upload

    <!--使用form包裹一个input,用于上传后的清除操作-->
    <form id="uploadForm" style="display:none">
      <el-input id="uploadFile" ref="uploadFile" v-model="file" type="file" accept="application/msword"></el-input>
    </form>
    <!--组合一个带前置按钮的输入框,禁用输入,用于选择文件和显示名称-->
    <el-input v-model="file" size="medium" disabled>
      <template slot="prepend">
        <el-button type="primary" size="medium" @click="chooseFile">选择文件</el-button>
      </template>
    </el-input>
    <el-button type="primary" size="medium" @click="upload" :loading="uploading">上传</el-button>
    
    methods:{
      chooseFile() {
        //模拟点击
        document.getElementById("uploadFile").click();
      },
      upload(){
        this.uploading = true;
        //新建FormData并append文件数据
        let fd = new FormData();
        fd.append("file", this.$refs.uploadFile.$refs.input.files[0]);
        //el-input编译后是两层,外层div包裹input,所以用了两次$refs来获取files,
        //用原生的长度也差不多,不纠结了。
        //fd.append("file", document.getElementById("uploadFile").files[0]);
        this.$http.request({
          url: this.baseUrl,
          method: "post",
          data: fd,
          typeFlag: true,//seeing this flag ?
          headers: { "Content-Type": "multipart/form-data" }
        })
        .then(res => {
            this.uploading = false;
            if (res.data.code == 0) {
              this.$message.success(res.data.msg);
            } else {
              this.$message.warning(res.data.msg);
            }
            //使用form的原生JS方法reset()在上传成功后清除input的files,
            //el-form的resetFields()好像并不好用。
            document.getElementById("uploadForm").reset();
            this.file = ""//名字数据也清掉
            })
        .catch(err => {
            this.uploading = false;
            console.log(err)
        });
      }
    }
    

    ajax请求的异步处理

    ajax请求在大部分情况下需要等待响应结果返回后再进行处理,可以使用ES7 async+await或者ES6 Promise对象的then()catch()方法

    methods:{
      async handleClick(){//async标记为异步函数
        await this.$ajax.post('url',this.config)//await 等待结果返回后再执行下一句
        await ...
      }//需要注意await需要搭配async使用,不可单独存在
      //或者使用Promise方法
      handleSubmit(){
        this.axios.post('url',this.config)
          .then((res)=>{
            console.log(res) 
           })
          .then(()=>{//后边也可以继续加 then...注意方法里的函数不能省略
           })
          .catch((err)=>{//无法获取结果时抓错误,像取消操作,服务器异常
            console.log(err)
          })
      }
    }
    

    vue.config.js

    Vue-CLi里简化处理了文件目录,可以新建vue.config.js进行自定义配置,这里列举一个简单的数据mock写法

    module.exports = {
      configureWebpack: {
        devServer: {//开发环境下
          before(app) {
            //调用get方法时指向以下设置
            app.get('/api/goods', function (req, res) {
              res.json({
                list: [
                  { name: 'good1', price: 100 },
                  { name: 'good2', price: 80 },
                  { name: 'good3', price: 60 }
                ]
              });
            });
          }
        }
      }
    }
    

    然后在页面组件里使用axiosasync+await获取接口数据

    created(){
       axios.get('/api/goods')
         .then(res=>{
           this.goods = res.data.list
         })
         .catch(()=>{})
    }
    //----------
    async created(){
       const res = await axios.get('/api/goods')
       this.goods = res.data.list
    }
    

    相关文章

      网友评论

        本文标题:Vue材料清单

        本文链接:https://www.haomeiwen.com/subject/wkpcoqtx.html