vue的生命周期
在创建一个vue对象的时候回有许许多多的步骤,这时,在每个步骤执行完后需要有回调函数来确定这一步执行完毕后需要做什么事情,比如网络请求。生命周期函数就应运而生。
vue生命周期如下:
- beforeCreate
- created
- beforeMount
- mounted
- beforeUpdate
- updated
- beforeDestroy
- destroyed
vue生命周期详解
beforeCreate
实例组件刚创建,元素DOM和数据都还没有初始化,暂时不知道能在这个周期里面进行生命操作。
created
数据data已经初始化完成,方法也已经可以调用,但是DOM未渲染。有人问了,请求都是异步的,并不会阻碍实例加载。这是我个人水平的问题,这边改正,在这个周期里面,请求因为是异步的,不会阻碍实例加载,除非是那些同步操走才会导致页面空白。这样说来,在这个周期里面进行请求,渲染速度反而会更快。
beforeMount
DOM未完成挂载,数据也初始化完成,但是数据的双向绑定还是显示{{}},这是因为Vue采用了Virtual DOM(虚拟Dom)技术。先占住了一个坑。
mounted
数据和DOM都完成挂载,在上一个周期占位的数据把值给渲染进去。可以在这边请求,不过created请求会更好一些。这个周期适合执行初始化需要操作DOM的方法。
beforeUpdate
只要是页面数据改变了都会触发,数据更新之前,页面数据还是原来的数据,当你请求赋值一个数据的时候会执行这个周期,如果没有数据改变不执行。
updated
只要是页面数据改变了都会触发,数据更新完毕,页面的数据是更新完成的。beforeUpdate和updated要谨慎使用,因为页面更新数据的时候都会触发,在这里操作数据很影响性能和容易死循环。
beforeDestroy
这个周期是在组件销毁之前执行,在我项目开发中,觉得这个其实有点类似路由钩子beforeRouterLeave,都是在路由离开的时候执行,只不过beforeDestroy无法阻止路由跳转,但是可以做一些路由离开的时候操作,因为这个周期里面还可以使用data和method。比如一个倒计时组件,如果在路由跳转的时候没有清除,这个定时器还是在的,这时候就可以在这个里面清除计时器。
Destroyed
说实在的,我还真的不知道这个周期跟beforeDestroy有什么区别,我在这个周期里面调用data的数据和methods的方法都能调用,所以我会觉得跟beforeDestroy是一样的。
例子
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>hello world</title>
<script src="./lib/vue.js"></script>
</head>
<body>
<div id="app">
<p>{{ msg }}</p>
</div>
<script type="text/javascript">
//创建一个vue实例
//这就是我们的vm调度者
var vm = new Vue({
//使用id选择器选择需要绑定的元素
el: '#app',
//数据层,这就是需要绑定到界面的数据
data: {
msg: 'hello world'
},
//方法区,存储需要绑定到界面的方法
method: {
},
created:function:(){
//此处可以进行网络请求,从后台拿取数据更新msg
}
})
</script>
</body>
</html>
数据与内容的绑定
插值表达式
插值表达式数据与视图双向绑定,视图会随数据的变化而变化,4种插值表达式如下:
<p>{{ msg }}</p>
<p>{{ msg.length }}</p>
<p>{{msg + '拼接的字符串'}}</p>
<p>{{dlag ? '条件为真' : '条件为假'}}</p>
var vm = new Vue({
//使用id选择器选择需要绑定的元素
el: '#app',
//数据层,这就是需要绑定到界面的数据
data: {
msg: 'hello world'
},
})
结果:
v-once属性
代表只渲染一次,之后不会随着数据的改变而改变。
<div id="app">
<p v-once>{{ msg }}</p>
</div>
v-html属性
data中的数据如果存在标签,就需要v-html。
<div id="app">
<p v-html>
{{url}}
</p>
</div>
var vm = new Vue({
//使用id选择器选择需要绑定的元素
el: '#app',
//数据层,这就是需要绑定到界面的数据
data: {
url: '<h3>v-html</h3>'
}
})
v-pre属性
有时候就不需要插值表达式,直接输出{{message}}的内容就需要使用到v-pre属性。
<div id="app">
<p v-pre>{{ msg }}</p>
</div>
v-cloak属性
有时候网页渲染过慢,会显示{{msg}}而非数值。这时就要v-cloak属性。
<style>
[cloak]{
display:null;
}
</style>
<div id="app" v-cloak>
<p v-pre>{{ msg }}</p>
</div>
绑定函数返回值
计算属性简介
有时候我们可能需要在{{}}里进行一些计算在展示出来数据,vue给我们提供了一个特别好的解决方案:计算属性,我们可以把这些计算的过程写到一个计算属性中去,然后让它动态的计算就可以了。
<div id="app">
<p>{{ fullName }}</p>
</div>
var vm = new Vue({
el: '#app',
data: {
firstName: 'tang',
secondtName: 'dexuan'
},
computed: {
fullName:function(){
return firstName+' '+secondtName
}
}
})
计算属性缓存
计算属性中是有缓存的,不是每次调用都计算一遍。
数据与属性的绑定
v-bind
有时候我们需要将vue option中data数据绑定到html某个标签的属性上,就可以使用v-bind指令,v-bind的语法糖是:
<div id="app">
<img v-bind:src="url" />
</div>
等价于
<div id="app">
<img :src="url" />
</div>
var vm = new Vue({
el: '#app',
data: {
url: 'https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1580928601481&di=3f39275cf8d21264208b21a5b9de7b3c&imgtype=0&src=http%3A%2F%2Fsc.sinaimg.cn%2Fiframe%2F453%2F2012%2F0509%2FU3759P841T453D1F12086DT20140727103938.jpg',
}
})
这就代表了src属性绑定了url。
控件与事件的绑定
v-on
<div id="app">
<button v-on:click="cliEvent">我是按钮</button>
<button @click="cliEvent">我是按钮</button>
</div>
var vm = new Vue({
//使用id选择器选择需要绑定的元素
el: '#app',
//数据层,这就是需要绑定到界面的数据
data: {
msg: 'hello world'
},
//方法区,存储需要绑定到界面的方法
method: {
cliEvent(){
alter("ok")
}
}
})
在事件中,vue会默认给你个event参数,event可以获取当前状态信息。
var vm = new Vue({
//使用id选择器选择需要绑定的元素
el: '#app',
//数据层,这就是需要绑定到界面的数据
data: {
msg: 'hello world'
},
//方法区,存储需要绑定到界面的方法
method: {
cliEvent(event){
alter(event)
}
}
})
控件数据的双向绑定
v-model
一般用于表单控件,比如文本框,实现数据和value的绑定
例子:
<div id="app">
<input type="text" v-model="myText">
</div>
var vm = new Vue({
//使用id选择器选择需要绑定的元素
el: '#app',
//数据层,这就是需要绑定到界面的数据
data: {
myText: 'hello world'
}
})
流程控制
v-if
用于控制相关组件是否显示
<div id="app">
<input type="text" v-if="is_show">
</div>
var vm = new Vue({
//使用id选择器选择需要绑定的元素
el: '#app',
//数据层,这就是需要绑定到界面的数据
data: {
is_show: true
}
})
v-if 和v-else
用于控制相关组件是否显示,如果is_show为true显示第一个,else显示第二个
<div id="app">
<input type="text" v-if="is_show">
<input type="text" v-else>
</div>
var vm = new Vue({
//使用id选择器选择需要绑定的元素
el: '#app',
//数据层,这就是需要绑定到界面的数据
data: {
is_show: true
}
})
v-show
实现本质⽅法不同,v-show本质就是通过控制css中的display设置为none,控制隐藏,只会编译⼀次;v-if是动态的向DOM树内添加或者删除DOM元素,若初始值为false,就不会编译了。⽽且v-if不停的销毁和创建⽐较消耗性能。
- 当显示和隐藏很频繁的时候,就用v-show
- 只有一次或者几次切换用v-if
v-for
迭代普通数组
在data中定义普通数组
data:{
list:[1,2,3,4,5,6]
}
在html中使用 v-for 指令渲染
<p v-for="(item,i) in list">--索引值--{{i}} --每一项--{{item}}</p>
迭代对象数组
在data中定义对象数组
data:{
list:[1,2,3,4,5,6],
listObj:[
{id:1, name:'zs1'},
{id:2, name:'zs2'},
{id:3, name:'zs3'},
{id:4, name:'zs4'},
{id:5, name:'zs5'},
{id:6, name:'zs6'},
]
}
在html中使用 v-for 指令渲染
<p v-for="(user,i) in listObj">--id--{{user.id}} --姓名--{{user.name}}</p>
迭代对象
在data中定义对象
data:{
user:{
id:1,
name:'托尼.贾',
gender:'男'
}
}
在html中使用 v-for 指令渲染
<p v-for="(val,key) in user">--键是--{{key}}--值是--{{val}}</p>
迭代数字
<!-- 注意:如果使用v-for迭代数字的话,前面 count 的值从 1 开始-->
<p v-for="count in 10">这是第{{count}}次循环</p>
vue组件
将一个问题拆分成多个可以处理的小问题,再将其放入整体,这就是组件化思想。
全局组件注册步骤
- 调用Vue.extend()创建组件构造器
- 调用Vue.component()方法注册组件
- 在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>Document</title>
<script src="https://cdn.jsdelivr.net/npm/vue@2.5.16/dist/vue.js"></script>
</head>
<body>
<div id="app">
<my-cpn></my-cpn>
<my-cpn></my-cpn>
</div>
</body>
<script>
const my_cpn = Vue.extend({
template: '<p>这是我的组件</p>'
})
// 定义名为 todo-item 的新组件
Vue.component('my-cpn', my_cpn)
var app = new Vue({
el: "#app",
data: {
m: "hello vue.js",
},
});
</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>Document</title>
<script src="https://cdn.jsdelivr.net/npm/vue@2.5.16/dist/vue.js"></script>
</head>
<body>
<div id="app">
<my-cpn></my-cpn>
<my-cpn></my-cpn>
</div>
</body>
<script>
const my_cpn = Vue.extend({
template: '<p>这是我的组件</p>'
})
var app = new Vue({
el: "#app",
data: {
m: "hello vue.js",
},
components: {
myCpn: my_cpn
}
});
</script>
</html>
父子组件
<!DOCTYPE html>
<html lang="zh">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>vue code</title>
<script src="./lib/vue.js"></script>
</head>
<body>
<div id="app">
<cpn2></cpn2>
<cpn1></cpn1>
</div>
</body>
<script type="text/javascript">
//创建子组件
var com1 = Vue.extend({
template: "<h3>来了老弟</h3>"
})
//创建父组件
var com2 = Vue.extend({
template: `
<div>
<h2>来了老哥</h2>
<cpn1></cpn1>
</div>
`,
components:{
cpn1:com1
}
})
//语法糖模式注册
//注册组件
var vm = new Vue({
el: '#app',
data: {
msg: "单纯的我"
},
methods: {},
components:{
cpn2:com2,
cpn1:{
template: "<h3>来了老弟2</h3>"
}
}
})
</script>
</html>
组件模板分离写法
<!DOCTYPE html>
<html lang="zh">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>vue code</title>
<script src="./lib/vue.js"></script>
</head>
<body>
<div id="app">
<cpn2></cpn2>
<cpn1></cpn1>
</div>
<template id="cpn">
<div>
<h1>来了老弟</h1>
<p>内容。。。。。。</p>
</div>
</template>
</body>
<script type="text/javascript">
//注册组件
var vm = new Vue({
el: '#app',
data: {
msg: "单纯的我"
},
methods: {},
components:{
cpn2:{
template:"#cpn"
}
}
})
</script>
</html>
组件中使用数据与函数
以下是使用组件封装一个计数器
<!DOCTYPE html>
<html lang="zh">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>vue code</title>
<script src="./lib/vue.js"></script>
</head>
<body>
<div id="app">
<cpn></cpn>
<cpn></cpn>
</div>
<template id="cpn">
<div>
<h1>计数器:{{counter}}</h1>
<button @click="increase">+</button>
<button @click="decrease">-</button>
</div>
</template>
</body>
<script type="text/javascript">
//注册组件
var vm = new Vue({
el: '#app',
data: {
msg: "单纯的我"
},
methods: {},
components:{
cpn:{
template:"#cpn",
data(){
return{
counter:0
}
},
methods:{
increase:function(){
this.counter++
},
decrease:function(){
this.counter--
}
}
}
}
})
</script>
</html>
最终结果:
思考,为什么data要做成一个函数呢?因为组件中的数据必须相互独立,return一个对象就会开辟一个新的堆空间,这样可以使得数据隔离
组件间通信
在实际开发中,经常会请求后端数据,获取列表信息等,然而,这个请求是最外层大组件发起请求的,如何将数据在父子之间传递呢?这就需要用到组件间的通信。
父传子
通过props向子组件传递数据。
步骤:
- 定义子组件,定义父组件
- 父组件中保证data函数或者属性中存在想要传给子组件的数值a
- 子组件定义props属性,建立数据变量之间的映射,比如a映射到b
- 在父组件template模版中使用子组件,v-bind:b=a将a与b进行绑定,这样在子组件data中就有b这个变量了
- 在子组件模版中使用变量b,比如 {{b}}
不得不吐槽一下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>Document</title>
<script src="https://cdn.jsdelivr.net/npm/vue@2.5.16/dist/vue.js"></script>
</head>
<body>
<div id="app">
<cpn1 :cmsg=msg :cmovies=movies></cpn1>
<cpn1></cpn1>
</div>
<template id="cpn1">
<div>
<h1>{{cmsg}}</h1>
<h1>{{cmovies}}</h1>
</div>
</template>
</body>
<script>
var app = new Vue({
el: "#app",
data: {
msg: "hahah",
movies: ["海王", "海贼王", "海扁王"],
},
components: {
cpn1: {
template: "#cpn1",
props: {
// 1、类型限制:
// cmovies:Array,
// cmsg:String
// 2、提供一些默认值,以及必传性
cmsg: {
type: String,
default: 'aaaaa'
},
// 类型是对象或数组时,默认值必须是一个函数
cmovies: {
type: Array,
// default:[] vue2.5.17版本,这种写法错误,应在一个工厂函数中返回默认值
default () {
return ["默认值"]
}
}
}
}
}
});
</script>
</html>
支持的类型:String,Number,BOOlean,Array,Symbol,Object,Function,Date
子传父
对于数据来说是父传子,但是对于事件来说就是子传父,一些子组件触发了某些事件时候,就需要将事件传递给父组件,由父组件发起比如请求接口的操作。
步骤:
- 指定想要传给父组件数据
- 事件触发函数,在函数中使用this.$emit(“itemclick”, item)传递数据
- 父组件使用v-on监听数据,@itemclick=“fatherclick”,默认参数为item
- 父组件写fatherclick函数接收数据处理
<!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>Document</title>
<script src="https://cdn.jsdelivr.net/npm/vue@2.5.16/dist/vue.js"></script>
</head>
<body>
<div id="app">
<cpn1 @itemclick="fatherclick"></cpn1>
</div>
<template id="cpn1">
<div>
<button v-for="(item,i) in msg" @click="clickEvent(item)">{{item.name}}</button>
</div>
</template>
</body>
<script>
const cpn = {
template: "#cpn1",
data() {
return {
msg: [{
name: "哈哈",
id: "123"
}, {
name: "呵呵呵",
id: "123"
}]
}
},
methods: {
clickEvent(item) {
this.$emit("itemclick", item)
}
}
}
var app = new Vue({
el: "#app",
data: {
msg: "hahah"
},
components: {
cpn1: cpn
},
methods: {
fatherclick(item) {
alert(JSON.stringify(item))
}
}
});
</script>
</html>
父子数据传递案例练习
需求:目前父组件有num1,num2,这两个数据,子组件有两个输入框,如何做到父组件num和子组件输入框的双向绑定?
解决方案:
- 使用父传子的方式将num1,num2的值传递给子组件,暂定为snum1,snum2
- 使用 :value=“snum1” 将数据单向绑定
- 使用 @input=“evnet”,在改变时触发函数evnet
- event中添加this.$emit(“itemclick”, item)触发子传父
- 父组件中添加方法,接收子组件传进来的值,将其赋给num1,num2
代码如下:
<!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>Document</title>
<script src="https://cdn.jsdelivr.net/npm/vue@2.5.16/dist/vue.js"></script>
</head>
<body>
<div id="app">
<h1>父组件num1:{{num1}}</h1>
<h1>父组件num2:{{num2}}</h1>
<cpn1 :number1="num1" :number2="num2" @iteminput1="iteminput1" @iteminput2="iteminput2"></cpn1>
</div>
<template id="cpn1">
<div>
<h1>子组件num1:{{snum1}}</h1>
<h1>子组件num2:{{snum2}}</h1>
<input type="text" v-model="snum1" @input="inputEvent1"><br>
<input type="text" v-model="snum2" @input="inputEvent2">
</div>
</template>
</body>
<script>
const cpn = {
template: "#cpn1",
props: {
number1: Number,
number2: Number
},
data() {
return {
snum1: this.number1,
snum2: this.number2
}
},
methods: {
inputEvent1(item) {
this.$emit("iteminput1", this.snum1)
},
inputEvent2(item) {
this.$emit("iteminput2", this.snum2)
},
}
}
var app = new Vue({
el: "#app",
data: {
num1: 1,
num2: 2
},
components: {
cpn1: cpn
},
methods: {
iteminput1(item) {
this.num1 = parseInt(item)
},
iteminput2(item) {
console.log(2)
this.num2 = parseInt(item)
},
}
});
</script>
</html>
父访子
如何用父组件获取子组件对象呢?可以使用this.$refs的方法获取。
<!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>Document</title>
<script src="https://cdn.jsdelivr.net/npm/vue@2.5.16/dist/vue.js"></script>
</head>
<body>
<div id="app">
<h1>父组件</h1>
<cpn1 ref="abc"></cpn1>
<button @click="get_sub_cpn">获取子组件</button>
</div>
<template id="cpn1">
<div>
<h1>子组件</h1>
</div>
</template>
</body>
<script>
const cpn = {
template: "#cpn1",
props: {
number1: Number,
number2: Number
},
data() {
return {
snum1: this.number1,
snum2: this.number2
}
},
methods: {
test_method(item) {
console.log("访问子组件的test_method方法")
}
}
}
var app = new Vue({
el: "#app",
data: {
num1: 1,
num2: 2
},
components: {
cpn1: cpn
},
methods: {
get_sub_cpn() {
var cpn = this.$refs.abc
console.log(cpn)
cpn.test_method()
}
}
});
</script>
</html>
最终可以获取该组件的信息:
VueComponent {_uid: 1, _isVue: true, $options: {…}, _renderProxy: Proxy, _self: VueComponent, …}
$attrs: (...)
$children: []
$createElement: ƒ (a, b, c, d)
$el: div
$listeners: (...)
$options: {parent: Vue, _parentVnode: VNode, _parentElm: null, _refElm: null, propsData: {…}, …}
$parent: Vue {_uid: 0, _isVue: true, $options: {…}, _renderProxy: Proxy, _self: Vue, …}
$refs: {}
$root: Vue {_uid: 0, _isVue: true, $options: {…}, _renderProxy: Proxy, _self: Vue, …}
$scopedSlots: {}
$slots: {}
$vnode: VNode {tag: "vue-component-1-cpn1", data: {…}, children: undefined, text: undefined, elm: div, …}
number1: (...)
number2: (...)
snum1: (...)
snum2: (...)
test_method: ƒ ()
_c: ƒ (a, b, c, d)
_data: {__ob__: Observer}
_directInactive: false
_events: {}
_hasHookEvent: false
_inactive: null
_isBeingDestroyed: false
_isDestroyed: false
_isMounted: true
_isVue: true
_props: {}
_renderProxy: Proxy {_uid: 1, _isVue: true, $options: {…}, _renderProxy: Proxy, _self: VueComponent, …}
_self: VueComponent {_uid: 1, _isVue: true, $options: {…}, _renderProxy: Proxy, _self: VueComponent, …}
_staticTrees: [VNode]
_uid: 1
_vnode: VNode {tag: "div", data: undefined, children: Array(1), text: undefined, elm: div, …}
_watcher: Watcher {vm: VueComponent, sync: false, lazy: false, user: false, deep: false, …}
_watchers: [Watcher]
$data: (...)
$isServer: (...)
$props: (...)
$ssrContext: (...)
get $attrs: ƒ reactiveGetter()
set $attrs: ƒ reactiveSetter(newVal)
get $listeners: ƒ reactiveGetter()
set $listeners: ƒ reactiveSetter(newVal)
get snum1: ƒ proxyGetter()
set snum1: ƒ proxySetter(val)
get snum2: ƒ proxyGetter()
set snum2: ƒ proxySetter(val)
__proto__: Vue
cpn.test_method()调用子组件的方法。
子访父
this. p a r e n t 的 方 法 获 取 父 组 件 t h i s . parent的方法获取父组件 this. parent的方法获取父组件this.root的方法获取根组件
插槽
为什么要插槽,因为组件之间有相同部分,有不同部分,对于不同部分,就可以使用插槽的功能。
<!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>Document</title>
<script src="https://cdn.jsdelivr.net/npm/vue@2.5.16/dist/vue.js"></script>
</head>
<body>
<div id="app">
<cpn1>
<h1>我是子组件的插槽1</h1>
</cpn1>
<cpn1>
<h1>我是子组件的插槽2</h1>
</cpn1>
</div>
<template id="cpn1">
<div>
<h1>子组件</h1>
<slot></slot>
</div>
</template>
</body>
<script>
const cpn = {
template: "#cpn1"
}
var app = new Vue({
el: "#app",
components: {
cpn1: cpn
}
});
</script>
</html>
插槽还可以定义默认值,如:
<slot><h1>我是默认值啊</h1></slot>
具名插槽
当一个组件有多个插槽时,单纯的匿名插槽已经无法满足需求了,这时候就需要具名插槽。
<!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>Document</title>
<script src="https://unpkg.com/vue@next"></script>
</head>
<body>
<div id="app">
<cpn1>
<h1 v-slot: left>左边</h1>
<h1 v-slot: mid>中间</h1>
<h1 v-slot: right>右边</h1>
</cpn1>
</div>
<template id="cpn1">
<div>
<h1>子组件</h1>
<slot name="left"></slot>
<slot name="mid"></slot>
<slot name="right"></slot>
</div>
</template>
</body>
<script>
const cpn = {
template: "#cpn1"
}
var app = new Vue({
el: "#app",
components: {
cpn1: cpn
}
});
</script>
</html>
模块的导入导出
在大型前端项目中,不可能将所有js代码用scrips标签写入,两个模块间需要导入和导出变量来完成模块间的信息传递,常用的导入导出标准有:CommonJs、AMD、CMD、ES6,其中最常见的就是es6。
具名导出
导出
export let name1, name2, …, nameN; // also var, const
export let name1 = …, name2 = …, …, nameN; // also var, const
export function FunctionName(){...}
export class ClassName {...}
导入
import * as name from "module-name";
import { member } from "module-name";
使用
name.xxxx
member
默认导出
每个模块只允许一个默认导出.
导出:
let arr=[1,2,3,4,5]
let string = "字符串"
export default {arr, string} // 一次全部导出 以一个对象的形式
导入
import all from "./px.js" // 打包导出 获取方法 import "all" 为自定义名
console.log(all) // 输出 所有 px.js 模块