17.生命周期(Lifecycle)
补:Vue2生命周期
1.引出生命周期
-
在Vue中,使用v-bind:style 动态绑定元素的内联样式
对象语法:v-bind:style={样式名:‘样式值’}
的对象语法---->简写:
:style={样式名:‘样式值’}
样式名如果有-,则改成驼峰式命名。 -
opacity属性
指定了一个元素的透明度。换言之,opacity属性指定了一个元素后面的背景的被覆盖程度。- 语法:
opacity: value | inherit
值 描述 value 规定不透明度。从 0.0 (完全透明)到 1.0(完全不透明)。 inherit 应该从父元素继承 opacity 属性的值。 - 语法:
-
opacity【css不透明度属性】:opacity【变量】
简写=》opacity
-
window.setInterval(调用函数,延时时间)
- 与setTimeout区别:
- setTimeout是延时时间到了就去调用这个回调函数,只调用了一次 就结束了这个定时器。
- setInterval是 每隔这个延迟时间 就去调用这个回调函数 会调用很多次 重复调用这个函数。应用在网页中的一些轮播图上。
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title>引出生命周期</title>
<!-- 引入Vue -->
<script type="text/javascript" src="../js/vue.js"></script>
</head>
<body>
<!--
生命周期:
1.又名:生命周期回调函数、生命周期函数、生命周期钩子。
2.是什么:Vue在关键时刻帮我们调用的一些特殊名称的函数。
3.生命周期函数的名字不可更改,但函数的具体内容是程序员根据需求编写的。
4.生命周期函数中的this指向是vm 或 组件实例对象。
-->
<!-- 准备好一个容器-->
<div id="root">
<h2 v-if="a">你好啊</h2>
<h2 :style="{opacity}">欢迎学习Vue</h2>
</div>
</body>
<script type="text/javascript">
Vue.config.productionTip = false //阻止 vue 在启动时生成生产提示。
new Vue({
el:'#root',
data:{
a:false,
opacity:1
},
methods: {
},
//Vue完成模板的解析并把初始的真实DOM元素放入页面后(挂载完毕)调用mounted
// 后续data数据变化时,会从新更新(updata)页面
mounted(){
// 生命周期函数里面的this,都指向Vue实例
console.log('mounted',this)
setInterval(() => {
this.opacity -= 0.01
if(this.opacity <= 0) this.opacity = 1
},16)
},
})
//通过外部的定时器实现(不推荐)
/* setInterval(() => {
vm.opacity -= 0.01
if(vm.opacity <= 0) vm.opacity = 1
},16) */
</script>
</html>
2.分析生命周期
①生命周期:beforeCreate(创建前)
**1、beforeCreate(创建前)流程
:**在Vue实例创建之前 ,其实应该是说在数据代理和数据监听之前
先初始化生命周期,将生命周期定义在 Vue 实例中(生命周期函数有多少个,都叫啥,什么时候调用这些生命周期),然后接着 Vue 内部自带的事件修饰符(例如:once)定义,告诉 Vue 解析到了这些事件需要怎么处理。但是此时 Vue 中传入的 data 数据还未被代理,此时 vm 实例还未接收到 data 数据,也就不用说 vm_data 了。
**2、beforeCreate(创建前)
:**此时无法在 new Vue() 内部通过this,或者在 外部通过 vm 访问到 data 中的数据,和 methods 中的方法
②生命周期:created(创建后)
1、created(创建后)流程
:在这个流程中,将传入的 data 数据进行数据代理 (挂载到vm实例上的data属性和方法)和 数据监测(对象监听 和 数组监听_data 中的由get 和 set 转化过的data) 对象监测
2、created(创建后)
:此时能够在通过 this 或 vm 实例访问到 data 中的数据以及 methods中配置的方法
③生命周期:beforeMount(载入前)
**1、beforeMount(载入前)流程
:**这里的流程比较复杂,经过了两次判断,从而走了不同的流程,下面详细解析一下。
a、首先问你在 new Vue() 的时候,有没有传入 el 属性,一般我们是会传的,例如上面的例子传的就是 root。如果传了,那就直接走下面的流程,如果没传,我们可以在 vm 实例创建完成之后,通过 vm.$mount(el) 操作来实现相同的效果。
new Vue({
// 配置项 & 生命周期
}).$mount('#root')
**b、**然后问你有没有 传入 templete 配置项,根据是否传入 来判断走哪一个流程 :
- (1)、如果没传【No】,那就将 传入的 el 属性的 outerHtml 作为模板来编译( 之所以是 outerHTML 而不是 innerHTML 是因为,root所在的div 标签【包含:id="root"的div】也是需要被编译进去的,可以在 root 所在的标签上 添加一个绑定属性来鉴定,因为如果改标签被编译了,那么绑定的属性也会编译)。
- (2)、如果传了【Yes】,那就是通过 render 函数,将 templete 配置项中的模板进行编译
【如下的配置项:会报错,有两个root节点】
。templete 配置项其实就是一个字符串,直接将需要展示的页面复制粘贴进去就行,但是会发现语法报错,所以需要使用es6字符串模板。
el: '#root',
template: `
<h2 :style='{opacity}'>欢迎学习 Vue </h2>
<h3>111111</h3>
`,
上面模板里面有两个根节点【h2,h3】,解决办法就是在模板外部添加一个根节点进行包裹。
【正确的配置项:如下】
el: '#root',
template: `
<div>
<h2 :style='{opacity}'>欢迎学习 Vue </h2>
<h3>111111</h3>
</div>
`,
**c、**在这个编译解析过程中,此阶段 Vue 开始解析模板,生成的虚拟DOM还存在内存中,因为虚拟DOM此时还未转化为真实DOM,页面暂时还不能展示解析好的内容。展示的是未经编译的代码。页面显示:
当前的n值是:{{n}}
点我n+1 点我销毁vm
2、beforeMount(载入前):此时页面呈现的是未经 Vue编译的 DOM 结构,所有对 DOM 的操作,最终
都是不奏效的(因为下一步的操作直接将原来就生成的虚拟DOM生成了真实DOM,即使在这里改变了 DOM 结构,但是初始化的虚拟DOM还是未改变的,所以不奏效
)。
④mounted(载入后)
1、mounted(载入后)流程
:将内存中的虚拟DOM转化为真实DOM,然后创建一个vm实例下的$el 属性,将真实DOM往 vm.$el 上存了一份,作为后期更新数据之后的复用节点对比
。然后用 vm.$el 属性替代原本的 el 属性。在这个流程中,会插入页面中,此时页面展示的是经过编译之后的结果
2、mounted(载入后):
a、此时页面中呈现的是经过 Vue 编译过后的DOM。
b、在这个生命周期中,对DOM的操作均是有效的(但尽可能避免在此阶段操作DOM)
c、自此生命周期钩子函数执行完毕,代表初始化过程结束
,一般在此进行:开启定时器,发送网络请求、订阅消息、绑定自定义事件等初始化操作
⑤beforeUpdate(更新前)
- beforeUpdate(更新前)
流程
:这个流程没有做啥操作- beforeUpdate(更新前):通过Vue的数据监听发现了
数据更改之后
,然后同步更新data中的数据
,但是此时数据是新的,页面却还未改变
,即:页面尚未与数据保持同步
。
⑥updated(更新后)
- updated(更新后)
流程
:数据更新之后根据新的数据生成新的虚拟DOM,随后与旧的虚拟DOM进行比较,然后生成新的真实DOM(此时会复用$el中保存的真实DOM),然后完成页面的更新。- updated(更新后):此时数据是新的,页面也是新的,即:页面与数据已经保持同步。
⑦beforeDestroy(销毁前)
- beforeDestroy(销毁前)
流程
:如果此时我不希望在我的数据更新之后,页面上继续响应变化,那么可以调用 vm.$destroy() 这个方法(这是有直接触发)或者等待路由切换等被动触发,那么 Vue 就进入了销毁流程
- beforeDestroy(销毁前):此时vm中的所有:
data、methods、指令等等都还是处于可用状态
,也就是说,之前的页面数据还是照常展示(能取到data中的数据),还可以点击按钮触发绑定的事件(但是事件触发后改变的data不会继续更新
),马上进入销毁流程,一般在此阶段我们可以关闭定时器、取消订阅信息、解绑自定义事件
等等操作。
⑧destroyed(销毁后)
- destroyed(销毁后)
流程
:移除watcher监听器、子组件以及事件监听。- destroyed(销毁后):销毁整个vm 实例
但是在 Vue 调用这些生命周期钩子函数之前,存在一些流程,这些流程不是我们能够干预的
,是 Vue 自己走完这些流程之后,自动执行了生命周期钩子函数,进而完成了 对 Vue 实例的完善。
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title>分析生命周期</title>
<!-- 引入Vue -->
<script type="text/javascript" src="../js/vue.js"></script>
</head>
<body>
<!-- 准备好一个容器-->
<div id="root" :x="n">
<!-- <h2 v-text="n"></h2> -->
<h2>当前的n值是:{{n}}</h2>
<button @click="add">点我n+1</button>
<button @click="bye">点我销毁vm</button>
</div>
</body>
<script type="text/javascript">
Vue.config.productionTip = false //阻止 vue 在启动时生成生产提示。
new Vue({
el:'#root',
// 反引号,完全替换root元素盒子
// template:`
// <div>
// <h2>当前的n值是:{{n}}</h2>
// <button @click="add">点我n+1</button>
// </div>
// `,
data:{
n:1
},
methods: {
add(){
console.log('add')
this.n++
},
bye(){
console.log('bye')
this.$destroy()
}
},
// 监视n的变化
watch:{
n(){
console.log('n变了')
}
},
beforeCreate() {
console.log('beforeCreate')
},
created() {
console.log('created')
},
// 在beforeMount()生命周期中,所有对 DOM 的操作,最终都是不奏效的
beforeMount() {
console.log('beforeMount')
// console.log(this);
// document.querySelector('h2').innerText='伍六七爱梅小姐'
// debugger;
},
// 在mounted()这个生命周期中,对DOM的操作均是有效的(但尽可能避免在此阶段操作DOM)
mounted() {
console.log('mounted')
// console.log(this);
// document.querySelector('h2').innerText='伍六七爱梅小姐'
// console.log('mounted',this.$el);
// debugger;
},
beforeUpdate() {
console.log('beforeUpdate')
// console.log(this);
// console.log(this.n);
// debugger;
},
updated() {
console.log('updated')
// console.log(this.n);
// debugger;
},
beforeDestroy() {
console.log('beforeDestroy')
},
destroyed() {
console.log('destroyed')
},
})
</script>
</html>
3.总结生命周期
- 常用的生命周期钩子:
1.mounted: 发送ajax请求、启动定时器、绑定自定义事件、订阅消息等【初始化操作】。
2.beforeDestroy: 清除定时器、解绑自定义事件、取消订阅消息等【收尾工作】。
-
关于销毁Vue实例
1.销毁后借助Vue开发者工具看不到任何信息。
2.销毁后自定义事件会失效,但原生DOM事件依然有效。
3.一般不会在beforeDestroy操作数据,因为即便操作数据,也不会再触发更新流程了。
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title>引出生命周期</title>
<!-- 引入Vue -->
<script type="text/javascript" src="../js/vue.js"></script>
</head>
<body>
<!--
常用的生命周期钩子:
1.mounted: 发送ajax请求、启动定时器、绑定自定义事件、订阅消息等【初始化操作】。
2.beforeDestroy: 清除定时器、解绑自定义事件、取消订阅消息等【收尾工作】。
关于销毁Vue实例
1.销毁后借助Vue开发者工具看不到任何信息。
2.销毁后自定义事件会失效,但原生DOM事件依然有效。
3.一般不会在beforeDestroy操作数据,因为即便操作数据,也不会再触发更新流程了。
-->
<!-- 准备好一个容器-->
<div id="root">
<h2 :style="{opacity}">欢迎学习Vue</h2>
<button @click="opacity = 1">透明度设置为1</button>
<button @click="stop">点我停止变换</button>
</div>
</body>
<script type="text/javascript">
Vue.config.productionTip = false //阻止 vue 在启动时生成生产提示。
new Vue({
el:'#root',
data:{
opacity:1
},
methods: {
stop(){
this.$destroy()
}
},
//Vue完成模板的解析并把初始的真实DOM元素放入页面后(挂载完毕)调用mounted
mounted(){
console.log('mounted',this)
this.timer = setInterval(() => {
console.log('setInterval')
this.opacity -= 0.01
if(this.opacity <= 0) this.opacity = 1
},16)
},
beforeDestroy() {
clearInterval(this.timer)
console.log('vm即将驾鹤西游了')
},
})
</script>
</html>
18.非单文件组件
1.基本使用
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title>基本使用</title>
<script type="text/javascript" src="../js/vue.js"></script>
</head>
<body>
<!--
Vue中使用组件的三大步骤:
一、定义组件(创建组件)
二、注册组件
三、使用组件(写组件标签)
一、如何定义一个组件?
使用Vue.extend(options)创建,其中options和new Vue(options)时传入的那个options几乎一样,但也有点区别;
区别如下:
1.el不要写,为什么? ——— 最终所有的组件都要经过一个vm的管理,由vm中的el决定服务哪个容器。
2.data必须写成函数,为什么? ———— 避免组件被复用时,数据存在引用关系。
备注:使用template可以配置组件结构。
二、如何注册组件?
1.局部注册:靠new Vue的时候传入components选项
2.全局注册:靠Vue.component('组件名',组件)
三、编写组件标签:
<school></school>
-->
<!-- 准备好一个容器-->
<div id="root">
<hello></hello>
<hr>
<h1>{{msg}}</h1>
<hr>
<!-- 第三步:编写组件标签 -->
<school></school>
<hr>
<!-- 第三步:编写组件标签 -->
<student></student>
</div>
<div id="root2">
<hello></hello>
</div>
</body>
<script type="text/javascript">
Vue.config.productionTip = false
//第一步:创建school组件
const school = Vue.extend({
/* Vue.extend 属于 Vue 的全局 API,在实际业务开发中我们很
少使用,因为相比常用的 Vue.component 写法使用 extend 步骤
要更加繁琐一些。但是在一些独立组件开发场景中,Vue.extend
+ $mount 这对组合是我们需要去关注的。 */
template: `
<div class="demo">
<h2>学校名称:{{schoolName}}</h2>
<h2>学校地址:{{address}}</h2>
<button @click="showName">点我提示学校名</button>
</div>
`,
// el:'#root', //组件定义时,一定不要写el配置项,因为最终所有的组件都要被一个vm管理,由vm决定服务于哪个容器。
data ()
{
return {
schoolName: '小鸡岛便利店',
address: '小鸡岛',
}
},
methods: {
showName ()
{
alert(this.schoolName)
}
},
})
//第一步:创建student组件
const student = Vue.extend({
template: `
<div>
<h2>学生姓名:{{studentName}}</h2>
<h2>学生年龄:{{age}}</h2>
</div>
`,
data ()
{
return {
studentName: '伍六七',
age: '21'
}
},
})
//第一步:创建hello组件
const hello = Vue.extend({
template: `
<div>
<h2>你好啊!{{name}}</h2>
</div>
`,
data ()
{
return {
name: '梅小姐'
}
}
})
//第二步:全局注册组件
// 第一个参数:使用时的组件标签名<hello></hello>
// 第二个参数:要注册的组件名hello
Vue.component('hello', hello)
//创建vm
new Vue({
el: '#root',
data: {
msg: '你好啊!'
},
//第二步:注册组件(局部注册)
components: {
school,
student
}
})
new Vue({
el: '#root2',
})
</script>
</html>
2.几个注意点
- 关于组件名:
- 一个单词组成:
- 第一种写法(首字母小写):
school
- 第二种写法(首字母大写):
School
- 第一种写法(首字母小写):
- 多个单词组成:
- 第一种写法(kebab-case命名):
my-school
- 第二种写法(CamelCase命名):
MySchool (需要Vue脚手架支持)
- 第一种写法(kebab-case命名):
- 备注:
- (1).组件名尽可能回避HTML中已有的元素名称,例如:
h2、H2都不行
。 - (2).可以
使用name配置项
指定组件在开发者工具中呈现的名字。
- (1).组件名尽可能回避HTML中已有的元素名称,例如:
- 关于组件标签:
- 第一种写法:
<school></school>
- 第二种写法:
<school/>
- 备注:
不用使用脚手架时,<school/>会导致后续组件不能渲染
- 一个
简写方式:
const school = Vue.extend(options)
可简写为:const school = options
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title>几个注意点</title>
<script type="text/javascript" src="../js/vue.js"></script>
</head>
<body>
<!-- 准备好一个容器-->
<div id="root">
<h1>{{msg}}</h1>
<school></school>
</div>
</body>
<script type="text/javascript">
Vue.config.productionTip = false
//定义组件
// const s = Vue.extend(options) 可简写为:const s = options
const s = Vue.extend({
// 可以使用name配置项指定组件在开发者工具中呈现的名字。
name:'atxiaojidao',
template:`
<div>
<h2>学校名称:{{name}}</h2>
<h2>学校地址:{{address}}</h2>
</div>
`,
data(){
return {
name:'鸡大宝',
address:'小鸡岛'
}
}
})
new Vue({
el:'#root',
data:{
msg:'欢迎学习Vue!'
},
components:{
school:s
}
})
</script>
</html>
3.组件的嵌套
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title>组件的嵌套</title>
<!-- 引入Vue -->
<script type="text/javascript" src="../js/vue.js"></script>
</head>
<body>
<!-- 准备好一个容器-->
<div id="root">
</div>
</body>
<script type="text/javascript">
Vue.config.productionTip = false //阻止 vue 在启动时生成生产提示。
//要先定义student子组件
const student = Vue.extend({
name:'student',
template:`
<div>
<h2>姓名:{{name}}</h2>
<h2>年龄:{{age}}</h2>
</div>
`,
data(){
return {
name:'何大春',
age:22
}
}
})
//定义school组件
const school = Vue.extend({
name:'school',
template:`
<div>
<h2>职业:{{name}}</h2>
<h2>工作地点:{{address}}</h2>
<student></student>
</div>
`,
data(){
return {
name:'保安队长',
address:'小鸡岛'
}
},
//注册组件(局部)
// 定义 父组件时,里面注册子组件【子组件student要先定义】
components:{
student
}
})
//定义hello组件
const hello = Vue.extend({
template:`<h1>{{msg}}</h1>`,
data(){
return {
msg:'欢迎来到小鸡岛学习!'
}
}
})
//定义app组件
const app = Vue.extend({
template:`
<div>
<hello></hello>
<school></school>
</div>
`,
// 父组件里面注册子组件
components:{
school,
hello
}
})
//创建vm
new Vue({
template:'<app></app>',
el:'#root',
//注册组件(局部)
components:{
app
}
})
</script>
</html>
4.VueComponent
关于VueComponent:
- school
组件本质
是一个名为VueComponent的构造函数
,且不是程序员定义的,是Vue.extend生成的
。 - 我们
只需要写<school/>
**【自闭合标签】**或<school></school>
,Vue解析时会帮我们创建school组件的实例对象,即Vue帮我们执行的:new VueComponent(options)
。 - 特别注意:每次调用Vue.extend,返回的都是一个全新的VueComponent!!!
- 关于this指向:
-
(1).
组件配置中
:- data函数、methods中的函数、watch中的函数、computed中的函数 它们的this均是【
VueComponent实例对象
】。
- data函数、methods中的函数、watch中的函数、computed中的函数 它们的this均是【
-
(2).
new Vue(options)配置中
:- data函数、methods中的函数、watch中的函数、computed中的函数 它们的this均是【
Vue实例对象,vm
】。
- data函数、methods中的函数、watch中的函数、computed中的函数 它们的this均是【
-
VueComponent的实例对象,以后简称vc(也可称之为:
组件实例对象
)。 -
Vue的实例对象,以后简称vm。
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title>VueComponent</title>
<script type="text/javascript" src="../js/vue.js"></script>
</head>
<body>
<!-- 准备好一个容器-->
<div id="root">
<school></school>
<hello></hello>
</div>
</body>
<script type="text/javascript">
Vue.config.productionTip = false
//定义school组件
const school = Vue.extend({
name:'school',
template:`
<div>
<h2>学校名称:{{name}}</h2>
<h2>学校地址:{{address}}</h2>
<button @click="showName">点我提示学校名</button>
</div>
`,
data(){
return {
name:'尚硅谷',
address:'北京'
}
},
methods: {
showName(){
console.log('showName',this)
}
},
})
const test = Vue.extend({
template:`<span>atguigu</span>`
})
//定义hello组件
const hello = Vue.extend({
template:`
<div>
<h2>{{msg}}</h2>
<test></test>
</div>
`,
data(){
return {
msg:'你好啊!'
}
},
components:{test}
})
// console.log('@',school)
// console.log('#',hello)
//创建vm
const vm = new Vue({
el:'#root',
components:{school,hello}
})
</script>
</html>
什么是原型和原型链?
原型:
- 原型是一个
对象
,是函数的一个属性prototype
; - 通过该函数实例化出来的对象都可以继承得到其构造函数的原型对象上的所有属性和方法;
- 原型对象默认有一个属性constructor ,值为对应的构造函数;另外,有一个属性
__proto__
,值为Object.prototype。
原型链:
当访问一个对象的某个属性时,会先在这个对象本身属性上查找,如果没有找到,则会去它的__proto__隐式原型
上查找,即它的构造函数的prototype
,如果还没有找到就会再在构造函数的prototype的__proto__
中查找,这样一层一层向上查找就会形成一个链式结构,我们称为==原型链==。
5.一个重要的内置关系
-
VueComponent.prototype.__proto__ === Vue.prototype
-
VueComponent.prototype.__proto__===vm.prototype
-
vc.__proto__.__proto__=== vm.prototype
-
vc.__proto__.__proto__=== Vue.prototype
-
以上四个等式,实际上是一个等式【借助下图理解】
-
为什么要有这个关系: 让组件实例对象可以访问到 Vue 原型上的属性、方法 。
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title>一个重要的内置关系</title>
<!-- 引入Vue -->
<script type="text/javascript" src="../js/vue.js"></script>
</head>
<body>
<!--
1.一个重要的内置关系:VueComponent.prototype.__proto__ === Vue.prototype
2.为什么要有这个关系:让组件实例对象(vc)可以访问到 Vue原型上的属性、方法。
-->
<!-- 准备好一个容器-->
<div id="root">
<school></school>
</div>
</body>
<script type="text/javascript">
Vue.config.productionTip = false //阻止 vue 在启动时生成生产提示。
// 定义了一个Vue原型上的属性: x
Vue.prototype.x = 99
//定义school组件
const school = Vue.extend({
name:'school',
template:`
<div>
<h2>学校名称:{{name}}</h2>
<h2>学校地址:{{address}}</h2>
<button @click="showX">点我输出x</button>
</div>
`,
data(){
return {
name:'尚硅谷',
address:'北京'
}
},
methods: {
showX(){
// 通过组件实例对象(vc)可以访问到 Vue原型上的属性 和 方法
console.log(this.x)
}
},
})
//创建一个vm
const vm = new Vue({
el:'#root',
data:{
msg:'你好'
},
components:{school}
})
//定义一个构造函数
/* function Demo(){
this.a = 1
this.b = 2
}
//创建一个Demo的实例对象
const d = new Demo()
console.log(Demo.prototype) //显示原型属性
console.log(d.__proto__) //隐式原型属性
console.log(Demo.prototype === d.__proto__) //true
//程序员通过显示原型属性操作原型对象,追加一个x属性,值为99
Demo.prototype.x = 99
console.log('@',d) */
</script>
</html>
19.单文件组件
1.xxx.vue文件基本模板
<template>
<!-- 组件的结构 -->
<div>
</div>
</template>
<script>
// 组件交互相关的代码(数据、方法等等)
</script>
<style>
/* 组件的样式 */
</style>
2.xx.vue文件变成js文件的两种方式:
-
webpack
-
脚手架(使用)
例:创建school.vue组件
组件起名
一个单词的名字:
- 直接纯小写school.vue
第一个字母大写School.vue(一般使用)
多个单词:
- my-school.vue
(大驼峰) MySchool.vue(一般使用)
3.暴露的三种方式
demo.vue : <sctipt></script>
中写三种暴露组件方式之一。
<template>
<!-- 组件的结构 -->
<div class="demo">
<h2>学校名称:{{schoolName}}</h2>
<h2>学校地址:{{address}}</h2>
<button @click="showName">点我提示学校名</button>
</div>
</template>
<script>
//组件交互的相关代码
</script>
<style>
/* 组件的样式 */
.demo{
background-color: orange;
}
</style>
第一种:分别暴露
<script>
export const school = Vue.extend({
data(){
return {
schoolName:'尚硅谷',
address:'北京',
}
},
methods:{},
})
</script>
第二种:统一暴露
<script>
const school = Vue.extend({
data(){
return {
schoolName:'尚硅谷',
address:'北京',
}
},
methods:{},
})
export {school}
</script>
第三种:默认暴露
<script>
const school = Vue.extend({
data(){
return {
schoolName:'尚硅谷',
address:'北京',
}
},
methods:{},
})
export default school
</script>
一般使用默认暴露,因为使用默认暴露在导入时,直接使用 import ??? from ???
就可以了。但是使用分别暴露和统一暴露都需要这样写 import {???} from ???
。
使用默认暴露时,可以不用中转变量。方式如下:
<script>
export default Vue.extend({
data(){
return {
schoolName:'尚硅谷',
address:'北京',
}
},
methods:{},
})
</script>
然后还可以进一步简写,省去Vue.extend(),使用创建组件的简写形式。直接暴露组件的配置对象。
<script>
export default {
name:'School',
data(){
return {
schoolName:'尚硅谷',
address:'北京',
}
},
methods:{},
}
</script>
创建两个组件,分别是Student和School
创建了App组件
在App组件中引入组件(在脚手架中,import组件时,可以带.vue后缀也可以不带
)
在main.js(入口文件)中创建Vue实例
App.vue文件如下:
<template>
<div>
<School></School>
<Student></Student>
</div>
</template>
<script>
//引入组件
import School from './School'
import Student from './Student.vue'
export default {
name:'App',
components:{
School,
Student
}
}
</script>
-
创建Vue实例之后,发现没有Vue实例服务的实例,所以需要创建一个html文件。
-
在index.html文件中,
在body的闭标签上方引入main.js文件,保证容器先存在
。 -
在main.js上方引入main.js依赖的vue.js文件
-
然后把写进页面(两种形式:直接写或者通过template)
main.js文件
// 当前目录下的App.vue文件
import App from './App.vue'
new Vue({
//为哪一个容器服务
el:'#root',
template:`<App></App>`,
//注册组件App
components:{App},
})
index.html文件
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title>练习一下单文件组件的语法</title>
</head>
<body>
<!-- 准备一个容器 -->
<div id="root"></div>
<!-- 在index.html文件中,在body的闭标签上方引入main.js文件,保证容器先存在。 -->
<!-- <script type="text/javascript" src="../js/vue.js"></script> -->
<!-- <script type="text/javascript" src="./main.js"></script> -->
</body>
</html>
件)中创建Vue实例**
App.vue文件如下:
<template>
<div>
<School></School>
<Student></Student>
</div>
</template>
<script>
//引入组件
import School from './School'
import Student from './Student.vue'
export default {
name:'App',
components:{
School,
Student
}
}
</script>
-
创建Vue实例之后,发现没有Vue实例服务的实例,所以需要创建一个html文件。
-
在index.html文件中,
在body的闭标签上方引入main.js文件,保证容器先存在
。 -
在main.js上方引入main.js依赖的vue.js文件
-
然后把写进页面(两种形式:直接写或者通过template)
main.js文件
// 当前目录下的App.vue文件
import App from './App.vue'
new Vue({
//为哪一个容器服务
el:'#root',
template:`<App></App>`,
//注册组件App
components:{App},
})
index.html文件
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title>练习一下单文件组件的语法</title>
</head>
<body>
<!-- 准备一个容器 -->
<div id="root"></div>
<!-- 在index.html文件中,在body的闭标签上方引入main.js文件,保证容器先存在。 -->
<!-- <script type="text/javascript" src="../js/vue.js"></script> -->
<!-- <script type="text/javascript" src="./main.js"></script> -->
</body>
</html>