组件(封装可重用的代码)

《1》简述

(1)使用

import headerFlex from "../components/headerFlex";

components: {
  headerFlex
},

<headerFlex />  或  <div is="headerFlex"></div>

(2)组件声明(main.js全局   局部    自动注册全局组件)

(3)规则

// 在组件定义中
components: {
  // 使用 camelCase 形式注册
  myComponent: { /*... */ }
}
<!-- 在模板中使用 kebab-case 形式 -->
<my-component></my-component>

《2》通讯

1:Props(父传子)

(1)规范:

<headerFlex :isOpen="isOpen" />

props: ["isOpen"], //props可写类型也可不写,写的话,当组件给其他人使用时这很有用,因为这些验证要求构成了组件的 API,确保其他人正确地使用组件

(2)动态绑定修饰符

<!-- 默认为单向绑定 -->
<child :msg="parentMsg"></child>

<!-- 双向绑定 -->
<child :msg.sync="parentMsg"></child>

<!-- 单次绑定 -->
<child :msg.once="parentMsg"></child>

2:父子组件通信

(1)使用

//子组件中的方法
this.$emit("getData", "开奖");

//父组件
<headerFlex @getData="getData" />

getData(data){
    console.log(data); //开奖
}

(2)父链

子组件用 this.$parent 访问它的父组件。

根实例的后代用 this.$root 访问它。

父组件有一个数组 this.$children,包含它所有的子元素。

不建议使用---》【

  1. 这让父组件与子组件紧密地耦合;

  2. 只看父组件,很难理解父组件的状态

(3)自定义事件

  • 使用 $on() 监听事件;

  • 使用 $emit() 在它上面触发事件;

  • 使用 $dispatch() 派发事件,事件沿着父链冒泡;

  • 使用 $broadcast() 广播事件,事件向下传导给所有的后代。

3:ref

        1、ref 加在普通的元素上,用this.ref.name 获取到的是dom元素

  2、ref 加在子组件上,用this.ref.name 获取到的是组件实例,可以使用组件的所有方法

  3、如何利用 v-for 和 ref 获取一组数组或者dom 节点

ref 需要在dom渲染完成后才会有,在使用的时候确保dom已经渲染完成。比如在生命周期 mounted(){} 钩子中调用,或者在 this.$nextTick(()=>{}) 中调用

4:solthttps://www.jianshu.com/p/b0234b773b68

插槽是为了将父组件中的子组件模板数据正常显示

匿名插槽,具名插槽

总结:
父组件传参给子组件,props接收后,插槽slot再通过绑定属性传递参数返回给父组件,不管是模板代码还是数据,控制权完全掌握在父组件手里。

//组件(父)
  <my-component>
    <template #[headerPart]>  //  v-slot:[headerPart]--》动态插槽  headerPart为变量
      <p>头部</p>  
    </template>
    <template #footer>  //缩写
      <p>脚部</p>
    </template>
  </my-component>

//组件内部(子)
    <div class="child-page">
        <slot name="header"></slot>
        <slot name="footer"></slot>
    </div>
//  组件(父)传参并接受参数
  <my-component
    v-bind="layout"  //  传递参数
  >
//  可以使用ES6解构{ slotProps }
    <template #header="slotProps">  //  接受参数
      <p>{{slotProps.headers}}</p>
    </template>
    <template #footer="slotProps">
      <p>{{slotProps.footers}}</p>
    </template>
    <template #body="slotProps">
      <p>{{slotProps.bodys}}</p>
    </template>
  </my-component>

  ...
  data() {
    return {
      layout: {
        header: '头部',
        body: '身体',
        footer: '脚部'
      }
    }
  }

//  组件内部(子)
    <div class="child-page">
        <h1>子页面</h1>
        <slot name="header" :headers="header"></slot>
        <slot name="body" :bodys="body"></slot>
        <slot name="footer" :footers="footer"></slot>        
    </div>

  ...
    props: {
        header: {
            require: true
        },
        body: {
            require: true
        },
        footer: {
            require: true
        }
    }

《3》杂记

1动态组件切换

new Vue({
  el: 'body',
  data: {
    currentView: 'home'
  },
  components: {
    home: { /* ... */ },
    posts: { /* ... */ },
    archive: { /* ... */ }
  }
})
<component :is="currentView">
  <!-- 组件在 vm.currentview 变化时改变 -->
</component>

2keep-alive缓存

如果把切换出去的组件保留在内存中,可以保留它的状态或避免重新渲染。为此可以添加一个 keep-alive 指令参数:

<component :is="currentView" keep-alive>
  <!-- 非活动组件将被缓存 -->
</component>

transition-mode

transition-mode 特性用于指定两个动态组件之间如何过渡。

在默认情况下,进入与离开平滑地过渡。这个特性可以指定另外两种模式:

  • in-out:新组件先过渡进入,等它的过渡完成之后当前组件过渡出去。

  • out-in:当前组件先过渡出去,等它的过渡完成之后新组件过渡进入

3异步组件

components: {
    'my-component': () => import('./my-async-component')
}

异步组件可以解决组件之间循环引用产生的问题

《四》组件的可复用性

1:firter过滤器(html里管道符,对文本进行过滤处理)

全局

  <template>
        <p>{{item.payTime | translateDate}}</p>
  </template>

  //为得到的时间前面加 0
Vue.filter('translateDate',(str)=>{
    let date = new Date(new Date(str).getTime()+540*24*60*60*1000);
    let y=date.getFullYear(),
        m=date.getMonth()+1,
        d=date.getDate(),
        h=date.getHours(),
        mi=date.getMinutes(),
        s=date.getSeconds();
    function toDB(str){
        return ( str.toString().length === 1 ? ( '0' + str ) : str )
    }
    return y + '-' + toDB(m) + '-' + toDB(d) + ' ' + toDB(h) + ':' + toDB(mi) + ':' + toDB(s)
})

局部

<span>{{item.inType|share}}</span>
  
filters:{
    share(type){
      let res = null;
      switch(type){
        case 1:res=_this.$t('earning.share');break;
        case 2:res=_this.$t('earning.community');break;
        default:
      }
      return res
    },

2:Vue 混入(mixin的作用是多个组件可以共享数据和方法)

1:将重复的代码统一放到Mixins中。新建文件 userMixin.js 在 src/mixins/userMixin.js

export const userMixin =  {
  	methods: {
	    get_active_or_inactive(){
	      	var status = this.status;
	      	return this.users.filter(function(users){
	            return users.status == status;
	      	});
	    },
	    filter_by_date(users){
	        return users.sort(function(a, b){
	            return a.created_at > b.created_at;
	        })
	    }
  	}
}

2:使用:直接通过调this.方法名

//全局引用
import mixin from './mixin'
Vue.mixin(mixin)

//在vue文件中引用
import '@/mixin'; // 引入mixin文件
export default {
   mixins: [mixin]
}

 

或者直接在main.js文件中

Vue.mixin({
    beforeCreate() {
        onPlusReady(() => {
            this.plusReady = true
        }, this);
    },
    methods: {
        onPlusReady: onPlusReady
    }
});


3:自定义指令

v-if, v-for, v-show 。除了核心功能默认内置的指令,Vue 也允许注册自定义指令。

新建一个存放自定义指令的 Js 文件 myDirective.js 在 src/directives/myDirective.js

// myDirective.js
import Vue from 'vue'

Vue.directive('test', {
      // 当被绑定的元素插入到 DOM 中时……
    inserted: function (el) {
        // 改变元素颜色及背景色
        el.style.color = 'white';
        el.style.background = 'blue' 
    }
})

<p v-test>test2</p>

知识点钩子函数

  • bind:只调用一次,指令第一次绑定到元素时调用。在这里可以进行一次性的初始化设置。

  • inserted:被绑定元素插入父节点时调用 (仅保证父节点存在,但不一定已被插入文档中)。

  • update:所在组件的 VNode 更新时调用,但是可能发生在其子 VNode 更新之前。指令的值可能发生了改变,也可能没有。但是你可以通过比较更新前后的值来忽略不必要的模板更新 (详细的钩子函数参数见下)。

  • componentUpdated:指令所在组件的 VNode 及其子 VNode 全部更新后调用。

  • unbind:只调用一次,指令与元素解绑时调用。

《五》其他

1:rem适配(html)【插件】【蓝湖px转,main.js中除以100】

2:vuex

const state = {
    currentLang:'cn',
};
let getters = {
    getCurrentLang(state){
        return state.currentLang;
    }
};
// this.$store.dispatch('setType',0);
const actions = {
    initMainHeight(context){
        context.commit('initMainHeight',document.documentElement.clientHeight + 'px')
    }
};
// this.$store.commit("changeLanguageShow", true);
const mutations = {
    changeLang (state,dis){
       state.currentLang = dis;
    }
};
export default {
    state,mutations,getters,actions
}

3:vue动画

<div id="demo"> 
<button v-on:click="show = !show"> Toggle</button>
 <transition name="fade"> <p v-if="show">hello</p> 
</transition> 
</div>

.fade-enter-active, .fade-leave-active {
  transition: opacity .5s;
}
.fade-enter, .fade-leave-to /* .fade-leave-active below version 2.1.8 */ {
  opacity: 0;
}

4flex-flow: row wrap;

 


 

 

 

 

 

 

 

 

 

 

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值