前端

svelte函数传参

月盾

svelte给dom对象绑定事件和vue框架类似。 定义函数:

function handler(index){
	alert("hello", index);
}

绑定事件:

<button on:click={handler}>点击</button>

但是带参函数的使用就略有不同了,函数handler的参数index需要传入的时候,不能直接这样使用<button on:click={handler(123)}>点击</button>,这样的写法会在页面打开时直接执行,而不是在点击按钮的时候执行。

这是初学svelte的时候比较郁闷的事,官方文档中也没有明显的文档说明如何传参。 正确的传参方式是这样的: <button on:click={() => handler(123)}>点击</button>on:click的内容改写为匿名函数,在函数中调用。

Svelte3路由

月盾

svelte目前没有提供官网路由组件,不过可以在社区中找到。本文介绍的是svelte-spa-router的使用方法。

npm i svelte-spa-router 参考以下目录结构创建文件(不是必须)

router.js:

import index from './index/index.svelte';
import a from './a/a.svelte';
import b from './b/b.svelte';

export const routes = {
    '/': index,
    '/a': a,
    '/b': b
}

动态导入组件和代码分割

import { wrap } from 'svelte-spa-router/wrap'
import index from './index/index.svelte';

export const routes = {
    '/': index,
    '/a': wrap({
        asyncComponent: () => import('./a/a.svelte')
    }),
    // '/b': b
	// 动态加载
    '/b': wrap({
        asyncComponent: () => import('./b/b.svelte')
    }),
}

动态导入组件的优点是组件不会一起打包,而是单独的组件文件,在打开对应的页面时才会请求,可以有效减少包文件大小。 App.svelte:

<script>
	import Router from 'svelte-spa-router'
	import { routes } from './router.js'
</script>

<Router {routes} />

a.svelte:

<script>
import { link } from "svelte-spa-router";
</script>

<a href="/a" use:link>a</a>
<a href="/b" use:link>b</a>

注意:svelte-spa-router是基于hash实现,作者认为这是静态单页应用的理想实现方式,history方式的路由需要增加服务端,这增加了复杂性。

vue nuxt组建注册

月盾

Nuxt.js 2.13+可以扫描并自动导入您的组件,不再需要在该script部分中手动导入它们!

nuxt.config配置:

export default {
  components: true
}

设置为true或使用对象时,它将包含nuxt / components依赖项,并且~/components在模板中使用它们时会自动导入您的组件。

组件目录:

components/
  ComponentFoo.vue
  ComponentBar.vue

使用

<template>
  <ComponentFoo />
  <component-bar />
</template>

注意:如果使用nuxt 2.10…2.13,则还必须手动安装并添加@nuxt/components到buildModulesinside nuxt.config。

vue子组件修改父组件的数据

月盾

vue在子组件中直接修改父组件传递下来的数据会报错: Avoid mutating a prop directly since the value will be overwritten whenever the parent component re-renders. Instead, use a data or computed property based on the prop's value. Prop being mutated: "json"

原因是vue子组件不能直接修改父组件的数据,可以使用this.$emit发送通知,让父组件来修改。 示例代码:

子组件:

this.$emit("changeData", "要修改的数据");

父组件:

<mycomponent :json="JsonData" @changeData="changeData"></mycomponent>

data(){
    return {
		JsonData:{}
	}
}
methods:{
    changeData(newData){
	    this.JsonData = newData;
	}
}

子组件发送changeData事件, 父组件绑定changeData事件并接受数据,赋值给父组件的JsonData属性,子组件的值也会改变。从而实现子组件修改父组件的属性值。

原生js实现图片预览

月盾

不依赖jquery也可以实现图片预览功能:

<!--图片放大后的div 开始  这块粘贴在你的html中最后body前 -->
<div id="outerdiv" style="text-align: center;position: fixed;z-index: 9999;top: 0;left: 0;width: 100%;height: 100%;background-color: rgba(28,28,28,0.9);">
	<img id="bigimg" style="max-height: 800px;max-width: 100%;border: 0;margin: auto;position: absolute;top: 0;bottom: 0;left: 0;right: 0;" src="" />
</div>
<!--图片放大后的div 结束 这块粘贴在你的html中最后body前-->
<!--js开始 是放大点击的触发事件 这块粘贴在你的html中最后body前-->
<script type="text/javascript">
	//图片放大
	document.querySelector("#outerdiv").style.display = "none";
	document.querySelectorAll("img").forEach(function (item) {
		item.style.cursor = "pointer";
	});

	document.querySelectorAll("img").forEach(function (item) {
		item.addEventListener("click", function () {
			imgShow("#outerdiv", "#bigimg", this);
		})
	})

	function imgShow(outerdiv, bigimg, _this) {
		var src = _this.src;//获取当前点击的pimg元素中的src属性
		document.querySelector('#outerdiv').style.display = "block";
		document.querySelector(bigimg).src = src;//设置#bigimg元素的src属性
	}
	document.querySelector("#outerdiv").addEventListener("click", function () {
	//再次点击淡出消失弹出层
		document.querySelector('#outerdiv').style.display = "none";
	});
</script>
<!--js开始 是放大点击的触发事件 这块粘贴在你的html中最后body前-->

整体代码量少,实现也简单。效果如下: 预览前

js转图片为base64上传

月盾
//上传图片
	var imagesBase64 = [];
	$("input[type=file]").on("change", function (e) {
		var image = e.target.files[0];
		var imgFile = new FileReader();
		var imgShow = new Image();
		imgFile.readAsDataURL(image);
		imgFile.onload = function () {
			var imgData = this.result; //base64数据
			imagesBase64.push({
				teaId: teacherInfo.id,
				fileType: "award",//图片
				fileName: image.name,
				file: imgData,
			});
			imgShow.src = imgData;
			imgShow.style.width = "100px";
			imgShow.style.height = "100px";
			imgShow.title = "双击删除";
			$("#imageShow").append(imgShow);
		}
	});
	$("#imageShow").on("dblclick ", "img", function () {
		var index = $("#imageShow > img").index(this);
		console.log(index);
		$(this).remove();
		imagesBase64.splice(index);
		console.log(imagesBase64)
	});

webpack构建vue项目警告

月盾
bundle.js:935 [Vue warn]: You are using the runtime-only build of Vue where the template compiler is not available. Either pre-compile the templates into render functions, or use the compiler-included build.

(found in <Root>)

解决方案:与entry属性平级添加

resolve: {
        alias: {
            'vue$': 'vue/dist/vue.esm.js'
			//该路径为node_modules下的vue目录
        }
    }
// 需要编译器
new Vue({
  template: '<div>{{ hi }}</div>'
})

// 不需要编译器
new Vue({
  render (h) {
    return h('div', this.hi)
  }
})

出现警告的原因是使用了template属性。 文文点到为止,详情请直接访问中文官方文档https://cn.vuejs.org/v2/guide/installation.html#对不同构建版本的解释

fullcalendar点击prve或者next按钮翻月触发事件调用

月盾
$('#calendar').fullCalendar({
    lang: "zh-cn",
    header: {
        left: 'prev, next, today',
        center: 'title',
        right: 'month'
    },
    height: 500,
    dayClick: function(date, jsEvent, view) {
        //点击空白日期调用
    },
    eventClick: function(calEvent, jsEvent, view) {
    //点击已有数据的日期调用
    },
    defaultDate: moment(),//默认日期
    events:function(start, end, callback){
    //点击prev上一月, next下一月等事件时调用
    }
});

vue.js做的应用中点击搜索功能会改变URI

月盾

用vue.js做的后台管理系统,有一个列表搜索功能,正常登陆进去,直接点击搜索功能,页面就会刷新一遍,原因是url地址变化了

原本地址是:
http://www.mydomain/#!/index
点击搜索以后就变成了
http://www.mydomain/?#!/index

在#!前面自动加了?,导致页面刷新一遍,这样第一次搜索就没意义了.

经过初步排查后发现点击其他按钮不会改变URL地址,对比后发现搜索按钮的type=“submit”,可能是提交表单导致跳转了,那么将type改为button或者直接去掉试试,结果还是不行,干脆也改为标签(加了bootstrap按钮样式),结果好了。为什么将button type改为button不行呢,原因是在标签内标签type会被默认当做submit,(IE浏览器默认type=button)