vue2 项目
========= vue cmd命令所包含知识点:
当npm install无效,需要进行npm cache clean --force命令操作,
如果这样操作不成功的话,去C盘清空一个文件夹:
C/用户/administrator/appdata/Roaming/npm-cache 直接将路径下该文件夹右键删除
再重新npm install
#删除node_modules
npm cache clean --force 强制清楚缓存
npm install rimraf -g
rimraf node_modules
重装:npm install
#canvas库---ocanvas
npm install ocanvas --save
import oCanvas from 'ocanvas'
var oCanvas = require('ocanvas')
安装vue-router: npm install vue-router --save
添加--save是因为项目运行时也需要依赖路由
document.title="首页" document.title可以改变当前页的网址上的文字描述
学会使用StackOverflow和GitHub提问
在vue3项目中使用scss:
npm install node-sass --save-dev
全局安装vue3脚手架:
npm i -g @vue/cli
vue3 通过vite初始化项目: 学习vue3.0,先从搭建环境开始
yarn/npm create vite-app vue3project
一步直接创建项目。
vue add vue-next 让vue支持3.0
=模块化开发====
避免多人开发时变量重名等问题
早期的模块化开发的实现,是通过匿名函数,使得多人开发时变量重名不会影响整体项目。同时将需要全局使用的变量或者函数通过return方式暴露出去–导出。这样就可以在其他位置直接使用–导入。
===webpack的作用/安装和使用/配置
1.1webpack安装和使用
vue脚手架 vue cli=====
帮助完成项目的代码目录结构,项目结构和部署,热加载,代码单元测试等功能。
vue cli俗称vue项目脚手架,可以快速搭建vue开发环境以及对应的webpack配置。所以使用vue cli需要先安装node(因为webpack的使用需要先安装node,然后才能使用npm—npm为node自带的)
安装node:
直接在官网下载安装:http://nodejs.cn/download/
检测安装的node版本:
node环境要求版本 >= 8.9
什么是NPM?node package manager
npm是一个nodejs包管理和分发工具,已经成为非官方的发布node模块的标准
国内直接使用npm的官方镜像非常慢,所以推荐使用淘宝npm镜像。
npm install -g cnpm --registry=https://registry.npm.taobao.org
一般org网址都是非营利性的。com结尾的网址是营利性的
安装vue cli3版本,既可以使用3版本,也可以使用2版本。所以直接安装3版本cli就好了。
npm install -g @vue/cli 安装vue cli3
cli3版本下创建vue项目:
vue create projectname
如果按照3版本后想要使用2.x旧版本。可以通过命令直接拉取旧版本
npm install -g @vue/cli-init
cli2版本下创建vue项目:
vue init webpack projectname
runtime compiler / runtion only的区别========
运行+编译器:可以直接使用template模板.
仅运行时.无法解析template模板,需要通过render函数提前编译
============vue所包含知识点:
input有个特有的动态监听事件,用来监听表单数据value的变化。v-on:input/@input
当input表单内数据value发生变化时会触发:input监听事件
button也有特有的监听事件
cli(event) {
//@click="cli" 当调用方法不传参不加括号时,会自动调用浏览器产生的event对象
console.log(event);
},
cli0(val,event) {
//@click="cli0(123,$event)" 当需要调用浏览器的event对象又需要传参时。event+$符号
console.log(val);
con``sole.log(event);
},
v-model实现数据双向绑定的原理: v-model实际上使得vue做了两步操作:
1.v-bind model—>view
2,input的特有监听事件@input view—>model
<input type="text" v-model="message">
<input type="text" v-bind:value='message' @input="message = $event.target.value">
为什么vue在设计的时候data是一个函数,而不是直接一个对象?
因为对象return的是同一片内存空间。这样会导致组件在复用时,所有复用组件使用同一片内存地址。导致数据紊乱。
data必须是一个函数。每调用一个组件实例,就会调用一个data函数。而函数return的是一片新的内存地址。这样使得所有复用的组件之间互不影响。
组件化开发:========
++ 4.1 父组件向子组件中传值:
props:['变量1','变量2','变量3'];//最基础的写法,数组类型,不推荐
props:{//对象类型,推荐。可以对传过来的值进行类型审核和简单验证,同时也方便阅读和简单维护
propA:Number,//基础的类型检查
propB:[String,Number],//多个可能的类型
propC:{//必填的字符串
type: String,
required:true
},
propD:{//带默认值的数字类型
type:Number,
default:100
},
propE:{//带默认值的对象
type:Object,
default:function() {//Object or Array的默认值是一个函数
return { msg:'hi' }
}
},
propF:{//自定义验证函数
validator:function(value) {
//这个值必须匹配下列字符串中的一个
return ['','',''].indexOf(value) !== -1;//返回值true or false
//arr.indexOf(item) 判断数组arr中是否包含元素item。如果不包含则返回-1
}
}
}
++ 4.2 子组件向父组件传值:
在子组件中使用this.$emit(‘func’,value)
在父组件调用子组件时:
<son @func="sonhappen"/>
methods:{
sonhappen(value) {
//注意,父组件中此处接收的值都是string类型。
console.log(value)
}
}
++父组件直接访问子组件:
this. c h i l d r e n : 数 组 类 型 一 般 不 使 用 children: 数组类型 一般不使用 children:数组类型一般不使用children来拿子组件数据。而是使用 r e f s 可 以 访 问 父 组 件 的 所 有 子 组 件 对 象 , 包 括 子 组 件 的 子 组 件 ; 可 以 访 问 子 组 件 的 所 有 数 据 。 t h i s . refs 可以访问父组件的所有子组件对象,包括子组件的子组件;可以访问子组件的所有数据。 this. refs可以访问父组件的所有子组件对象,包括子组件的子组件;可以访问子组件的所有数据。this.refs: 对象类型 好像行不通啊??
this.$refs.name可以访问到son子组件的所有数据。name会作为子组件对象的key值。
++子组件访问父组件:
this. p a r e n t : 可 以 在 子 组 件 中 访 问 到 父 组 件 对 象 。 一 般 开 发 中 不 使 用 。 会 影 响 组 件 的 独 立 性 。 t h i s . parent:可以在子组件中访问到父组件对象。一般开发中不使用。会影响组件的独立性。 this. parent:可以在子组件中访问到父组件对象。一般开发中不使用。会影响组件的独立性。this.root:可以在子组件中访问根组件即vue实例对象
v-bind不支持驼峰写法
v-bind:cInfo=“info” 这样写会出现值传递失败的情况 需要改成v-bind:c-info=“info”
计算属性存在缓存。在多次调用时,由于存在缓存,只会执行一次。
与methods的区别:methods调用几次执行几次
插槽的作用:为了让组件具有可扩展性。
9.1基本插槽的使用:
在自定义的组件中使用。可以在插槽内填入默认内容。
在引用组件时,可以在组件内直接填入内容。就可以替换子组件内插槽的默认内容。
9.2具名插槽的使用:
一个子组件内可能存在多个插槽,当引用子组件时,可能只希望替换其中某一个插槽的内容。这时候就可以使用具名插槽。即给每个slot一个特有的name属性值。
在子组件中:
在父组件中引用子组件时:
我要把son组件内的center插槽内容替换掉
9.3作用域插槽:
—有个需求:子组件中包含一个数组数据。需要在不同的位置进行展示。有的地方水平展示,有点地方纵列展示,有的位置直接显示一个数组。希望父组件告知子组件具体如何展示。
—以上需求就可以使用作用域插槽。展示数据由子组件提供。但展示方式由父组件决定。
—所以需要先在父组件中拿到子组件的数据:
1,在子组件中将子组件的数据绑定到abc: [abc可以随意更改成你喜欢的名字]
在son组件中:
this. r o u t e r 指 的 时 n e w V u e 的 实 例 对 象 t h i s . router 指的时newVue的实例对象 this. router指的时newVue的实例对象this.router.push/this. r o u t e r . r e p l a c e t h i s . router.replace this. router.replacethis.route 指的是当前活跃状态下的路由对象
{ path:’/user/:abc’,component:user } this.$route.params.abc
所以通过Vue.prototype.自定义的方法和变量,整个vue项目中的所有组件都可以使用变量或方法
https://blog.csdn.net/qq_36545813/article/details/109510815
可以使被包含的组件保留状态,或避免重新渲染;
被包裹在keep-alive里面的组件,所有路径匹配到的视图组件都会被缓存。
keep-alive有两个非常重要的属性,开发者可以自由定义哪些组件需要被缓存,哪些组件需要被重复创建和销毁【一般存在每次进入路由都需要重新更新的情况】
–inclue属性:只有相匹配的组件才会被缓存–字符串或正则
–exclue属性:任何相匹配的组件都不会被缓存–字符串或正则
比如app.vue下有a b c 3个组件,且全部都被keep-alive包裹,但我需要每次切换到组件C时都重新创建。
可以这样操作: c是组件的name值。如果需要排除多个组件,使用逗号分隔就好,需要注意的是不能多添加空格,否则会出错
npm i vuex -S
npm i es6-promise -S
在码云新建仓库并第一次将本地代码提交
在控制台:
git comfig --global user.name ‘677’
git config --global user.email ‘[email protected]’
创建本地git仓库:
mkdir storename
cd storename
git init
touch READEME.md //注意:如果报错touch:无法将’touch’项识别为cmdlet… 安装touch :npm install touch-cli -g 安装后再执行touch READEME.md
git add READEME.md
git commit -m ‘first commit’
git remote add origin https://gitee.com/…
git push -u origin master
npm install echarts --save
在引用echarts的组件内import echarts from ‘echarts’
绘制一个图表:
1,准备一个具备宽高的容器:
#Vuex中执行完mutations,更新了state后,视图不更新 vuex中state数据是异步渲染的。初始渲染的是state中的默认数据。在渲染时去获取三层表达式中的属性值,此时对象还不存在,获取不到值。这样就会造成,在界面上可以正常打印出值,但是
https://blog.csdn.net/edc3001/article/details/86833558
参考:
@dragstart="Dragstart($event,item)"
draggable="true"
* methods:{
Dragstart (event, item) {//@dragstart是html自带的mouseevent事件
console.log('===================dragstart');
console.log(event);//
console.log(item);
var infoJson = JSON.stringify(item.info);
event.dataTransfer.setData('my-info', infoJson);
}
}
dragstart、drag、dragenter、dragover、dragleave、drop、dragend属性
事件顺序:
dragstart -> drag -> dragenter -> dragover -> dragleave -> drop -> dragend
拖放事件
(默认图像,链接,文本是可以拖动的)
(别的元素要拖动首先设置draggable=“true”:对于draggable的支持ie10+,ie9-只能使用默认拖动)
被拖放对象:dragstart:开始拖放的时候触发
被拖放对象:drag:在拖放过程中持续触发
经过对象:dragenter:拖放过程中鼠标经过的元素,被拖放的元素‘正开始’进入其他元素范围内 e.preventDefault()
经过对象:dragover:拖放过程中鼠标经过的元素,被拖放的元素正在本元素范围内移动(一直) e.preventDefault()
经过对象:dragleave:拖放过程中鼠标经过的元素,被拖放的元素离开本元素范围
目标地点:drop:拖放元素被放置到目标点的时候触发
被拖放对象:dragend:拖放操作结束时触发
a.在拖放数据的时候使用dataTransfer来存储和获取数据
b.存储数据:ev.dataTransfer.setData("类型","值") 类型通用有两种:"text/plain"和"text/url-list"(ie中使用"text"和"url")
c.获取数据:ev.dataTransfer.getData("类型")类型同上
(获取数据是在目标对象的drop事件上获取在别的事件上都取不到)
(注意设置document的dragover和dragend为return false否则获取不到数据)
(目标有几层元素就会触发几次)
对于拖动元素而言在dragstart时设置effectAllowed不为none光标显示为指针而不是禁止标志
这两个属性的主要作用:用于设置拖拽过程中鼠标指针的类型。
4.dataTransfer属性:
a. clearData(format):清除特定格式的数据
b. setDragImg(elem,x,y):设置拖动的时候光标下面显示的图像,(x,y为光标在图像上的位置)
(这个方法还是很好用的,但是不支持ie)
dragenter 和 dragover需要阻止浏览器的默认事件。
*/
http://www.itxst.com/vue-draggable/tutorial.html
#批量注册全局方法
https://www.cnblogs.com/yanl55555/p/12543993.html
document.onkeydown = (e) => {
let key = window.event.keyCode;
if(key == 46|| key == 8) {// delete||backspace
alert('删除canvas')
let id = this.selectedid;
console.log(id);
const targetcanvas = document.getElementById(id);
targetcanvas.remove();//删除元素
}
}
str_before = string.split(str)[0]
str_after = string.split(str)[1]
string.charAt(string.length-1)
x = y = (boxstyle.circleR / 2).toFixed(2);//除以2保留2位小数
https://www.jb51.net/article/55128.htm
const el = document.getElementById(‘main’);//拿到mian盒子的左上角坐标。
this.x = e.clientX - el.offsetLeft;
this.y = e.clientY - el.offsetTop;//这就是生成的canvas盒于main盒子的坐标啦!
1,当侧边栏数据发生变化并提交表单时,传递表单数据。
2,在center页面监听数据的变化。并给监听属性添加deep:true。保证数据对象内的任意属性值发生变化都会触发事件监听。监听事件触发的条件有两点:对象被选中【可以在点击选中对象时获取对象id。监听时判断是否有id】;侧边栏数据更新后发生了提交【在提交事件中记录标记sub:true】。
3,
item:{
handler:function(newval) {
console.log(newval);
},
deep:true//修改item对象内的任何一个属性,都会触发item的监听。
}
1,获取鼠标坐标。page/client
2,获取事件源的左上角坐标。//offsetLeft
3,相减就是鼠标距离事件源左上角的坐标。
document.getElementById(’’).clientWidth/clientHeight
[0,{},1:{}] => [{},{}] ?
Object.assign({},data)
Object.values() 获取对象键值对中的value组成数组 Object.keys()
arr.push()
let i in arr
hadNumber(str) {//判断字符串中是否包含数字
for(let i in str) {
let asc = str.charCodeAt(i);
if(asc >= 48 && asc <= 57) {//表示包含数字
return true;
}
}
return false;//不包含数字
},
delNumber(str) {//删除字符串中数字返回新字符串
for(let i in str) {
let asc = str.charCodeAt(i);
if(asc >= 48 && asc <= 57) {//表示包含数字
let needdel = str.charAt(i);//获取索引处的字符
console.log(needdel);
str = str.replace(needdel,'');
}
}
console.log(str);
return str;
},
const newdata = arr.map((element,index) => { //map遍历数组对每个元素进行处理,返回新元素组成的数组。
// console.log(element);
element.canvasid += ''+index;
return element;
});
https://www.cnblogs.com/mica/p/11276447.html
document.getElementById(id).contains(e.target)
https://blog.csdn.net/u012746918/article/details/106359881/
https://juejin.cn/post/6908502083075325959
项目搭建和功能完成都差不多了我才看到这个文档。非常有用,可作为文档参考加深印象或者优化项目。
Object.keys(lbj).length==0 为空
动画库 Animate.css https://animate.style/ ?
-1,插件: 本项目中使用animate.css插件
-2,vue自带的动画效果: transition
-3,css实现动画效果:
1,用一个文件来打包动画需要用到的动画效果数据。
本项目中使用的是animate.css。可去官网查看动画演示效果,以及获取相关动画属性。
2,先将所有动画在遮罩层【本项目中使用的标签是抽屉】中渲染出来。先实现悬浮时触发动画。
只需要使用悬浮事件,改变类名。给任意元素添加移除animatename即可添加或移除动画效果
@mouseover=“hoverAnimate = animatename”
:class="[hoverAnimate === animatename?‘animate__’+animatename:’’]"
3,第三步,点击某个动画效果时,将该动画效果绑定到相应组件。即改变相应组件的class。
4,动画效果预览。点击相应动画的预览效果时,将相应动画与相关组件绑定。
1,用一个文件来存储事件需要的数据
2,使用遮罩层来进一步控制交互效果。让用户输入事件的参数信息。当用户点击确定按钮时
3,通过用户的点击事件触发。给相应组件绑定相关的事件监听。
4,事件预览:在对象选中的情况下,选择单个事件时,对相关对象进行事件监听和事件解绑。
1:
@keyframs name {
0% {}
50% {}
100 % {}
}
.fade-enter-active {
transform-origin: left center;
animation: name 1s;
}
.fade-leave-active {
transform-origin: left center;
animation: name 1s reverse;
}
2:使用Animate.css库和transition结合:
npm install animate.css --save
import animated from ‘animate.css’
Vue.use(animated)
appear:表示第一次显示时有动画效果。
appear-active-class:用于在组件第一次显示时展示动画效果
enter-active-class:入场动画 必须有animated
leave-active-class:出场动画 必须有animated
duration:自定义动画执行的总时长
还可以分别定义入场和出场动画的时长:duration="{enter:5000,leave:1000}"
:duration=“5000”
enter-active-class=“animated 自定义添加入场动画”
leave-active-class=“animated 自定义添加出场动画”
apear
appear-active-class=“animated 自定义添加入场动画”
@berfore-enter=“handleBeforeEnter”
@enter=“handleEnter”
@before-leave=""
@leave=""
@after-leave=""
methods:{
handleBeforeEnter: el => {
el.style.color = ‘red’;
},
handleEnter: (el,done) => {//el指动画transition包裹的标签
setTimeout(()=>{
el.style.color = ‘green’;
done();//手动结束动画 不可省略 done()被调用后,会执行afterEnter()
},2000)
},
handleAfterEnter: el => {//结束时动画
el.style.color = ‘black’;
}
}
文档:http://shouce.jb51.net/velocity/index.html
下载:npm install velocity-animate
1,使用git工具: 弃用
https://blog.csdn.net/guoweifeng0012/article/details/87922312
.stop 阻止事件冒泡。
.self 让事件只在本身元素上触发
使用场景:阻止子元素的点击事件冒泡到父元素。当点击子元素时 ,子元素在父元素内,也相当于点击了父元素。而self确保事件只在子元素上触发
DOM.addEventListener(‘click’,eventHandler.call(this,evt),false);//addEventListener(‘click’,fn,false)
//eventHandler.call(this,evt) 改变eventHandler函数内的this指向,并传入参数evt
function eventHandler(evt) {
console.log(this);
console.log(evt);
}
Math.min(start.x,end,x)
Math.max(start.x,end,x)
str.split(’-’)[1] 表示截取str字符串-后的子串
比如button-11 str.split(’-’)[1]表示’11’ str.split(’-’)[0]表示’button’
vvv
,来拼接字符串和对象,还可以引入表达式,也支持换行this. m e s s a g e . e r r o r ( “ 该 对 象 已 绑 定 ” + e v t . l a b e l + “ , 请 勿 重 复 绑 定 ” ) ; t h i s . message.error(“该对象已绑定”+evt.label+“,请勿重复绑定”); this. message.error(“该对象已绑定”+evt.label+“,请勿重复绑定”);this.message.error(该对象已绑定“${evt.label}”,请勿重复绑定
);
event.stopPropagation() 阻止事件冒泡
Math.abs(-1); //1
Math.abs(-2); //2
该方法是在页面已经存在图表的情况下。
let opt=myChart.getOption();
myChart.clear();
myChart.resize({height:“500px”,width:“500px”});
myChart.setOption(opt);
https://blog.csdn.net/qq_26477073/article/details/84568668
let myEchart;//全局变量
if (myEchart != null && myEchart != “” && myEchart != undefined) {
myEchart.dispose();//销毁
}
https://blog.csdn.net/weixin_42333548/article/details/103626427
https://blog.csdn.net/SpringRolls/article/details/108105014
https://blog.csdn.net/u012732909/article/details/108124313
参考链接:https://blog.csdn.net/txp1993/article/details/70046443/
最推荐这个链接了:看一遍更加深入理解:https://www.cnblogs.com/liuxianan/p/js-download.html
1,//js文件
export default{
install (Vue) {
//将getPdf定义为全局方法
Vue.prototype.getPdf = () => {
}
}
}
2,在main.js文件中引入:
import htmlToPdf from ‘@/utils/htmlToPdf’
Vue.use(htmlToPdf)
3,在其他任何位置直接通过函数名调用全局方法
@contextmenu=“rightclick”
rightclick() {
// console.log(‘单击了鼠标右键’);
},
translate平移,rote绕几何中心旋转。旋转后,坐标轴会发生变化。此时translate平移所参考的坐标轴就是新坐标轴了。
如何解决组合使用问题呢?
:style="{
‘transform’:‘translate(’+item.info.form.box.left+‘px,’+item.info.form.box.top+‘px) rotate(’+item.info.form.box.rotate+‘deg)’
}"
let tag = window.event.target || window.event.srcElement;
tag.tagName.toLowerCase()==‘body’
document.getElementById(‘dragendarea’).contains(tag) 返回true / false //判断鼠标是否点击在#dragendarea区域内
https://www.cnblogs.com/hjson/p/10254555.html
https://cn.vuejs.org/v2/guide/render-function.html
const h = this. c r e a t e E l e m e n t ; / / v u e 的 c r e a t e E l e m e n t 函 数 c o n s t h = t h i s . createElement;//vue的createElement函数 const h = this. createElement;//vue的createElement函数consth=this.createElement;
const content = h(‘div’,{},[
h(‘a-input’,{
attrs:{
placeholder,
value:’’,
id:‘input_url’
}
// nativeOn:{//用于监听原生事件
// pressEnter: onOk()//希望回车能执行onOk
// }
})
]);
this.$confirm({
title: ‘请输入跳转路径’,
content:content,
okText: ‘确认’,
cancelText: ‘取消’,
onOk() {},
onCancel() {}
});
怎么获取到自己创建的input内的数据呢?
document.getElementById(’?’).value
如果content是input标签,怎么实现input回车时关闭modal呢。即使用回车事件代替onOk()事件。
document.getElementById(item.newid).style = ‘pointer-events:none’;//设置事件穿透;
setTimeout( ()=> {//半秒钟之后,恢复不穿透状态
// document.getElementById(item.newid).style = ‘pointer-events:auto’;
// },500)
1,拖拽效果,鼠标按下,出现一个半透明对象,跟随鼠标拖动。draggable功能自带。
2,移动和resize效果。插件vuedraggableresizable。
3,键盘del键删除选中的单个对象。 DOM事件。和数据处理 arr.splice(index,1)
4,选中对象,ctrl+c,ctrl+v 。复制粘贴选中对象。并指定粘贴位置。 dom事件。arr.push()
5,移动对象。改变坐标。
6,改变选中对象样式。选中时获取对象样式,侧边栏数据也随着对象的切换而变化。侧边栏修改单个样式直接修改对象的样式显示效果。
7,撤回上一步操作。撤回cv。撤回删除。撤回新增。撤回移动。撤回resize。—?还没有撤回样式修改的功能【比如改变了颜色和border等,撤回】。
1,选取范围内的对象,并获取到选取的所有对象信息,根据鼠标坐标,分别改变每个选取对象的坐标,实现整体移动的效果。并在选取区域形成一个border。⭐
2,单击选取范围内的单个对象,可对单个对象进行操作和样式修改。此时再拖拉整个选取区域,范围内对象不再整体移动,而是只移动border ⭐
3,选取范围内对象后,可以将对象整合成一个组件。?不明白具体实现的是什么。动态生成组件吗?
4,撤回样式修改。
5,生成html。
6,预览。
7,保存。
8,编辑。
9,绑定事件。
10,绑定动画。
11,触发mac的键盘监听控制事件。⭐
12,alert弹窗改为ant-vue弹窗。 ⭐
=====================================
* [实现响应式数据:通过ES6的proxy实现。将传入的数据包装成一个【Proxy对象】。【vue2中通过defineProperty实现】
* 监听复杂类型的变化【比如对象/数组】:import {reactive} from 'vue'> 监到数据发生变化,会即时响应到页面
* let data = reactive({
stus:[]
})
* 如果给reactive传递了其他对象:
- 默认情况下修改对象,界面不会响应更新
- 如果想更新,可以通过重新赋值的方式
setup() {
let state = reactive({
time: new Date()
});
function myfun () => {
const newtime = new Date(state.time.getTime());//创建一个新data对 象,和state.time值一样。
newtime.setDate(state.time.getDate() + 1);//给newtime的天数重设置 为time的天数+1
state.time = newtime;//对state.time重新赋值。这样,页面中显示的state.time就能实时响应了。
}
return {state,myfun};
}
ts是js的超级,包含了es6和es5的规范,适用于大型项目。浏览器无法识别。使用ts后,需要转es5,会自动转的。
newnew: