el 挂载点
//index.html
<body>
<div id="app">
</div>
</body>
//main.js
new Vue({
el:'#app'
})
或
new Vue({
...
}).$mount('#app')
data 内部数据
//main.js
//对象的形式
new Vue({
data:{
n:0
}
...
})
//函数的形式
new Vue({
data: function(){
return {
n: 0
}
...
}
})
应该优先使用函数,为何?
import Demo from './Demo.vue'
new Vue({
data: function(){
return {
n: 0
}
},
//...
render: h=>h(X, [h(Demo), h(Demo)])
})
如上,如果通过import Demo from './Demo.vue'引入,那么Demo.vue里的data必须是函数
因为这里的Demo实际上是一个对象,Vue会自动把这个对象传给new Vue
如上使用render
-
如果data是对象
- Vue会传两次对象给new Vue,也就是new Vue(Demo)了两遍,而这两次对象的data是同一个data,
- 也就是说这两个组件用了同一个data,这样如果其中一个组件把data改了,另一个组件的data也会被更改
-
如果data是函数
-
每一次执行new Vue(Demo),都会调用一次Demo.data(),这样使得每一次执行,都会得到一个全新的data
-
methods 方法
使用Vue完整版
// main.js
new Vue({
data(){
return {
n: 0,
array:[1,2,3,4,5,6,7,8]
}
},
template:`
<div class="red">
{{n}}
<button @click="add">+1</button>
<hr>
{{filter()}}
</div>
`,
methods:{
add(){
this.n += 1
},
filter(){
return this.array.filter(i => i%2 ===0)
}
},
}).$mount("#app")
methods 每次执行都会重新渲染
component 组件
方法一
- 创建一个文件 Demo.vue,将其引入
//Demo.vue
<template>
<div class="red">
demo
</div>
</template>
<style scoped>
.red{
color:red;
}
</style>
//main.js
import Demo from './Demo.vue'
const vm = new Vue({
components:{//引入组件
Demo1:Demo
},
data(){
return {
n: 0
array:[1,2,3,4,5,6,7,8]
}
},
template:`
<div class="red">
{{n}}
<button @click="add">+1</button>
<Demo1/>
<hr>
{{filter()}}
</div>
`,//在template写入组件
methods:{
add(){
this.n += 1
},
filter(){
return this.array.filter(i => i%2 ===0)
}
},
}).$mount("#app")
ES6的新语法中,如果对象里,key和value一样即components:{Demo:Demo},可以缩写为:
import Demo from './demo.vue'
new Vue({
components: {Demo},
})
方法二
运用JS
Vue.component('Demo2',{
template:`
<div>demo2</div>
`
})
const vm = new Vue({
data(){
...
},
template:`
<div class="red">
{{n}}
<button @click="add">+1</button>
<Demo2/>
<hr>
{{filter()}}
</div>
`,
methods:{
...
},
}).$mount("#app")
组件和实例的区别:
我是入口(直接new Vue),我就是实例,我是被别人用的(import或者Vue.component),我就是组件
方法三
将上述两种方法的特点相结合
// main.js
const vm = new Vue({
components:{
Demo3:{
data(){
return{n:0}
},
template:`
<div>Demo3's n:{{n}}</div>
`
}
},
data(){
...
},
template:`
<div class="red">
{{n}}
<button @click="add">+1</button>
<Demo3/>
<hr>
{{filter()}}
</div>
`,
methods:{
...
},
}).$mount("#app")
同样,成功插入组件,且这里点+1按钮,只会加外面的0,不会加Demo3's n的0
注:优先使用方法一,因为其他两个方法不够模块化
四个钩子
created
此时创建的功能出现在了内存中,没有出现在页面中
new Vue({
data(){
return {
n: 0,
}
},
template:`
<div class="red">
{{n}}
<button @click="add">+1</button>
</div>
`,
created(){
debugger//在created出打一个断点
console.log('这玩意出现在内存中,没有出现在页面中')
},
methods:{
add(){
this.n += 1
},
},
}).$mount("#app")
运行,
可以看到内面里什么都没有
mounted
new Vue({
data(){
...
}
},
template:`
...
`,
created(){
console.log('这玩意出现在内存中,没有出现在页面中')
},
mounted(){
debugger //在mounted处打一个断点
console.log('这玩意出现在页面中')
},
methods:{
...
},
}).$mount("#app")
可以看到,执行到mounted时,数字和按钮已经出现在了页面中
update
new Vue({
data(){
...
}
},
template:`
...
`,
created(){
console.log('这玩意出现在内存中,没有出现在页面中')
},
mounted(){
console.log('这玩意出现在页面中')
},
updated(){
console.log('更新了')
console.log(this.n)
},
methods:{
...
},
}).$mount("#app")
在created和mounted阶段都不会触发updated,只有点击按钮后才会触发,且每次更新都能拿到最新的n
所以,updated能保证每次数据都更新了,再触发当前的函数
destroyed
我们需要让一个组件出现,然后让它消失,
- 所以我们需要先搞一个Demo.vue,把之前new Vue里内容放入进去
- 把这个Demo.vue作为组件引入
- 在main.js中设置一个按钮,点击时让div里的内存消失,
- 再点击时,让内容重现
//Demo.vue
<template>
<div class="red">
{{n}}
<button @click="add">+1</button>
</div>
</template>
<script>
export default {
data(){
return {
n: 0,
array:[1,2,3,4,5,6,7,8]
}
},
created(){
console.log('这玩意出现在内存中,没有出现在页面中')
},
mounted(){
console.log('这玩意出现在页面中')
},
updated(){
console.log('更新了')
console.log(this.n)
},
destroyed(){
console.log('已经消亡了')
},
methods:{
add(){
this.n += 1
},
},
}
</script>
//main.js
import Demo from './Demo.vue'
new Vue({
components:{Demo},
data:{
visible:true
},
template:`
<div>
<button @click="toggle">toggle</button>
<hr>
<Demo v-if="visible===true"/>
</div>
`,
methods:{
toggle(){
this.visible=!this.visible
}
}
}).$mount("#app")
且,每一次出现在内存中的数据都是新的数据
证明很简单,做个实验,我们点击上面的+1按钮,使数字到4,再点击toggle,如果重新出现的内容是4就是原来的数据,如果是0就是新的数据
props 外部属性
可以传字符串,传值
首先需要一个Demo.vue
//Demo.vue
<template>
<div class="red">
这里是Demo的内部
{{this.message}}
</div>
</template>
<script>
export default {
props:['message']//从外部接受一个message,这个message会自动绑到this上面
}
</script>
<style scoped>
.red{
color:red;
border: 1px solid red;
}
</style>
并在main.js中将其引入
//main.js
import Demo from './Demo.vue'
new Vue({
components:{Demo},
data(){
return{
n:0
}
},
template:`
<div>
<Demo message="你好 这里是外部穿进去的props"/> //传字符串
<Demo :message="n"/> //传值
</div>
`,
methods:{
}
}).$mount("#app")
当然,还可以传methods
//Demo.vue
<template>
<div class="red">
这里是Demo的内部
{{this.message}}
<button @click="fn">call fn</button>
</div>
</template>
<script>
export default {
props:['message','fn']
}
</script>
<style scoped>
...
</style>
import Demo from './Demo.vue'
new Vue({
components:{Demo},
data(){
return{
n:0
}
},
template:`
<div>
这里是外部实例{{n}}
<Demo :message="n":fn="add"/>
</div>
`,
methods:{
add(){
this.n += 1
},
}
}).$mount("#app")
main.js里的add方法传给了Demo.vue,Demo.vue里面的click事件调用了add,
点击组件demo的按钮, 外部的n+1, 且更新的n用 :message再传入内部组件,于是内部组件的n也同步更新