Get新知识:
vue devtools 的安装及简单使用
vue devtools 调试工具,相对于浏览器自带的开发者工具对于调试和查看vue 的项目和demo 提供更强大的调试功能,在对数据绑定的检验,标签结构等方面的查看检验调试更方便。
vue 父子组件传值
父子组件之间传值,在子组件中使用props 属性接受传值,在使用时子组件时传入在props 中定义的参数名一致的数值。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>vue_demo03</title>
</head>
<body>
<div id="app3">
/* 使用时需要传入对应props中元素的名称 */
/* 这是静态的传入,即参数名传入参数的数值都是固定的 */
<menu-item title="father"></menu-item>
/*这是动态传入,使用属性绑定, 可以动态改变 */
<menu-item :title="d_title"></menu-item>
</div>
</body>
<script type="text/javascript" src="../vue_js/vue.js"></script>
<script type="text/javascript">
/* 组件间数据交互 */
/* 子组件中定义,使用props属性,传入一个数组,数组中是接受外部父组件传入数值的形参数值 */
Vue.component('menu-item', {
props: ["title", "d_title"],
data: function(){
return {
msg: "子组件内容"
}
},
/* 在props中定义好之后便可以使用,但当外部为传入参数对应数值时会显示undefined */
template: '<div>{
{msg}}-------{
{title}}</div>',
});
var temp_vue = new Vue({
el: "#app3",
data: {
fmsg: "父组件内容",
d_title: "动态内容"
}
});
</script>
</html>
vue 父子组件传值 props 属性名规则
在props 中定义接受数据的形参名,可以使用驼峰命名,短横线命名等,但在html的标签中传值的必须使用短横线的方式传值,否则会出现得不到的情况。
而在模板中则可以不区分这些命名方式,即在props 中使用驼峰命名在template 中也可以直接使用驼峰命名的形参名,不会受到影响。
vue 属性值类型
父子组件传值 使用 props 属性,props 属性支持传输 字符串 String,数值 Number,布尔值 Boolean,数组 Array,对象 Object。在使用组件传值时,需要注意,使用静态的方式传值,默认传递的任何数据都是字符串类型的,而使用
动态的方式传值时 传递的数据类型 则是会自动推断出传递数据的类型,所以一般建议使用动态的方式进行传值。
vue 子组件项父组件传值
props 传递数据原则:单项数据流。
所以根据以上的原则,不建议直接在子组件中操作父组件传递过来的数据。
可以通过子组件自定义事件向父组件传值
在子组件中的template 模板中 使用$emit 绑定一个事件形参名,在使用组件时,为事件形参名传递一个method 方法,在method方法中进行操作父组件数据的操作。原理 是 因为子组件中触发如按钮的点击事件时 会触发一个$emit 的方法执行,并且该方法需要传入一个自定义的事件,一般该自定义事件会绑定一个方法,通过该方法来获取并可以操作父组件的数据。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>vue_demo04</title>
</head>
<body>
<div id="app4">
<div :style="{
fontSize: fontsize + 'px'}">{
{pmsg}}</div>
/* 组件中为自定义事件名绑定父组件中的method,通过method 操作父组件的fontsize */
<son-assembly :parr="parr" @transmit-data="handle"></son-assembly>
</div>
</body>
<script type="text/javascript" src="../vue_js/vue.js"></script>
<script type="text/javascript">
/* 组件注册 */
Vue.component('son-assembly', {
props: ["parr"],
data: function(){
return {
count: 0
}
},
/* s使用,在子组件的template 中定义$emit 执行的自定义事件名 */
template: `<div>
<ul>
<li :key="index" v-for="(item, index) in parr">{
{item}}</li>
</ul>
<button @click='$emit("transmit-data")'>向父组件传递数据以操作父组件</button>
</div>`,
});
var temp_vue = new Vue({
el: "#app4",
data: {
fontsize: 10,
parr: ["test1", "test2", "test3", "test4"],
pmsg: "父组件内容"
},
methods: {
handle: function(){
this.fontsize += 5;
}
},
});
</script>
</html>
vue 子组件向父组件传值 并且携带参数
使用起来 总体与不传参数 基本一致,但需要注意传参的方式。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>vue_demo05</title>
</head>
<body>
<div id="app5">
<div :style="{
fontSize: fontsize + 'px'}">{
{pmsg}}</div>
/* 组件中使用,在method 中传入$event 即可将数据传入到method */
<son-assembly :parr="parr" @transmit-data="handle($event)"></son-assembly>
</div>
</body>
<script type="text/javascript" src="../vue_js/vue.js"></script>
<script type="text/javascript">
/* 组件注册 */
Vue.component('son-assembly', {
props: ["parr"],
data: function(){
return {
count: 0
}
},
/* 在子组件的template 中 在$emit() 中不仅传入自定义事件名,还传入参数 */
template: `<div>
<ul>
<li :key="index" v-for="(item, index) in parr">{
{item}}</li>
</ul>
<button @click='$emit("transmit-data", 5)'>向父组件传递数据以操作父组件</button>
<button @click='$emit("transmit-data", 10)'>向父组件传递数据以操作父组件2</button>
</div>`,
});
var temp_vue = new Vue({
el: "#app5",
data: {
fontsize: 10,
parr: ["test1", "test2", "test3", "test4"],
pmsg: "父组件内容"
},
/* 自定义事件绑定的method 中使用形参名来接受参数 */
methods: {
handle: function(event){
this.fontsize += event;
}
},
});
</script>
</html>
vue 兄弟组件之间的交互
兄弟组件之间的数据交互 通过事件中心其实是一个vue 实例对象,来进行数据交互。示例图如下:
使用:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>vue_demo06</title>
</head>
<body>
<div id="app6">
<div>父组件</div>
<div>
<button @click="handle">销毁事件</button>
</div>
<test-tom></test-tom>
<test-jerry></test-jerry>
</div>
</body>
<script type="text/javascript" src="../vue_js/vue.js"></script>
<script type="text/javascript">
/* 兄弟组件间数据交互 */
/* 生命一个vue 示例,作为事件中心,来监听兄弟组件之间的事件 */
var hub = new Vue();
Vue.component('test-tom', {
data: function(){
return {
num: 0
}
},
/* 组件的模板中,定义事件绑定函数 */
template: `
<div>
<div>TOM: {
{num}}</div>
<div>
<button @click='handle'>点击</button>
</div>
</div>
`,
/* 函数中使用事件中心,触发兄弟组件的绑定事件 */
methods: {
handle: function(){
hub.$emit('jerry-event', 1);
}
},
/* 操作兄弟组件的数据,实现数据交互 */
mounted() {
hub.$on('tom-event', (val) => {
this.num += val;
});
},
});
Vue.component('test-jerry', {
data: function(){
return {
num: 0
}
},
template: `
<div>
<div>TOM: {
{num}}</div>
<div>
<button @click='handle'>点击</button>
</div>
</div>
`,
methods: {
handle: function(){
/* 触发兄弟组件的事件 */
hub.$emit('tom-event', 2);
}
},
mounted() {
hub.$on('jerry-event', (val) => {
this.num += val;
});
},
});
var temp_vue = new Vue({
el: "#app6",
data: {
},
/* 销毁事件,将指定的事件进行销毁 */
methods: {
handle: function(){
/* 销毁事件 */
hub.$off("tom-event");
hub.$off("jerry-event");
}
},
});
</script>
</html>
vue 兄弟之间传值的流程:
vue 插槽
插槽是用于将父组件的模板内的内容传递到子组件中。
简单使用:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>vue_demo07</title>
</head>
<body>
<div id="app7">
<slot-assembly>test1</slot-assembly>
<slot-assembly>test2</slot-assembly>
</div>
</body>
<script type="text/javascript" src="../vue_js/vue.js"></script>
<script type="text/javascript">
/* 在组件的template中,使用指定的slot 标签名,用于接受父组件的模板内容传递到子组件 */
/* slot 可以指定默认值,当如果没有数值传入时,会使用默认值来填充 */
Vue.component('slot-assembly', {
template: `
<div>
<strong>Error: </strong>
<slot>default</slot>
</div>
`,
});
var temp_vue = new Vue({
el: "#app7",
data: {
}
});
</script>
</html>
具名插槽
**
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>vue_demo08</title>
</head>
<body>
/* 在使用时,传入slot="" 的name 值,将标签中的模板内容传递对应的插槽中 */
<div id="app8">
<base-layout>
<p slot="header">title1</p>
<p>title</p>
<p>title</p>
<p slot="footer">title3</p>
</base-layout>
/*如果需要将多个标签的模板内容传入时,借助指定template 标签将多条内容包围使用 */
<base-layout>
<template slot="header">
<p>title</p>
<p>title</p>
</template>
</base-layout>
</div>
</body>
<script type="text/javascript" src="../vue_js/vue.js"></script>
<script type="text/javascript">
/* 与普通的使用,区别在于,使用slot 标签时,指定name 值 */
Vue.component('base-layout', {
template: `
<div>
<header>
<slot name="header"></slot>
</header>
<main>
<slot></slot>
</main>
<footer>
<slot name="footer"></slot>
</footer>
</div>
`,
});
var temp_vue = new Vue({
el: "#app8",
data: {
}
});
</script>
</html>
作用域插槽
作用域插槽就是 父组件 决定显示的样式 即 怎样显示,子组件可以提供内容 决定显示的内容, 即 显示什么。而在之前的普通插槽和具名插槽中 都是父组件既要决定显示内容,又要决定显示样式。作用域插槽 作用就在与 可以根据子组件传递过来的数据 来分别动态决定最终显示的样式。