随手备份

193 阅读1分钟
<el-table        v-if="showTable" ref="table"        :data="datas"        :header-cell-style="this.$store.state.rowStyle"        @selection-change="handleSelectionChange"        border        style="height:93%;"      >//上面设置ref,在script中可以通过this.$ref获取this.$nextTick(()=>{     //父组件获取子组件table相当于dom,更新渲染表格的数据     this.$refs.table.doLayout()})

ref有三种用法

1. 加载普通元素上,用this.$ref.[name]获取到的是dom元素

2. ref加在子组件上,用this.$ref.[name]获取到的是组件实例,可以使用组件的所有方法

3. 如何利用 v-for 和 ref 获取一组数组或者dom 节点

注意:

1、ref 需要在dom渲染完成后才会有,在使用的时候确保dom已经渲染完成。比如在生命周期 mounted(){} 钩子中调用,或者 this.$nextTick(()=>{}) 中调用

2、如果ref 是循环出来的,有多个重名,那么ref的值会是一个数组 ,此时要拿到单个的ref 只需要循环就可以了

this.$nextTick

一、示例

先来一个示例了解下关于Vue中的DOM更新以及nextTick的作用。

模板

{{msg}}
Message got outside $nextTick: {{msg1}}
Message got inside $nextTick: {{msg2}}
Message got outside $nextTick: {{msg3}}

<button @click="changeMsg">

Change the Message

Vue****实例

new Vue({

el: '.app',

data: {

msg: 'Hello Vue.',

msg1: '',

msg2: '',

msg3: ''

},

methods: {

changeMsg() {

this.msg = "Hello world."

this.msg1 = this.$refs.msgDiv.innerHTML

this.$nextTick(() => {

this.msg2 = this.$refs.msgDiv.innerHTML

})

this.msg3 = this.$refs.msgDiv.innerHTML

}

}

})

点击前

点击后

从图中可以得知:msg1和msg3显示的内容还是变换之前的,而msg2显示的内容是变换之后的。其根本原因是因为Vue中DOM更新是异步的(详细解释在后面)。

二、应用场景

下面了解下nextTick的主要应用的场景及原因。

  • 在Vue生命周期的created()钩子函数进行的DOM操作一定要放在Vue.nextTick()的回调函数中

在created()钩子函数执行的时候DOM 其实并未进行任何渲染,而此时进行DOM操作无异于徒劳,所以此处一定要将DOM操作的js代码放进Vue.nextTick()的回调函数中。与之对应的就是mounted()钩子函数,因为该钩子函数执行时所有的DOM挂载和渲染都已完成,此时在该钩子函数中进行任何DOM操作都不会有问题 。

  • 在数据变化后要执行的某个操作,而这个操作需要使用随数据改变而改变的DOM结构的时候,这个操作都应该放进Vue.nextTick()的回调函数中。

.sync的修饰符

在vue的组件通信props中,一般情况,数据都是单向的,子组件不会更改父组件的值

不使用sync的情况

{{dd}}//调用子组件        <A :aData='dd'></A>import A from '../TestComponentData/A';export default {    inject:['userInfo'],    components:{        A        // A: () => import('../TestComponentData/A')    },    data(){        return {            dd:'这是父级传给子级的数据'        }}}

子组件中:

<template>    <div>        {{aData}}        <button @click="changeData">            Change the Data        </button>    </div></template><script>export default {    props:['aData'],    methods:{        changeData(){            this.aData = '子集改变了父级的数据';        }    }}</script>

点击按钮前显示:

点击按钮后显示:

父级中的dd没有改变

使用sync修饰符

父组件调用子组件时

{{dd}}<A :aData.sync='dd'></A>

子组件

<template>    <div>        {{aData}}        <button @click="changeData">            Change the Data        </button>    </div></template><script>export default {    props:['aData'],    methods:{        changeData(){            this.aData = '子集改变了父级的数据';            this.$emit('update:aData',this.aData);        }    }}</script>

点击按钮前显示:

点击按钮后显示:

父级中的dd也改变了

Vue值拷贝

// 活动促销tableHdData: [],// 打折促销tableDzData: [],// 值拷贝 _this.tableHdData = JSON.parse(JSON.stringify(res.data.goods_list)); _this.tableDzData = JSON.parse(JSON.stringify(res.data.rate_goods));

捕获异常

this.$axios({        method: "post",        url: "/admin/Audit_Bill/level_save",        data: _data      }).then(res => {          console.log(res);          this.$message1(res.data.msg);          this.handleNodeClick(this.list.id);          this.set_level = false;        }).catch(err => {          //这里打印err没有用不会显示出来,打印err.response会有内容          console.log(err.response);          // 状态码          console.log(err.response.status)          if(err.response.status == 400){            this.$message1(err.response.data.msg);          }        });

Vue中img动态拼接:src图片地址

data(){

return{

gatherInfo: {

title: '库存汇总信息',

img1: 'k1',

img2: 'k2',

img3: 'k3',

},

}

}

//获取图片地址

getImgUrl (img) {

//在vue的js引入图片,就需要使用require("路径")进来

return require("@/assets/images/inventory/" + img+ ".png");

},

el-table多了会卡顿

使用pl-table

Umy-ui

uView UI

是uni-app生态最优秀的UI框架

watch: {

obj: {

handler(newName, oldName) {

console.log('obj.a changed');

},

immediate: true,

deep: true

}

}

watch 里面还有一个属性 deep,默认值是 false,代表是否深度监听,比如我们 data 里有一个obj属性

immediate:true代表如果在 wacth 里声明了 firstName 之后,就会立即先去执行里面的handler方法,如果为 false就跟我们以前的效果一样,不会在绑定的时候就执行。

可以使用watch来进行路由的监听

watch: {

changeShowType(value) {

console.log("-----"+value);

},

'$route'(to,from){

console.log(to); //to__表示去往的界面

console.log(from); //from__表示来自于哪个界面

if(to.path=="/shop/detail"){

console.log("商品详情");

}

}

  }

Vue的table滚动加载

安装:

npm install --save el-table-infinite-scroll

全局引入:

import Vue from 'vue';

import elTableInfiniteScroll from 'el-table-infinite-scroll';

Vue.use(elTableInfiniteScroll);

局部引入:

完整实例

.el-table { width: 100%; }

<el-table

:data="sku_data"

border

sortable

//是否禁用 boolean

infinite-scroll-disabled='scroll_disable'

v-el-table-infinite-scroll="load"

//是否立即执行加载方法boolean

infinite-scroll-immediate='false'

//触发加载距离阈值 px

infinite-scroll-distance='30'

//节流延时 ms

infinite-scroll-delay='300'

height="350"

style="height: 400px;overflow:auto"

class="table-attr"

:header-cell-style="rowStyle"

<el-alert v-if="isflag"

title="正在努力加载中..."

type="success"

center

:closable="false"

style="width:97%"

show-icon>

<el-alert v-if="isMore"

title="没有更多啦!"

type="warning"

center

style="width:97%"

show-icon>

scroll_disable:false,

isMore: false,

isflag: false

//load加载方法

load() {

this.isflag = true;

if(this.sku_total == this.sku_data.length){

this.isMore = true;

this.isflag = false;

this.scroll_disable = true;

this.timer = null;

this.timer = setTimeout( () => {

this.isMore = false;

    }, 2000);

}

if (this.isflag && !this.isMore) {

this.getSKUData();

}

},

getSKUData(){

this.$axios({

method: "get",

url: "/admin/good/return_info",

params: {

id: this.$route.query.id,

pageSize:5,

page:++this.current_page

}

})

.then(res => {

res.data.data.sku.forEach((e,i) => {

this.sku_data.push(e)

let index = (this.current_page-1)*5 + i;

// this.attr_info[index] = Object.assign({}, this.attr_info[0]);

//将动态列传给

this.attr_info[index] = res.data.attr[i];

this.isflag = false;

})

})

    }

beforeRouteEnter无效

有可能是因为router没有配置页面或者配置错误

beforeRouteEnter(to, from, next) {
next((vm) => {
vm.reload();
});
},

reload之后mounted会重新调用

//子组件中

inject: ["reload"],

<button
type="button"
class="btn-primary refresh"
@click="this.reload"
round

父组件

reload() {
this.isRouterAlive = false;
this.$nextTick(function () {
this.isRouterAlive = true;
});
}

动画

#div_digg {

bottom: 0px; margin: 0px; position: fixed; right: 0.5rem;

animation: jumping 5s ease-in-out; animation-iteration-count: infinite;

}

数组删除

this.choose_dynamicPart.splice(index, 1);
this.choose_dynamicPartId.splice(index, 1)

provide和inject

父组件

provide() {
return {
reload: this.reload,
updateTag: this.updateTagsValue,
getTabs:this.getTabs,
updateTabs:this.updateTabs
};
}

reload() {
// this.search_data=[]
this.isRouterAlive = false;
this.$nextTick(function() {
this.isRouterAlive = true;
});
},
updateTagsValue(name){
this.TabsValue = name;
},
getTabs(){
return this.Tabs;
},
updateTabs(tabs){
this.Tabs = tabs;
},

子组件

inject: ["reload","updateTag","getTabs","updateTabs"],

this.updateTag('ValetOrder');

this.Tabs = this.getTabs();

数据初始化

初始化 data 中的 footData 数据
Object.assign(this.data.footData,this.data.footData, this.options.data().footData);

初始化全部的 data数据
Object.assign(this.data,this.data, this.options.data());

this.nextTick(()=> { this.select_all_goods.forEach(row => { this.refs.singleTable.toggleRowSelection(this.goods_datas.find(item => {
return row.good_itemid == item.good_itemid; // 注意这里寻找的字段要唯一
}), true);
});
this.goods_child = [];
});
})
.catch(err => {});

cookies

JavaScript操作cookies是项目中常用的功能,几乎所有浏览器都支持原生的cookies并且后端接口可以直接写入cookies,这点相对于localStore来说也算个小优势,而现在大多数情况下项目开发会选择vue框架,因为vue框架开发效率搞,也更易于后期的升级迭代和维护。那么好的工具来了,vue-cookies主要用于vue项目中操作cookie。

image

安装

npm install vue-cookies --save

引入使用

方式一(全局引入):

import  Vue  from  'Vue'

import  VueCookies  from  'vue-cookies'

Vue.use(VueCookies)

方式二(局部引入,如果是小范围使用推荐局部引入的方式):

import  VueCookies  from  'vue-cookies'

Api function 方法

一下为全局引入的使用,如果是局部引入则this对象改成引入的VueCookies

设置 cookie:

this.$cookies.set(keyName, time)

删除cookie:

this.$cookies.remove(keyName)

获取cookie:

this.$cookies.get(keyName)

获取所有cookie:

this.$cookies.keys()

监测cookie是否存在:

this.$cookies.isKey(keyName)