wumi_blog icon indicating copy to clipboard operation
wumi_blog copied to clipboard

Vue

Open 5Mi opened this issue 8 years ago • 3 comments

  1. porps 与 v-bind 模板中属性值为动态的(vue组件类中的表达式 如 data属性中的值,props,methods,computed中的值等),要用v-bind绑定该属性 porps,组件标签上的属性, 此外 ~~模板里的标签中用到props的属性要用动态绑定使用:属性名~~好像标签中属性值是动态的属性名前都要有_:_来动态绑定

    伪代码为

    <child  :name='somethingfromfather'></child>
    
    //模板中
    <input  :value='name' type="text" />
    ...
    //类中属性
    default export{
        props:['name']
    }
    
  2. events $emit (es6相关= =)

    用实例或this调用.$emit等方法 只能触发组件自身的自定义事件 即组件实例.$on绑定的或events属性中声明的自定义事件Object.assign方法的第一个参数是目标对象,后面的参数都是源对象。 注意,如果目标对象与源对象有同名属性,或多个源对象有同名属性,则后面的属性会覆盖前面的属性。Object.assign方法实行的是浅拷贝,而不是深拷贝。也就是说,如果源对象某个属性的值是对象,那么目标对象拷贝得到的是这个对象的引用。一旦遇到同名属性,Object.assign的处理方法是替换,而不是添加。

  3. Object.assgin

    Object.assign方法用于对象的合并,将源对象(source)的所有可枚举属性,复制到目标对象(target)。

  4. slot

    一般来说,组件标签中内容将被抛弃(不渲染),除非其模板中有slot标签,如果组件标签中没内容,则会显示其模板中slot标签的内容

    假定 my-component 组件有下面模板:

<div>
  <h1>This is my component!</h1>
  <slot>
    如果没有分发内容则显示我。
  </slot>
</div>

父组件模板:

<my-component>
  <p>This is some original content</p>
  <p>This is some more original content</p>
</my-component>

渲染结果:

<div>
  <h1>This is my component!</h1>
  <p>This is some original content</p>
  <p>This is some more original content</p>
</div>

具名slot slot 可以有name属性 组件标签里的内容元素可以有slot属性,其值对应slot标签的name属性来插入同名的slot插槽中,没slot属性的插到没name属性的slot标签中,找不到的就抛弃

[参考doc](http://vuejs.org.cn/guide/components.html#单个-Slot)

5Mi avatar May 26 '16 11:05 5Mi

vue 保证钩子中的异步流程(执行完mounted中的代码再去执行activated中的代码)

data () {
    return {
      mountedPromise: new Promise((resolve) => { this.mountedPromise_resolve = resolve }),
  }
},
async mounted () {
    //
    await this.fetchSomething()
    this.mountedPromise_resolve()
  },
 async activated () {
    // await mounted fetch
    await this.mountedPromise
    //  保证 先mounted 后 activated
  }

5Mi avatar Nov 16 '18 10:11 5Mi

router 全局路由守卫中 调用 root 实例

项目中曾有以下情况, router 全局守卫中调用vue根实例, 偶尔build之后 服务端页面运行 会报错: app undefined, 考虑可能为 index.jsrouter.js相互引用导致 循环加载

// in index.js
import Vue from 'vue'
import App from './App.vue'
import store from './store'
import router from './router'

export default new Vue({
  store,
  router,
  render: h => h(App)
})
// in ./router/index.js
import Vue from 'vue'
import Router from 'vue-router'
import vueStore from '../store'
import routes from './routes'
// 引用了vue 实例
import app from '../index'
Vue.use(Router)

const router = new Router({
  mode: 'history',
  routes
})
router.afterEach(async (to, from) => {
  // 此处引用实例 在build后的页面中有时会 报错: app undefined
  app.$toast('fdas')
})
解决: 不在router中引用 ./index.js 中的实例`
  • 使用router.app

  • 通过to.matched[0].components.default抓取组件实例, 在调用实例prototype上的方法

to.matched[0].components.default

  • 或者避免实例参与, 通过store来迂回实现需求

参考 使用 router.app第一次加载也可能有问题?

5Mi avatar Mar 20 '20 09:03 5Mi

// https://slides.com/akryum/vueconfus-2019
// vue3 hooks defer 延时x帧渲染
import { ref, onMounted } from "vue";
export default function(fpsMaxCount = 60) {
  const displayPriority = ref(0);

  const runDisplayPriority = () => {
    const step = () => {
      requestAnimationFrame(() => {
        displayPriority.value++;
        if (displayPriority.value < fpsMaxCount) {
          step();
        }
      });
    };
    step();
  };

  const defer = (priority) => {
    return displayPriority.value >= priority;
  };

  onMounted(() => {
    runDisplayPriority();
  });

  return {
    displayPriority,
    defer
  };
}

// 使用场景 延时30帧
<template v-if="defer(3)">
      <div>
        defer render
      </div>
    </template>
   <Heavy v-if="defer(30)" />

---
import useDefer from '@/hooks/defer'
export default {
  setup(props, context) {
   const { defer } = useDefer()
   return {
      defer
   }

}

5Mi avatar Apr 02 '21 07:04 5Mi