《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
,包含它所有的子元素。不建议使用---》【
这让父组件与子组件紧密地耦合;
只看父组件,很难理解父组件的状态
】
(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:solt(https://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;