I belong to : Experience
本来javascript:void(0);的用处是不用整体刷新网页且返回一个空值,但这儿由于DOM本身的冒泡事件所以会最后执行HREF属性内的javascript:void(0);导致执行函数返回了一个空值,所以覆盖掉了前面正常执行函数所返回的值引起的错误。
一般情况下,IE会先运行DOM本身绑定的事件,如ONCLICK;如果没有阻止冒泡,则会顺序执行HREF属性。如果想正确运行,可以在前面用RETURN FALSE终止冒泡,例如:
<a target="_blank" class="prev" onclick="return false;" href="javascript:void(0);"></a>
或者直接删去也行,如:
<a target="_blank" class="prev" ></a>
但是后者hover的时候没有手势的pointer
解决方法参考链接
可以,运用方括号法设置就是。如
var a = "name";
var b = 10;
var obj = {};
obj[a] = b;
修改图片之后,因为src的内容一直都是后台服务链接,是个不变的值,所以不会重新去请求,图 片会一直不变。如果刷新页面这个链接返回的图片会改变,为了做到点击图片只重载这个src而整个页面不刷新,采用的方法是在后面加上 Math.random(),例如
`http:${this.baseURL}gw/app.get.logo?tenantId=${this.tenantId}&appId=${this.appId}?`+Math.random();
var arr2 = arr;
var arr3 = [...arr];
console.log(arr===arr2); //true, 说明arr和arr2指向同一个数组
console.log(arr===arr3); //false, 说明arr3和arr指向不同数组
数字类型的验证需要在 v-model 处加上 .number 的修饰符,这是 Vue 自身提供的用于将绑定值转化为 number 类型的修饰符。 v-model.number只会截取数字部分,比如100ttt只会取前面的100。做修改操作的时候这种情况用自定义validator解决
<router-link class="my-link" :to="{name: 'main.provider.index', params: {providerId: scope.row.providerId}}">提供者主页</router-link>
解决方法:给组件绑定原生事件。有时候,你可能想在某个组件的根元素上监听一个原生事件。可以使用 v-on 的修饰符 .native。例如:
<my-component v-on:click.native="doTheThing"></my-component>
参考连接 给组件绑定原生事件
line-height设置为height的值
在讨论非父子通信的时候,并在没有用Vuex的情况下,我是用官网那种创建Vue实例的方法,但是同事提到了另一种方法 用refs来引用,不禁一想这好像也是一种解决方案,就是觉得怪怪的。在这里记录一下
总结一下vue传播事件
(1) 子组件传播事件给父组件,用$on,$emit
.
虽然说是这样说,但是不是直接在父组件里面写$on的,应该是这样
<parent>
<child @eventname="event">
</parent>
然后在parent组件里面写 event函数.event(){}
子组件调用的时候用this.$emit('eventname',payload)
(2)父组件传播事件给子组件,用 $refs
<parent>
<child ref="refname">
</parant>
调用的时候用this.$ref['refname'].eventname()
(3)上面有种都麻烦的话,创建实例bus
(4) [{…}, {…}, {…}, {…}, total: 4, code: "core.ok"]
他的length是4
console.log("2">>>0) //2 number
console.log("2">>0) //2 number
console.log("2"<<0) //2 number 没有(<<<)
console.log("2"- 0) //2 number
console.log("2"+0) //20 string
今天写了一个有重大作用的reduce函数,好开心。在此纪念一下
//str {String}, "app.get.logo.list"
//ctx {Object}, this._$http
//return {Object}, this._$http.app.get.logo.list
getBackend(str){
const arr = this.loadBackend.split('.');
let ctx= this._$http;
let a;
let b=arr.reduce((prev, cur, idx) => {
a = prev[cur] ;
return a;
},ctx);
return b;
}
npm install node-sass --save-dev
npm install sass-loader --save-dev
npm install sass-resources-loader --save-dev
修改build/utils.js
scss: generateLoaders('sass').concat(
{
loader: 'sass-resources-loader',
options: {
resources: path.resolve(__dirname, '../src/assets/your.scss')
}
}
)
el-footer会直接fixed在窗口底部,不好看,
解决方法:el-footer放到el-main里面
<el-container style="height:100%;">
<el-header class="header" style="height:100px">
<cty-navbar :navs="navs"></cty-navbar>
</el-header>
<el-main>
<el-scrollbar wrap-style="overflow-x:hidden;" style="min-height: 800px">
<div>
<router-view></router-view>
</div>
</el-scrollbar>
<el-footer class="footer" style="height:70px">
<cty-footer></cty-footer>
</el-footer>
</el-main>
</el-container>
https://segmentfault.com/q/1010000010844655
写在共用组件文件里
data(){
...
}
mounted(){...},
watch: {
$route: {
handler: function (val, oldVal) {
this.worksheet_type = this.$route.params.type;
},
deep: true
}
},
在共用组件上加上key
<div :key="$route.path">
.element{
width: 20em;/*不允许出现半汉字截断*/
overflow: hidden; /*自动隐藏文字*/
text-overflow: ellipsis;/*文字隐藏后添加省略号*/
white-space: nowrap;/*强制不换行*/
.element{
width: 20em;
height: 3em;/*注意高度和宽度,不允许出现半汉字截断*/
line-height: 1.5em;
overflow: hidden;
display: -webkit-box;
-webkit-line-clamp: 3;
-webkit-box-orient: vertical;
}
<a target="_blank" :href="`http://wpa.qq.com/msgrd?v=3&uin=${qqnum}&site=qq&menu=yes`">
<img border="0" :src="`http://wpa.qq.com/pa?p=2:1424314130:51`" alt="点击这里给我发消息" title="点击这里给我发消息"/>
</a>
this.$options.filters.dateformat
本地字符串不会自己转义,所以本地需要写成 \\d
后台请求返回的字符串会自动帮你转义,所以在后台数据库只需要写成\d
>每一个被继承的组件都需要有slot;
//获取文件信息
getFileInfo(item){
let fileId= item.value;
const downloadLink =`/gw/tenant/worksheet/extend/Download?worksheetInfoId=${item.worksheetInfoId}&blobId=offer.info`;
return new Promise((resolve,reject)=>{
if(fileId == 'undefined') resolve(null);
this._$http.tenant.offerExtendGetFileInfo({fileId: fileId})
.then(res=>{
res={...res,downloadLink};
resolve(res)
})
})
},
//获取文件信息
fileGetter: async function(item) {
const fileInfo = await this.getFileInfo(item);
return Promise.resolve(fileInfo);
},
最大的用处就是可以引用一些第三方的代码插入到Vue项目中,比如有一个操作dom的函数:
//当然,真实情况第三方的代码要复杂的多
function changeColor(dom){
dom.style.backgroundColor = "red";
}
我们可以注册一个全局的指令来为需要执行changeColor方法的dom提供指令:
Vue.directives('color',{
bind:function(el){
changeColor(el)
}
})
这样,如果需要这个dom改变颜色的话,只需要这样即可:
<div v-color>改变颜色</div>
当日常开发遇到跟dom有关的问题却一筹莫展时,可以想想自定义指令是否有功能可以解决为题
直接一层一层传prop非常麻烦. Vue提供了【inheritAttrs】和【attrs】两个功能来解决这样的问题
//父组件
<template>
<div>
<child :text="text" :count="count"></child>
</div>
</template>
<script>
export default{
data(){
return {
text:"父组件的值",
count:123456,
}
}
}
</script>
//子组件
<template>
<div>{{text}}</div>
</template>
<script>
export default{
props:["text"]
}
</script>
这里父组件的count属性仅仅挂在子组件上,并没有使用。此时我们打开浏览器,可以看到子组件的dom上显示的展示了<div class='child' count="123456"></div>
。
此时,我们可以通过设置inheritAttrs: false来取消这种默认行为:
data(){
return{
......
}
}
inheritAttrs: false,
mounted(){
console.log(this.$attrs); //{count:123456}
}
这时再看dom上就没有count属性了。然后,我还打印了this.$attrs的值,值为一个包含着count键值对的Object。
也就是说,父组件没有props的属性值会被保存在一个名为$attrs中供子组件使用
,然而这并没有解决开头子组件的子组件获取值的问题。
别急,我们只需要在子组件上加个东西就可以了:
<template>
<div class="child">
<my-child v-bind="$attrs"></my-child>
</div>
</template>
这样,子组件的子组件也可以获取这个值了。
provide/inject方法要比inheritAttrs/attrs更适合用来做父组件给子组件或孙组件传值, 文档的链接
//父组件使用provide
<template>
<div class="parent">
<child-component></child-component>
</div>
</template>
<script>
export default {
......
provide: { parent: "父组件的值"},
components:{ child-component, },
......
</script>
//此时可以在子组件通过这种方式获取父组件中“parent”的值:
//子组件中
export default {
mounted(){
console.log(this.parent); //"父组件的值"
},
inject: ['parent'],
}
2018/5
htmlDocx
(将html代码导出为doc文件)http://evidenceprime.github.io/html-docx-js/build/html-docx.js
saveAs
(将浏览器内存中的doc文件保存至硬盘)http://evidenceprime.github.io/html-docx-js/test/vendor/FileSaver.js
domtoimage
(将dom节点转化成为图片)https://cdnjs.cloudflare.com/ajax/libs/dom-to-image/2.6.0/dom-to-image.min.js
domtoimage.toPng(dom); //转出来是base64 saveAs(htmlDocx.asBlob(html), filename);
主要这三个库方法 domtoimage.toPng saveAs htmlDocx.asBlob
const userId = 123
router.push({ name: 'user', params: { userId }})
// 路由设置 path 为:'/user/:userId'
// 跳转路径:'/user/123'
// 路由设置 path 为:'/user'
// 跳转路径:'/user'
// this.$route.params.userId 获取userId
在商品列表进入商品详情页之后 vue中使用keepAlive组件缓存遇到的坑
<a :href="file.worksheetFileId|url" :download="file.fileName">{{file.fileName}}</a>
html5对a标签新增的download属性用于下载文件,简单的理解是a标签如果添加了download属性,那么点击它的时候就不会跳转,而是会触发浏览器下载文件。 那么我不加download属性会下载下来的东西是什么??
答案:docx后缀的word文档用解压软件打开就是这个目录结构
Vue 实现响应式并不是数据发生变化之后 DOM 立即变化,而是按一定的策略进行 DOM 的更新。 $nextTick 是在下次 DOM 更新循环结束之后执行延迟回调,在修改数据之后使用 。
vue-router在IE 11下有bug,a href 里的路径,点击地址栏发生了变化,页面并不跳转 vm._route.path并没有发生变化,和地址栏不同步 要加上这段代码修正下:
function fixRouterIE(vm){
//IE 11下
if (
'-ms-scroll-limit' in document.documentElement.style &&
'-ms-ime-align' in document.documentElement.style
) {
window.addEventListener("hashchange", function(event) {
const currentPath = window.location.hash.slice(1);
if (vm._route.path !== currentPath) {
vm._router.push(currentPath)
}
}, false)
}
}
<el-scrollbar style="height:100%" ref="elscrollbar">
var div = this.$refs['elscrollbar'].$refs['wrap'];
this.$nextTick(() => {
div.scrollTop = div.scrollHeight
})
父元素(inline-block\block)必须含有line-height(inline元素有无皆可),子元素(inline-block/inline元素)中的vertical-align才能起作用。 vertical-align不可继承,必须对子元素单独设置。
当父元素没有设置line-height时,vertical-align只对行内元素的兄弟元素对齐有用,无法子元素居中对齐父元素。 设置了vertical-align:middle的子元素的中线与兄弟元素的基线对齐。若兄弟元素都设置该项,则居中对齐。
IE9-- Array.prototype.sort 不能根据 对象属性 做排序的遗憾
//方法1冒泡排序
var mySort = function(fn){
if(typeof fn != 'function'){
fn = function(a,b){
return a-b;
}
}
for(var i=0; i < this.length-1;i++){
for(var j=i+1;j<this.length;j++){
var t = this[i];
if(fn(this[i],this[j]) > 0){
this[i] = this[j];
this[j] = t;
}
}
}
return this;
}
if(typeof Array.prototype.sorts!= 'fucntion'){
Array.prototype.sorts = mySort;
mySort = null;
}
//方法2 插入排序
var mySort = function(fn){
if(typeof fn != 'function'){
fn = function(a,b){
return a-b;
}
}
for(var i=1;i<this.length;i++){
var t = this[i];
var j = i-1;
while(j >= 0 && fn(this[j],t)> 0 ){
this[j+1] = this[j];
j--;
}
this[j+1] = t;
}
return this;
}
if(typeof Array.prototype.sorts!= 'fucntion'){
Array.prototype.sorts = mySort;
mySort = null;
}
safari 不支持函数参数
!function(window){
var ua = window.navigator.userAgent.toLowerCase(),
reg = /msie|applewebkit.+safari/;
if(reg.test(ua)){
var _sort = Array.prototype.sort;
Array.prototype.sort = function(fn){
if(!!fn && typeof fn === 'function'){
if(this.length < 2) return this;
var i = 0, j = i + 1, l = this.length, tmp, r = false, t = 0;
for(; i < l; i++){
for(j = i + 1; j < l; j++){
t = fn.call(this, this[i], this[j]);
r = (typeof t === 'number' ? t :
!!t ? 1 : 0) > 0
? true : false;
if(r){
tmp = this[i];
this[i] = this[j];
this[j] = tmp;
}
}
}
return this;
}else{
return _sort.call(this);
}
};
}
}(window);
https://blog.csdn.net/lt3487928/article/details/53157817
https://www.cnblogs.com/Alucelx/archive/2011/07/13/2104381.html
用vue.$set不行,watch不行,试试$forceUpdate。
还有一种办法,再把值重新复制一遍也是可以的
this.obj = Object.assign({},this.obj)
https://www.jianshu.com/p/5e81814f8d8c
会先发option请求,如果server返回access-control-allow-origin头为*或者和当前域名一致的话,才会进入第二段的真正请求。
防止下次选择数据不更新
deactivated () {
this.$destroy(true)
}
arr.slice()
如果obj所有值都是非引用类型,那么obj.slice(0)与深浅拷贝没有差别;
如果obj有引用类型的元素的话,obj.slice(0)仅仅是复制了元素的地址,,obj.slice(0)可看作浅拷贝。
对象深拷贝 Object.assign({},obj)
,不要用JSON.parse(JSON.stringify(obj)),太慢
在父容器或某个祖先容器上绑定一个@click.stop='stop'
stop函数为一个空函数即可
并不是访问vue项目内某个文件, src/assets内的文件是不能在index.html直接引用的, 必须经过loader处理路径
plublic里放置的文件是不经过 webpack 处理的。在 index.html 里引用的时候,直接就是 <script src="/plublic/oidc-client.js"></script>。
$title-width: 100;
:export {
titleWidth: $title-width;
}
https://www.cnblogs.com/chaozhang/p/4711282.html
加上display:inline-block
用vertical-align:bottom解决
只要设置img为 height:auto,width:auto,就不会出现这种情况了
这样使用query,路由变化,meta并没有变化
{
name: 'order.list.1',
path: '/order/list/status=1',
component: list,
meta: {
domain: 'order',
key: 'order-list-1',
},
},
{
name: 'order.list.2',
path: '/order/list/status=2',
component: list,
meta: {
domain: 'order',
key: 'order-list-2',
},
},
使用params是可以的
{
name: 'order.list.1',
path: '/order/list/1',
component: list,
meta: {
domain: 'order',
key: 'order-list-1',
},
},
{
name: 'order.list.2',
path: '/order/list/2',
component: list,
meta: {
domain: 'order',
key: 'order-list-2',
},
},
使用函数模式也可以
const dict = {
1: 'order-list-1',
2: 'order-list-2',
default: 'order-list',
};
export default{
name: 'order',
path: '/order',
redirect: {
name: 'order.list',
},
component: Container,
children: [{
name: 'order.list',
path: '/order/list',
component: list,
meta: {
domain: 'order',
key(route) {
return dict[route.query.status || 'default'];
},
},
},
//Marquee.js
import Marquee from './Marquee.vue';
const Tpl = Vue.extend(Marquee);//这个好漂亮
const Plugin = {
install(vue, options) {
Vue.directive('marquee', {
inserted(el, binding, vnode) {
const mask = new Tpl({
el: document.createElement('div'),
data: { name: binding.value }
});
el.appendChild(mask.$el);
})
}
}
}
export default Plugin;
//main.js
import Marquee from './Marquee.js'
Vue.use(Marquee)
在 config/index.js 中修改 assetsPublicPath 为 ./ 在 build/utils.js 中的 ExtractTextPlugin.extract 传入参数 publicPath: '../../'
for-in不仅可以遍历数组还可以遍历对象 for-in 遍历属性的顺序并不确定,即输出的结果顺序与属性在对象中的顺序无关,也与属性的字母顺序无关,与其他任何顺序也无关。 使用for-in在遍历的时候,它不仅遍历了对象上的属性,而且还遍历了对象父类原型上的属性。 所以for-in并不适合遍历Array中的元素,更适合遍历对象中的属性 for-in只会遍历存在的实体,以及对应的原型链上的属性.因此其速度相比较其他for循环,要慢一些。 所以除非明确要迭代一个属性数量未知的对象,否则应该避免使用for-in。 for-in遍历数组的缺点:数组的下标index值是数字,for-in遍历的index值"0","1","2"等是字符串
在不同浏览器下测试的结果都是 forEach 的速度不如 for。 forEach主要应用在遍历数组,但是它的性能并不如for,因此可以使用for就尽量不要使用forEach。 forEach 不能break 或者return
for-of不支持普通对象遍历,只返回具有数字索引的属性.
遍历数组:for-of > for > for-each 遍历对象:for-in(要用hasOwnProperty) await/async 要用for-of for循环、while循环、do-while循环比for in 要快
比较下四中字符串拼接方法的性能:
A:str = str + 'a'+'b'
B:str += 'a' + 'b'
C: arr.join('')
D:str.concat('b','c')
☆ Chrome65上测试的是A优于B优于C优于D
1、内容长短不固定的时候用min-height,而不要用height
2、
//显示一行,多余的用省略号表示
.one-line{
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
display: inline-block;
}
//最多显示2行,多余的用省略号表示
.two-line{
overflow: hidden;
display: -webkit-box;
-webkit-box-orient: vertical;
-webkit-line-clamp: 2;
text-overflow: ellipsis;
}
3、 一般英文或者数字是默认不换行,所以要加上
css
word-break: break-all;
4、placeholder
:-moz-placeholder { /* Mozilla Firefox 4 to 18 */
color: #C6C6C6;
}
::-moz-placeholder { /* Mozilla Firefox 19+ */
color: #C6C6C6;
}
input:-ms-input-placeholder{
color: #C6C6C6;
}
input::-webkit-input-placeholder{
color: #C6C6C6;
}
在使用.vue文件开发的过程当中,我们在里面写了template模板,在经过了vue-loader的处理之后,就变成了render function,最终放到了vue-loader解析过的文件里面。这样做有什么好处呢?原因是由于在解析template变成render function的过程,是一个非常耗时的过程,vue-loader帮我们处理了这些内容之后,当我们在页面上执行vue代码的时候,效率会变得更高。
Vue为我们提供了renderError方法,这个方法只有在开发的时候它才会被调用,在正式打包上线的过程当中,它是不会被调用的。它主要是帮助我们调试render里面的一些错误。
renderError (h, err) {
return h('div', {}, err.stack)
}
有且只有当render方法里面报错了,才会执行renderError方法。 所以我们主动让render函数报个错:
render (h) {
throw new TypeError('render error')
}
还有一点,renderError只有在本组件
的render方法报错的情况下它才会被调用。
no-cache: 告诉浏览器、缓存服务器,不管本地副本是否过期,使用资源副本前,一定要到源服务器进行副本有效性校验。
must-revalidate:告诉浏览器、缓存服务器,本地副本过期前,可以使用本地副本;本地副本一旦过期,必须去源服务器进行有效性校验。
max-age: 指缓存资源的缓存时间比指定的值小,那么客户端就接受缓存资源,且缓存服务器不对资源有效性进行再次确认
是web编程的概念,是相对的而不是绝对的单位. 用户的缩放比会影响单位CSS像素点对应的实际物理像素的多少
https://github.com/amfe/article/issues/17
异步脚本禁止使用document.write() 延迟脚本禁止使用document.write()
在一个文件或模块中,export可以有多个,export default仅有一个。
(1) 导入的时候带花括号
```javascript
// 写法一
export var m = 1;
// 写法二
var m = 1;
export {m}; //export m 或者export 1都错误
// 写法三
var n = 1;
export {n as m};
```
(2) export命令规定的是对外的接口,必须与模块内部的变量建立一一对应关系。
(1) 导入的时候没有花括号
```javascript
import str from 'demo1' //导入的时候没有花括号
```
(2) export default命令的本质是将后面的值,赋给default变量,所以可以直接将一个值写在export default之后。