编写轮子的过程中遇到的问题与总结,
轮子项目地址:https://github.com/o0Chivas0o/my-wheel
—2019-04-09—
- Vue组件中Props的变量接受类型可以是指定单个或多个类型.props具体属性可查看vue官方文档:https://cn.vuejs.org/v2/guide/components-props.html 1 
 2
 3
 4
 5
 6
 7
 8
 9// props有2种写法: 
 1.
 props:{
 xxx:{
 type:[String,Number]
 }
 }
 2.
 props:['xxx']
- 组件中name属性建议规范命名,便于调试 1 //通过 this.$option.name 可以获取到当前组件的名字 
—2019-06-17—
- props中的default的值如果是对象或者数组,需要用函数return一个对象或数组 1 
 2
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19props:{ 
 object:{
 type:Object,
 default:() => {
 return {
 a:'1',
 b:'2'
 }
 }
 },
 array:{
 type:Array,
 default:() => {
 return [
 'a','b','c
 ]
 }
 }
 }
 
 ### ---2019-07-02---
- vue 默认合并 :style 和 class里的东西 - 1 
 2- <w-tabs class='lee'></w-tabs> 
 // html 中 class 为 class='tabs lee'
- .sync的用法 - 1 
 2
 3- <w-tabs :selected.sync="selectedTab"> 
 <w-tabs selected="selectedTab" @update:selected="selectedTab = $event">
 // 两种写法是等价的
- vue 的事件不会冒泡 
- css中 - margin-left:auto可将元素放置在最右
- porps 与 data的区别 - 1 
 2
 3
 4
 5
 6
 7- prop:需要用户传值 
 data:不需要用户传值
 function fn(prop1,prop2){
 var data1 = prop1
 data1 = 2
 }
- 通过 - provide和- injectAPI完成- eventBus- 1 
 2
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29- //top-level 
 import Vue from 'vue'
 export default{
 ...
 data(){
 return {
 eventBus:new Vue(),
 yyy:false
 }
 },
 provide:{
 eventBus:this.eventBus
 },
 mounted(){
 this.eventBus.$emit('update:xxx',this.yyy)
 }
 }
 //rest of level
 export default{
 ...
 inject:['eventBus'],
 created(){
 this.eventBus.$on('update:xxx',()=>{
 // 通过回调来改变值或进行其他操作
 })
 }
 }
- 组件生成过程中使用 - mounted钩子函数进行后续操作,因为- created并不能确定组件是否完全生成
 
 ### ---2019-07-03---
- this.$children的操作,只能获取到组件内的 子组件 ,并不能获取到组件内的 子元素
 
 ### ---2019-07-04---
- 编写 - popover组件的思路,- 点击button使其展示或关闭,此方法仅能通过按钮来展示或关闭,满足不了更多的需求且有bug.1 
 2
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24<template> 
 <div class="popover" @click="xxx">
 <div class='content-wrapper' v-if="visible">
 <slot name='content'></slot> // 等价展示内容
 </div>
 <slot><slot> // 等价按钮
 </div>
 </template>
 // 靠变量visible使其关闭或显示
 <script>
 ...
 data(){
 return {
 visible:false
 }
 },
 methods:{
 xxx(){
 this.visible = !this.visible
 }
 }
 ...
 </script>
- 使其点击 body元素 就能关闭popove  1 
 2
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34// 接上段代码,更改methods中的xxx函数 
 xxx(){
 this.visible = !this.visible
 if(this.visible){
 document.addEventListener('click',()=>{
 this.visible = false
 })
 }
 }
 // 然而以上代码会产生几个bug
 // 1. 监听器并没有删除,点击一次监听器在增加一个
 // 2. 监听是同时进行的,当visible变为ture的瞬间,监听器便将其值更改为false,所以页面中看不到visible
 // 3. 需要使用this.$nextTick或者setTimeout 来使其是异步操作
 // 完善以上代码
 xxx(){
 this.visible = !this.visible
 if(this.visible){
 // 这个操作是因为
 // 1. 箭头函数不具名
 // 2. 如果修改为function x(){}.bind(this) 会新生成另一个函数,与x函数不同,所以提出来这样写
 let x = () => {
 this.visible = false
 document.removeEventListener('click',x)
 }
 this.$nextTick(()=>{
 document.addEventListener('click',x)
 })
 }
 }
 // 此时点击外层的document元素也能使其关闭内容展示
- 但是用户如果需要复制popover弹出层的内容,而这段代码不能满足该需求,所以修改如下结构.  1 
 2
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32<template> 
 // vue中给@click事件添加修饰符.stop便阻止冒泡,仅添加这一项便能满足如下需求
 <div class="popover" @click.stop="xxx">
 <div class='content-wrapper' v-if="visible" @click.stop>
 <slot name='content'></slot> // 等价展示内容
 </div>
 <slot><slot> // 等价按钮
 </div>
 </template>
 
 // 靠变量visible使其关闭或显示
 <script>
 ...
 data(){
 return {
 visible:false
 }
 },
 methods:{
 xxx(){
 this.visible = !this.visible
 let x = () => {
 this.visible = false
 document.removeEventListener('click',x)
 }
 this.$nextTick(()=>{
 document.addEventListener('click',x)
 })
 }
 }
 ...
 </script>
 
 
- 点击
—2019-07-08—
- popover组件,还需要注意几点.- 点击按钮开启,点击其他位置只关闭一次.(事件监听)
- popover显示内容,不能被具有overflow:hidden属性的元素遮挡,解决办法很简单,通过$refs.popoverContent找到popover显示内容,并通过document.body.appendChild(popoverContent)插入到body中.
- 在寻找popover的位置时,如果页面出现滚动条,还会出现位置不正确的bug,需要在定位的同时,加上scroll的距离,例如:this.$refs.contentWrapper.style.left = left + window.scrollX + 'px',该情况下是x方向出现滚动条的定位.
 
### ---2019-07-09--- - 在编写某些标签上的自定义属性,如果用到拼接字符串,需用双引号包起来,如:
| 1 | <use :xlink:href="`#i-${name}`"></use> | 
—2019-07-15—
- 递归组件的几种写法.  1 
 2
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42//以cascader组件为例子 
 
 // 1. 以组件中name为标识,通过组件name递归引用自身
 <template>
 <div class="cascader-item">
 {{sourceItem.name}}
 <w-cascader-item
 v-if="sourceItem.children"
 v-for="item in sourceItem.children"
 :sourceItem="item"></w-cascader-item>
 </div>
 </template>
 
 export default {
 name: 'WCascaderItem',
 props: {
 sourceItem: {type: Object}
 }
 }
 
 // 2. 以下形式
 <template>
 <div class="cascader-item">
 {{sourceItem.name}}
 <w-cascader-item
 v-if="sourceItem.children"
 v-for="item in sourceItem.children"
 :sourceItem="item"></w-cascader-item>
 </div>
 </template>
 
 const WCascadearItem = {
 name: 'WCascaderItem',
 components:{WCascadearItem},
 props: {sourceItem: {type: Object}},
 }
 
 export default WCascadearItem
 
 
 // 上述两种形式都需要在父组件中 import 该组件, 并添加components属性使用该组件.
- scss @mixin和placeholder的区别- @mixin会将属性重复写在被选择器选中的元素内(重复写属性)
- placeholder会将选择器提取出来写在属性前(不会重复)
 
—2019-07-17—
- 编写组件需要用到数组记录的过程当中需注意:- vue是不允许直接修改数组的,需要使用this.$set(target,index,value)这样的api来动态修改数组内的值
- 或者使用this.target.push()或者this.target.splice()等数组方法来间接修改数组内的值.
- 切记勿使用this.array = value来修改值
- 参考-深入响应式原理
 
- vue是不允许直接修改数组的,需要使用
- vue编写组件,不允许 子组件 直接 修改props的值
- 组件的编写尽量单项数据流的思路去做,省去很多麻烦
—2019-07-19—
- Vue自定义指令- 组件如果需要操作dom,尽量封装到Vue指令中,v-xxx这种
- 具体编写查看vue文档,下面是cascader轮子中用到的自定义指令:
 
- 组件如果需要操作dom,尽量封装到Vue指令中,
| 1 | // click-outside.js | 
—2019-07-22—
- vue动画- transition 动画
- CSS animation 动画 (可搭配animate.css使用)
- JS 操作动画 (volocity.js 库使用 2.0.0版本以上可能存在问题)
-  条件渲染时,在渲染元素需要加上key,transition标签加mode
 
—2019-08-08—
- vue中 $children 如果是通过 slot 这种方式渲染的 不会马上拿到
—2019-08-10—
- 移动端 获取用户手指坐标(touchstart事件),通过e.touches[0]来获取第一个手指的坐标
—2019-08-12—
- vue.config.js 文件中 如若有修改路径目录的东西,需按以下写
| 1 | const path = require('path') | 
—2019-08-20—
v-if 和 v-show的区别
- v-if让元素不出现在页面,而v-show则元素一直在页面.
- v-if 为 true 时 元素 create 当 v-if 为false 时 元素 destory,而v-show 只改变style,并没有生命周期
—2019-08-22—
浏览器会合并css属性,例如:
| 1 | el.style.height = 0 | 
—2019-08-26—
表单验证有两种,及时验证,异步验证,参考
validate.js
- 及时验证- 邮箱正则 /^.+@.+$/
- 手机 /\d{10}或/\d{11}
 
- 邮箱正则 
- 异步验证- 需要用到查询数据的
 
一个关于引用类型的知识点 具体参考:https://segmentfault.com/a/1190000006769676
| 1 | let a = {} | 
—2019-09-17—
uploader 组件 涉及到简单的node.js构建的静态服务器,其中有一些需要注意的地方
—2020-07-20—
发现table组件 并不能在 column 中 添加标签 如 a 标签进行其他操作,于是修改结构,将table自身column 属性,更改为 table-column 组件 , 通过 slot 来构建table 的 column , 其中发现需要声明一个组件来完成该操作.
- 需要构建一个组件来渲染子组件中的html标签
- 外层引用 需要用到 slot-scope 的属性
| 1 | <template> | 
__END__