此篇是基于 vue2.x
的开发环境
在项目文件夹下的src文件夹下的components文件夹下创建的一个.vue文件就是一个组件,组件的script中使用this,这个this代表当前组件的实例
先通过import 组件名 from ‘组件路径’ 导入组件;在export default 中用components注册组件
示例代码:
写在App.vue文件中
依旧是先导入组件,再注册组件通过vue.component(’ 组件名 ’ , 导入组件名)
示例代码:
在main.js文件中
import Vue from 'vue'
import App from './App.vue'
Vue.config.productionTip = false
// 导入Search组件
import Search from './components/Search.vue'
// 注册组件(全局组件,可以在所有的.vue文件中使用)
Vue.component('Search', Search);
//实例化Vue对象
new Vue({
render: h => h(App),
}).$mount('#app')
使用组件(可以是全局组件 或 局部组件)
在在App.vue文件中使用:<组件名/> 或者 <组件名><组件名/>
在项目文件夹下的src文件夹下创建一个文件utils放置创建的js文件
第一种:默认导出
导出:export default 要导出的变量名
导入:import 导出的变量名 from ‘路径’
示例代码:
新建的js文件导出:
//定义函数
function add(a,b){
return a+b;
}
//默认抛出(导出)
export default add;
main.js文件导入:
import Vue from 'vue'
import App from './App.vue'
Vue.config.productionTip = false
// 默认导入 可以给默认导入的数据改名
// 默认导出和默认导入 配合使用
import abc from './utils/a'
console.log( abc(10,20) );
//实例化Vue对象
new Vue({
render: h => h(App),
}).$mount('#app')
第二种:命名导出
导出:export { 变量名1,变量名2 ,…}
导入:import {变量名1,变量名2,…} from ‘路径’
示例代码:
js文件导出:
function sub(a,b){
return a-b;
}
function mul(a,b){
return a*b;
}
//命名导出
export {
sub,
mul
};
main.js文件导入
import Vue from 'vue'
import App from './App.vue'
Vue.config.productionTip = false
// 命名导入
// 命名导入导出是对应的配合使用的,命名变量名字要相同
// {sub,mul}解构赋值,解析出你想要导入的文件
// 命名导入,必须以{}的形式导入解构时不能改名字要和导出中的名字一样
import {sub,mul} from './utils/b';
console.log(sub(10,20),mul(10,20));
console.log(abc(10,20));
//实例化Vue对象
new Vue({
render: h => h(App),
}).$mount('#app')
生命周期钩子是在Vue组件实例生命周期的某个阶段执行的已定义方法。从初始化开始到它被销毁,实例对象都会遵循不同的生命阶段。这是一个着名的图表,表示钩子函数执行顺序。
vm.$el
替换,并挂载到实例上去之后调用该钩子。如果root实例挂载了一个文档内元素,当mounted被调用时vm.$el
也在文档内。注意:
示例代码:
App.vue文件
count:{{count}}
所谓组件通信,即组件和组件之间的数据传递,包含两个方面:
Ø 具有嵌套关系的父子组件之间数据的传递问题;
Ø 兄弟组件之间数据的传递问题;
具体可以分为:
当数据存在父组件中,需要将父组件中的数据传到子组件中
父组件在子组件身上通过自定义属性传值,子组件内部通过props接收值
父组件:
<div id="app">
<div class="tabs">
<!-- App.vue与渲染的组件之间是父子关系 -->
<!-- 所有数据都存在于父组件中,需要将父组件中的数据传到子组件中进行渲染 -->
<!-- 父组件向子组件传值:父组件在子组件身上通过自定义属性传值,子组件内部通过props接收值 -->
<!-- 子组件向父组件传值:父组件提前在子组件身上绑定自定义事件,子组件内部通过$emit触发 -->
<!-- 渲染左侧分类 -->
<TabLeft :tabs="tabs" ></TabLeft>
<!-- 渲染右侧分类 -->
<TabRight ></TabRight>
</div>
</div>
export default {
data() {
return {
// 用来保存当前点击的分类下标
currentIndex: 0,
tabs: [
{
tabName: "三文鱼",
list: [
{ pic: pic1, name: "三文鱼", price: 45 },
{ pic: pic1, name: "高级三文鱼", price: 55 },
{ pic: pic1, name: "vip三文鱼", price: 65 },
]
},
{
tabName: "刺身",
list: [
{ pic: pic2, name: "刺身", price: 45 },
{ pic: pic2, name: "高级刺身", price: 55 },
{ pic: pic2, name: "vip刺身", price: 65 },
]
},
{
tabName: "大虾",
list: [
{ pic: pic3, name: "大虾", price: 45 },
{ pic: pic3, name: "高级大虾", price: 55 },
{ pic: pic3, name: "vip大虾", price: 65 },
]
},
]
};
},
components: {
TabRight,
TabLeft,
}
子组件:
export default {
// 通过props接收从父组件传来的值,该值是只读的(不能修改)
// props:['tabs','currentIndex']//数组形式
props:{//对象形式,可以对传来的数据进行类型验证
tabs:{type:Array, default:[]},
}
}
父组件提前在子组件身上绑定自定义事件,子组件内部通过$emit触发
on订阅,emit发布,on和emit是在Vue的原型上的,每个实例都可以调用。
父组件:
export default {
data() {
return {
// 用来保存当前点击的分类下标
currentIndex: 0,
tabs: [
{
tabName: "三文鱼",
list: [
{ pic: pic1, name: "三文鱼", price: 45 },
{ pic: pic1, name: "高级三文鱼", price: 55 },
{ pic: pic1, name: "vip三文鱼", price: 65 },
]
},
{
tabName: "刺身",
list: [
{ pic: pic2, name: "刺身", price: 45 },
{ pic: pic2, name: "高级刺身", price: 55 },
{ pic: pic2, name: "vip刺身", price: 65 },
]
},
{
tabName: "大虾",
list: [
{ pic: pic3, name: "大虾", price: 45 },
{ pic: pic3, name: "高级大虾", price: 55 },
{ pic: pic3, name: "vip大虾", price: 65 },
]
},
]
};
},
components: {
TabRight,
TabLeft,
},
methods:{
changelist(index){
this.currentIndex = index;
}
}
子组件:
<div class="tab" :class="{active:currentIndex ==index}" @click="$emit('deliverIndex',index)" v-for="(item,index) in tabs" :key="index">{{item.tabName}}</div>
<div class="tabright">
<!-- 渲染多个商品(列表) -->
<div class="good" v-for="(item,index) in tabs[currentIndex].list" :key="index">
<div class="imgbox">
<img :src="item.pic" alt="">
</div>
<div class="text">
<div class="name">{{item.name}}</div>
<div class="price">¥{{item.price}}</div>
</div>
</div>
</div>
**注意:**emit中传入的事件名称必须全部小写
需要借助一个公共的eventbus (通信管道) 其中一个组件提前绑定事件,另外一个兄弟组件去触发事件并传值
创建一个空实例,例如:vm = new Vue({});作为通信桥梁;
在需要接收数据的组件中用vm.$on()监听自定义事件(一般在mounted函数中处理),并在回调函数中处理传递过来的参数(注意回调函数中的this处理);
在需要传值的组件中用vm.$emit()触发自定义事件,并传递数据;
实例化Vue空实例:
var vm = new Vue({});
步骤:
1.先在src中创建一个utils文件夹在该文件夹中创建一个tools.js文件,在该文件中实例化Vue空实例,并导出
import Vue from 'vue'
// 实例化Vue 并导出
export default new Vue()
2.在需要接收数据的组件中用vm.$on()监听自定义事件(一般在mounted函数中处理)
{{item.name}}
¥{{item.price}}
import eventbus from '../utils/tools'
export default {
// 通过props接收从父组件传来的值,该值是只读的(不能修改)
data(){
return {
currentIndex:0
}
},
props:['tabs'],
mounted(){
// 绑定事件
eventbus.$on('deliverIndex',(index=>{
this.currentIndex = index; //保存接收到的值
}))
}
}
3.在需要传值的组件中用vm.$emit()触发自定义事件,并传递数据;
触发事件并不一定要传值有可能只是触发这个事件
兄弟组件a:
{{item.tabName}}
// 导入空实例
import eventbus from '../utils/tools'
export default {
// 通过props接收从父组件传来的值,该值是只读的(不能修改)
// props:['tabs','currentIndex'] //数组形式
data(){
return {
currentIndex:0
}
},
props:{//对象形式,可以对传来的数据进行类型验证
tabs:{type:Array,default:[]}
},
methods:{
handleClick(index){
eventbus.$emit('deliverIndex',index);//触发事件并传值
this.currentIndex = index;
}
}
}
外层组件通过provide传值, 内层组件通过inject接收值。
示例:
将外层组件中的值传给Child1组件再将值通过Child1组件传给Child2组件中再将值通过Child2组件传给Child3组件中
示例代码:
App.vue文件
Child1.vue文件
我是子组件1 - {{money}}
Child2.vue文件
我是子组件2 - {{money}}
Child3.vue文件
我是子组件3 - {{money}} - {{list}}
获取dom节点:
通过ref属性给标签设置标识(别名),在js代码中通过this.$refs.xx 获取标识对应的dom节点
ref应用在组件身上
在js代码中通过this.$refs.xx获取标识对应的组件实例
示例代码:
学习ref
购物车组件
已选商品
清空
{{item.name}}
¥{{item.price}}
-
{{item.count}}
+
购物车空空如也,去逛逛!
父组件
购物车
去结算
@click.left:只有点击鼠标左键时候才会触发
@click.right:只有点击右键才会触发
@click.middle:必须点击鼠标滚轮才会触发点击事件
@click.prevent:阻止默认行为,例如:a标签的跳转
@click.ctrl:点击事件想要触发必须按Ctrl键
@click.shift:当按下shift键时才会触发
@click.native:把点击事件绑到子组件上时原生点击事件
自定义事件:子组件在父组件中使用时,直接绑定在子组件上的事件就是自定义事件,必须经过子组件的触发vm.$emit()才能执行 原生事件:直接在子组件里的模板上绑定的事件,子组件引入后是可以直接触发的