总结:iview(基于vue.js的开源ui组件)学习的一些坑(三)

1、深入理解vue传参数

(1)params传参数---参数在url中不显示。

需要name:页面路由的名字,需要传递的参数为对象,放在params里面。

  this.$router.push({ name: "list-item-edit", params: {reportItemData:datas} }) 

接收参数:$route.params.reportItemData.

  getAllReportItem(){
          var datas=this.$route.params.reportItemData;
          console.log(datas);
          this.formValidate=datas;
      },

(2)query传参数---参数在url中显示

需要path,页面路径参数,需要query对象存放需要传递的参数

  this.$router.push({ path:"/workreport/setting/list-item",query: {table_id:params.row.id} });

跳转到新页面时:页面url为:http://127.0.0.1:8050/#/workreport/setting/list-item?table_id=96

接收参数:

  this.tid=this.$route.query.table_id;

深入理解:做这个项目时候,需要一直使用table_id,发现如果用params传递参数,如果刷新本页面,那么从上一个页面携带参数进入本页面,会在刷新的过程中变为undefined,虽然这个可以很好的保护数据,让参数不再url中显示,但是容易造成数据丢失。如果用query传递参数,则刷新以后,?后面传递的参数依然在,也可以直接进行后续逻辑操作。

2、新增列表信息后重新进入列表展示页面,页面并没有重新请求数据,使用路由监听即可。

    watch:{
          '$route'(to, from) { // 路由监听,重新获取数据
                    this.getAllReportItem()                       
            }
        },

3、生命周期问题

今天一个小问题困了一个多小时,页面传递过来的table_id参数在页面查询数据时需要使用,结果我在beforeRouterEnter这个钩子函数中,对table_id赋值为url?传递过来的参数。再在created里面调用函数,查询函数,把Table_id给接口,但是fidder抓包工具抓到我给的table_id为undefined。

解决:beforeRouterEnter里面的vm.next()函数在vue生命周期的mounted时候才执行,所以created 时候table_id确实没有值。

直接在cerated生命周期的函数里面给table_id赋值即可。

 created: function () {
            this.getAllReportItem();  },      
       methods:{
            getAllReportItem(){
                 this.tid=this.$route.query.table_id;
                 getReportItem(this.tid,this.pid, this.page_size, this.page_num, this.keyword).then(res => {
                   console.log(res);}
}

4、涉及父子关系的需求。

在本条数据的下级需要给本条数据添加子项,本条数据为table_id,在新增下级菜单时,需要携带该table_id。在新增下级菜单时,本来会有属于自己的Id,注意:这个和table_id不一样!!!!!

在本条数据修改时,table_id为他的父级内容id,这条数据有自己的id,为202,

修改以后在提交到接口,这时增加了column_id,这个和本条数据的Id一样,我赋值给column_id=table_id,导致报错,说项目找不到。

5、iview组件中的开关组件

 render: (h, params) => {
                            return h('div', [
                                h('i-switch', {
                                    props: {
                                        value: params.row.column_state == 1 ? true : false
                                    },
                                    on: {
                                        'on-change': () => {
                                            this.changeState(params.row.column_state, params.index)
                                        }
                                    },
                                }),
                            ]);
                        }

经过测试,返回的值可以是数字01也可以是字符串“0”。“1”

  changeState(state,index) {
                let app = this;
                const change_state = state == "1" ? "0": "1";
                app.itemData[index].column_state=change_state;
            },

5、项目中有需要自动生成表单,引入了一个vue插件,form-create

使用如下:

 <form-create ref="fc" v-model="fApi" :rule="rule" :option="option"></form-create>

(1)rule:需要自动生成的表单字段

 rule: [
    formCreate.maker.input('商品名称1', 'goods_name1').props({
      placeholder: '请输入商品名称'
    }).validate([{
      required: true,
      message: '请输入商品名称',
      trigger: 'blur'
    }]), 
     //第二项
    {
      type: "input",
      title: "商品名称2",
      field: "goods_name2",
      value: "iphone 7",
      props: {
        "type": "textarea",
        "placeholder": "请输入商品名称",
        "rows":5
      },
      validate: [{
        required: true,
        message: '请输入goods_name',
        trigger: 'blur'
      },
      ],
}
]

第一项使用maker来生成。

rule是一个数组对象,每一个表单字段是一个对象。对象的属性有type、fie;ld、props等。自动生成的表单字段也有验证规则,规则validate也是一个是数组对象。

(2)option用来全局配置,是一个对象

 option: {
        //显示表单重置按钮
        resetBtn: true,
        submitBtn:{
          long:false,
            size:"large",
            col:{
              span:16
            }
        },
 //表单提交事件
        onSubmit: function(formData) {
          alert(JSON.stringify(formData));
        }
      },

每一个对象字段里面,也可以有col属性,单独对本表单字段设置样式。 

col:{
        span:12,
        labelWidth:200,
        xs:24
    }

上传图片:主要注意三点

 for (var i = 0; i < res.data.length; i++) {
            if (res.data[i].type == "upload") {     
                res.data[i].props.action = app.action_url;
                res.data[i].props.name = "file";
                res.data[i].props.headers = app.trueHeader;
                res.data[i].props.onSuccess = function(res) {
                  return res.data;
              }
            }

 其中props属性里面你的action是要提交图片接口,onsuccess方法里面的参数是提交图片后返回的图片地址,这样提交图片后可以直接显示在表单上。

6、接下来的一个问题也出在form-create上面,要实现需求,需要在点击提交按钮时提交数据并且把页面转到上一级。但是由于这个在form-create里面的this并不是这个组件,所以无法使用this.$router.

最后只能用原生的办法来跳转页面了:window.location.href="***"

7、在vue页面如何取到dom元素

后台返回的数据如果都是文字则正常显示,如果时一个图片地址,就需要创建一个图片元素,并且插入到dom文档中。

那么如何取到vue中的dom元素呢:

 <div class="dispose" v-for="(content,index) in list">
          <span class="left">{{content.label}}</span>
          <span class="details">{{content.value}}</span>
        </div>

直接$(".left")[0]打印出来时undefined

console.log($(".dispose")[0])

也是输出undefined

需要用ref=name属性,通过$refs.name来获取,也是undefined

原因:ref属性要在mounted中使用,因为只有在执行mounted的时候,vue已经渲染了dom节点,这个时候是可以获取dom节点的,vue中尽量不去操作dom元素,选用ref操作属性获取

 <div  ref="bb"class="content" >
        <div ref="box" class="dispose" v-for="(content,index) in list">
          <span class="left">{{content.label}}</span>
          <span class="details">{{content.value}}</span>
        </div>

这里面也有一个问题,this.$refs如下:

只取到了第一个,取不到v-for循环的那个元素。说明$refs只能取到页面上固定的元素,不能取到自动生成的元素。

使用原生来实现,遇到图片地址即显示本张图片。

build(data){
      var wrap=document.createElement("div");
      wrap.style.cssText = "height:50px;line-height:50px;font-size: 14px;color: #464c5b;";
     var label= document.createElement("span");
     label.style.cssText ="margin-right:30px;";
     label.innerHTML=data.label;
     var content=document.createElement("span");
     var reURL =/(http|https):\/\/([\w.]+\/?)\S*/;
 var url=data.value;
     if(reURL.test(url)){
       var img=document.createElement("img");
      img.style.cssText ="width:100px;height:auto";
       img.src=url;
       content.appendChild(img)
     }else{
      content.innerHTML=data.value;
      }
      wrap.appendChild(label);
        wrap.appendChild(content);
         $("#wrap")[0].appendChild(wrap)
    },

8、要修改iview组件的内嵌样式,可以给组件一个id,然后给class写样式。

<Select id="sel" @on-change="chooseType(note)" v-model="note" placeholder="选择公告类型" multiple
                    style="width:300px;text-align: center;" class="sel">
              <Option v-for="item in List" :key="item.value" :value="item.value">{{item.label}}</Option>
            </Select>

css 样式如下:

#sel .ivu-select-selection{
border-radius: 40px;
}

如果不加Id,写的样式会影响其他页面。经测试,就算加了scoped,也不保证仅在本页面起作用,别的页面也会受影响。

猜你喜欢

转载自blog.csdn.net/runner_123/article/details/86084748