# Vue

# 组件

属性校验?
name:{
	validator:function(value) {
		return ["alice","bob"].includes(value);
	}
}

<todo-item data-isvip='yes'>
isvip 的值会被挂载到根节点

@click.stop="handleClick"
也可以在handleClick里对element.stop

插槽是一种传递负责内容的一种方式,用在没法用属性来传递

vue路由里前进后退的那些事儿 https://juejin.im/post/6844903845999427592#comment

var orig = MyClass1.prototype.myMethod;
MyClass1.prototype.myMethod = function() {
    alert('Injected');
    return orig.apply(this, arguments);
}

var orig = Player.prototype.currentTime;
console.log(orig)
Player.prototype.currentTime = function() {
    
setTimeout(function() { 
            	console.log('=====延迟2秒');
                alert('Injected');
                orig.apply(this, arguments);
            }, 2000);
    return orig.apply(this, arguments);
}
          //   var PlayerProto = Object.getPrototypeOf(vvv.$children[3].player);
ele.playerReadied2 = function () {
            var agentdata = navigator.userAgent.toLowerCase();
            if (!/iphone|ipod|ipad|ios/.test(agentdata)) {
              setTimeout(function () {
                vplayer.currentTime(ele.ctime);
              }, 2000);
            } else {
              vplayer.play();
            }
          };

span换行输出:https://stackoverflow.com/a/41495115

<span style="white-space: pre;">{{debugText}}</span>

# 获取click方法所在的element

html:

<div @click="clickItem(item.value, i,$event)" v-for="(sub, i) in item.value" :key="i" span="12">{{ sub }}</div>

js:

clickItem(param1, param2,event) {
  let selectedElement = event.target;
}

# :style

:style="{ 'background-image': 'url(' + bgimg + ')' }"

# 数据不刷新

:key换成每次都变化的就行了

<div v-for="(item, index) in filterObj" :key="index" span="12">
      <van-row class="pp-section" type="flex" justify="start">
        <van-col @click="clickItem(item.value, row, index)" v-for="(sub, row) in item.value" :key="sub.hash" span="12">
          <div class="pp_item" :class="{ active: sub.selected }">{{ sub.name }}-{{ sub.selected }}</div>
        </van-col>
      </van-row>
    </div>

# 强制刷新一个component的最佳方法:

You have to assign a key to your component. When you want to re-render a component, you just update the key. More info here (opens new window).

https://stackoverflow.com/a/54483746/4493393

<template>
    <component-to-re-render :key="componentKey" />
</template>

export default {
  data() {
    return {
      componentKey: 0
    }
  },
  methods: {
    forceRerender() {
      this.componentKey += 1
    }
  }
}

# 引入图片的几种方式

s simple as:

<template>
    <div id="app">
        <img src="./assets/logo.png">
	      <img src="@/assets/logo.png">
    </div>
</template>
    
<script>
    export default {
    }
</script>
    
<style lang="css">
</style> 

Taken from the project generated by vue cli.

If you want to use your image as a module, do not forget to bind data to your Vuejs component:

<template>
    <div id="app">
        <img :src="image"/>
    </div>
</template>
    
<script>
    import image from "./assets/logo.png"
    
    export default {
        data: function () {
            return {
                image: image
            }
        }
    }
</script>
    
<style lang="css">
</style>

And a shorter version:

<template>
    <div id="app">
        <img :src="require('./assets/logo.png')"/>
        <img :src="require('@/assets/image.png')"/>
    </div>
</template>
    
<script>
    export default {
    }
</script>
    
<style lang="css">
</style> 

# 文本换行

将div容器的white-space属性设置为pre-wrap即可解决问题:

white-space: pre-wrap;

# @click vs @click.native

问题:为什么<YOURComponent @click="方法" />不会生效,而<YOURComponent @click.native="方法" />或者html自带标签<div @click="方法"></div> 可以生效

任何组件必须挂在到具体的DOM上,DOM本身具有事件属性,组件也有自己的事件系统,vue处理这两种事件的逻辑是不同的,所以你在component组件上定义事件,vue必须要知道是那种类型的事件好进入相应的处理逻辑,.native 就是区分的标识。

回过头来看<div @click="方法"></div> ,按照上面逻辑是必须要添加.native才能生效的,但是divhtml原生元素而非vue组件,没有自己的事件系统,所有的事件都是DOM事件,不需要区分,所以对于这种元素不需要添加.nativevue统一按照DOM本身的事件属性处理了

作者:许如云 链接:https://www.zhihu.com/question/318103114/answer/648741323

# async await

async created (){
    await this.getA()
    this.getB() 
},
methods : {
    getA : async() => {
        return $axios.post(`/getA`,params);
    },
    getB : () => {
        console.log(3)
    }
}

# Props with type Object/Array must use a factory function to return the default value

https://github.com/vuejs/vue/issues/1032

You can return the default value for a prop inside the data function as well:

data: function () {
  return {
    arr: []
  }
}

A warning seems necessary in the case you described. A solution would be:

props: {
  arr: {
    type: Array,
    default: function () { return [] }
  }
}

A little verbose, but better with ES6:

props: {
  arr: {
    type: Array,
    default: () => []
  }
}

对象

props: {
    exampleDefaultObject: {
        type: Object,
        default() {
            return {}
        }
    },
    exampleDefaultArray: {
        type: Array,
        default() {
            return []
        }
    }
},

# TODO & 疑问

为什么这样不行
components: {
    Cell,
}
必须这样子
components: {
    "van-cell":Cell,
}
难道是Cell内部export的时候没有"name"

# Vue-Router

//router.js
{
  path: "/details/:ppid",
  name: "DestinationDetails",
  component: () =>
    import(/* webpackChunkName: "DestinationDetails"*/ "./views/DestinationDetails")
}

//你的view(DestinationDetails.vue)
this.$route.params.ppid


<router-link
          :to="{ name: 'DestinationDetails', params: { ppid: destination.id } }"
        >

# URL不显示哈希符号(#)

https://router.vuejs.org/zh/guide/essentials/history-mode.html

export default new VueRouter({
  mode: 'history',
  routes: [...]
})

# 返回不reload

为了防止reload行为并缓存路由组件,可以将 < router-view > 包装在 < keep-alive > 内

<keep-alive>
    <router-view></router-view>
</keep-alive>

按需

<keep-alive>
  <router-view v-if="$route.meta.keepAlive">
    <!-- 这里是会被缓存的视图组件 -->
  </router-view>
</keep-alive>

<router-view v-if="!$route.meta.keepAlive">
  <!-- 这里是不被缓存的视图组件 -->
</router-view>

# name 和 params搭配使用

上次更新: 3/16/2022, 2:29:37 PM