声明
本文没有细讲,是为了帮助工作需要的朋友们快速入门Vue写的,或者是复习用的文章,所以不要说:啊!这里也不说因为啥,就这么写 别杠,杠就是你对,出门左转谢谢,求你给我写一篇细节点的好吗,我必给你点赞 此文会一直更到实战项目完事,附带代码,有错误欢迎指出,有问题留言,期间我会不断补充,细节一下文章内容的,大家一起加油吧
总览
Vue起步
Hello World
在官网下载vue.js(百度Vue进入官网) 我们先用原生来写一段代码
<body>
<div id="app"></div>
<script>
var dom = document.getElementById('app')
dom.innerHTML = 'hello world'
</script>
</body>
现在我们要用vue来写了,我们要引入vue.js,然后创建vue实例 Vue.js在官网可以下载,我也会直接给大家
<body>
<div id="app">{{ content }}</div>
<script>
var app = new Vue({
el: '#app',
data: {
content: 'hello world'
}
})
</script>
</body>
el配置项:实例负责管理的区域 我们如果要延迟两秒显示内容的话需要用setTimeout
<body>
<div id="app">{{ content }}</div>
<script>
var app = new Vue({
el: '#app',
data: {
content: 'hello world'
}
})
setTimeout(function () {
app.$data.content = 'bye world'
}, 2000)
</script>
</body>
这里$data理解为data的别名
我们用原生和Vue追重要的区别是,我们不需要DOM操作了
使用Vue.js实现TodoList(例子)
<body>
<div id="app">
<input type="text">
<button>提交</button>
<ul>
<li>第一课的内容</li>
<li>第二课的内容</li>
</ul>
</div>
</body>
现在我有个需求,输入框输入内容,提交后呈现在li 我们现在,要利用vue.js不再让我们的数据是死数据 具体代码如下
<body>
<div id="app">
<input type="text">
<button>提交</button>
<ul>
<li v-for="item in list">{{item}}</li>
</ul>
</div>
<script>
var app = new Vue({
el: '#app',
data: {
list: ['第一课的内容', '第二课的内容']
}
})
</script>
</body>
效果和原生是一样的 v-for指令:类似于for,就是用来遍历渲染的 v-on:绑定事件 v-model:数据的双向绑定
<body>
<div id="app">
<input type="text" v-model="inputValue">
<button v-on:click="handleBtnClick">提交</button>
<ul>
<li v-for="item in list">{{item}}</li>
</ul>
</div>
<script>
var app = new Vue({
el: '#app',
data: {
list: ['第一课的内容', '第二课的内容'],
inputValue: ''
},
methods: {
handleBtnClick: function () {
}
},
})
</script>
</body>
这就是双向的数据绑定
<body>
<div id="app">
<input type="text" v-model="inputValue">
<button v-on:click="handleBtnClick">提交</button>
<ul>
<li v-for="item in list">{{item}}</li>
</ul>
</div>
<script>
var app = new Vue({
el: '#app',
data: {
list: [],
inputValue: ''
},
methods: {
handleBtnClick: function () {
this.list.push(this.inputValue)
this.inputValue = ''
}
},
})
</script>
</body>
MVVM模式
在MVVM模式之前,前端采用的是MVP的模式
<body>
<div>
<input type="text">
<button id="btn">提交</button>
<ul></ul>
</div>
<script>
function Page() { }
$.extend(Page.prototype, {
init: function () {
this.bindEvents()
},
bindEvents: function () {
var btn = $('#btn')
btn.on('click', $.proxy(this.handleBtnClick,
this))
},
handleBtnClick: function () {
alert('123')
}
})
var page = new Page()
page.init()
</script>
</body>
这是一段基础的代码
<body>
<div>
<input id="input" type="text">
<button id="btn">提交</button>
<ul id="ul"></ul>
</div>
<script>
function Page() { }
$.extend(Page.prototype, {
init: function () {
this.bindEvents()
},
bindEvents: function () {
var btn = $('#btn')
btn.on('click', $.proxy(this.handleBtnClick,
this))
},
handleBtnClick: function () {
var inputValue = $("#input").val()
var ulElem = $("#ul")
ulElem.append('<li>' + inputValue + '</li>')
$("#input").val('')
}
})
var page = new Page()
page.init()
</script>
</body>
这是我们的效果代码 可以达到跟vue一样的效果 M:模型,在这个代码里不涉及Ajax,所以不涉及M层 V:视图 P:控制器
MVVM呢 注意,我们需要关注的是view和model层 VM层不需要我们去操作,它是Vue自动操作的
- M层:就是我们写的数据
- V层:就是视图
- VM层:就是我们数据变,视图就跟着变,这个不需要我们操作
前端组件化
每个组件就是每个页面上的一个区域,类似于原生里面,我们不也是用各个div盒子来进行分区吗 我们在Vue里,不同的区域我们会有对应的组件
使用组件化思想修改TodoList
<!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="./vue.min.js"></script>
</head>
<body>
<div id="app">
<input type="text" v-model="inputValue">
<button v-on:click="handleBtnClick">提交</button>
<ul>
<todo-item v-bind:content="item" v-for="item in list"></todo-item>
</ul>
</div>
<script>
Vue.component("TodoItem", {
props: ['content'],
template: "<li>{{content}}</li>"
})
var app = new Vue({
el: '#app',
data: {
list: [],
inputValue: ''
},
methods: {
handleBtnClick: function () {
this.list.push(this.inputValue)
this.inputValue = ''
}
},
})
</script>
</body>
</html>
以上的是定义了一个全局组件,现在我们想定义一个局部组件呢 最主要的区别就是,我们需要去注册组件,用components去注册
<!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="./vue.min.js"></script>
</head>
<body>
<div id="app">
<input type="text" v-model="inputValue">
<button v-on:click="handleBtnClick">提交</button>
<ul>
<todo-item v-bind:content="item" v-for="item in list"></todo-item>
</ul>
</div>
<script>
var TodoItem = {
props: ['content'],
template: "<li>{{content}}</li>"
}
var app = new Vue({
el: '#app',
components: {
TodoItem: TodoItem
},
data: {
list: [],
inputValue: ''
},
methods: {
handleBtnClick: function () {
this.list.push(this.inputValue)
this.inputValue = ''
}
},
})
</script>
</body>
</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="./vue.min.js"></script>
</head>
<body>
<div id="app">
<input type="text" v-model="inputValue">
<button v-on:click="handleBtnClick">提交</button>
<ul>
<todo-item v-bind:content="item"
v-bind:index="index"
v-for="(item,index) in list"
@delete="handleItemDelete">
</todo-item>
</ul>
</div>
<script>
var TodoItem = {
props: ['content', 'index'],
template: "<li @click='handleItemClick'>{{content}}</li>",
methods: {
handleItemClick: function () {
this.$emit("delete", this.index)
}
}
}
var app = new Vue({
el: '#app',
components: {
TodoItem: TodoItem
},
data: {
list: [],
inputValue: ''
},
methods: {
handleBtnClick: function () {
this.list.push(this.inputValue)
this.inputValue = ''
},
handleItemDelete: function (index) {
this.list.splice(index, 1)
}
},
})
</script>
</body>
</html>
Vue基础
Vue实例
Vue 的每个组件实际上都是一个Vue的实例,我们官方用vm
Vue2生命周期
生命周期函数就是Vue实例在某一个时间点会自动执行的函数,通过不同的时间点,可以做不同的时间,比较常用的是created和mounted,可以用来发axios和操作DOM
计算属性,方法与侦听器
<body>
<div id="app">
{{first + " " + last}}
</div>
<script>
var vm = new Vue({
el: '#app',
data: {
first: "Jin",
last: "Lin"
}
})
</script>
</body>
我想让页面上显示Jin Lin,我在插值中是这个写法,可以发现,他成语句了,也就是有逻辑了,但是我们不想在模版的插值中去写逻辑,怎么办 我们引出一个概念:计算属性
<body>
<div id="app">
{{full}}
</div>
<script>
var vm = new Vue({
el: '#app',
data: {
first: "Jin",
last: "Lin"
},
computed: {
full: function () {
console.log('计算了');
return this.first + " " + this.last
}
}
})
</script>
</body>
计算属性和别的最重要的区别就是:它还是属性,它和data里的属性最大的区别就是,它是通过计算得来的 计算属性有一个缓存的机制:就是计算属性依赖的值不发生改变,计算属性就不会发生计算 除了计算属性,我们还可以通过方法来达到相同的效果
<body>
<div id="app">
{{full()}}
</div>
<script>
var vm = new Vue({
el: '#app',
data: {
first: "Jin",
last: "Lin"
},
methods: {
full: function () {
return this.first + " " + this.last
}
},
})
</script>
</body>
只不过我们需要用()调用一下 但是这种方法,是没有计算属性有效的,为什么这么说呢 除了以上的两种,还有一种,叫做侦听
<body>
<div id="app">
{{full}}
{{age}}
</div>
<script>
var vm = new Vue({
el: '#app',
data: {
first: "Jin",
last: "Lin",
full: "Jin Lin",
age: "18"
},
watch: {
first: function () {
console.log('计算了一次');
this.full = this.first + "" + this.last
},
last: function () {
console.log('计算了一次');
this.full = this.first + "" + this.last
}
}
})
</script>
</body
watch也有缓存
那么,watch和computed都具有缓存的机制,推荐使用哪个呢 computed呗,因为简单呗
watch和computed区别: watch可以开启异步任务,computed不可以开启异步,因为它依靠返回值 computed可以完成的功能,watch都可以完成
计算属性的getter和setter
<body>
<div id="app">
{{full}}
</div>
<script>
var vm = new Vue({
el: '#app',
data: {
first: "Jin",
last: "Lin",
},
computed: {
full: {
get: function () {
return this.first + " " + this.last
},
set: function (value) {
var arr = value.split(" ")
this.first = arr[0]
this.last = arr[1]
}
}
}
})
</script>
</body>
Vue的样式绑定
<body>
<div id="app">
<div @click="hand" :class="{activated:isActivated}">
hello world
</div>
</div>
<script>
var vm = new Vue({
el: '#app',
data: {
isActivated: false
},
methods: {
hand: function () {
this.isActivated = true
}
},
})
</script>
</body>
通过这个,我们就可以实现,点击变颜色了
<!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="./vue.min.js"></script>
<style>
.activated {
color: red;
}
</style>
</head>
<body>
<div id="app">
<div @click="hand" :class="{activated}">
hello world
</div>
</div>
<script>
var vm = new Vue({
el: '#app',
data: {
activated: ""
},
methods: {
hand: function () {
this.activated = "activated"
}
},
})
</script>
</body>
</html>
我们想再点击变黑,互相切换呢
hand: function () {
this.activated = this.activated === "activated" ? "" : "activated"
}
可以用if else,但是三元表达式不是更简便,看着更牛b嘛,嘿嘿 那么,如果我们直接绑定style呢,两种写法:对象形式,数组形式 对象:
<body>
<div id="app">
<div :style="styleObj">
hello world
</div>
</div>
<script>
var vm = new Vue({
el: '#app',
data: {
styleObj: {
color: "red"
}
},
methods: {
},
})
</script>
</body>
变色的
<body>
<div id="app">
<div :style="styleObj" @click="hand">
hello world
</div>
</div>
<script>
var vm = new Vue({
el: '#app',
data: {
styleObj: {
color: "red"
}
},
methods: {
hand: function () {
this.styleObj.color = this.styleObj.color === "red" ? "black" : "red"
}
},
})
</script>
</body>
数组模式
<body>
<div id="app">
<div :style="[styleObj,{fontSize:'20px'}]" @click="hand">
hello world
</div>
</div>
<script>
var vm = new Vue({
el: '#app',
data: {
styleObj: {
color: "red"
}
},
methods: {
hand: function () {
this.styleObj.color = this.styleObj.color === "red" ? "black" : "red"
}
},
})
</script>
</body>
字符串写法:适用于样式的类名不确定,需要动态指令 数组写法:要绑定的样式个数不确定,名字也不确定 对象写法:要绑定的样式个数不确定,名字也不确定,但要动态决定用不用
Vue中的条件渲染
<body>
<div id="app">
<div v-if="show">{{message}}
</div>
</div>
<script>
var vm = new Vue({
el: '#app',
data: {
show: false,
message: "Jin ? Lin"
}
})
</script>
</body>
这是v-if,同时还有一个指令v-show
<body>
<div id="app">
<div v-if="show">{{message}}</div>
<div v-show="show">{{message}}</div>
</div>
<script>
var vm = new Vue({
el: '#app',
data: {
show: false,
message: "Jin ? Lin"
}
})
</script>
</body>
注意这里的区别,v-if是直接没有,而v-show是用了display:none,也就是说,这两者在根本上就不同 显然,我们v-show的性能更高一些,因为它不用频繁地销毁和生产DOM 但是,v-if能和v-else配合使用,当然也可以和v-else-if使用,需要注意的是,中间不能被打断 还有一点需要注意的:v-show不能和template配合使用
Vue列表渲染
<body>
<div id="app">
<div v-for="item of list">
{{item}}
</div>
</div>
<script>
var vm = new Vue({
el: '#app',
data: {
list: [
"Jin",
"Lin"
]
}
})
</script>
</body>
item of list中的of可以改成in
<body>
<div id="app">
<div v-for="(item,index) of list">
{{item}}
</div>
</div>
<script>
var vm = new Vue({
el: '#app',
data: {
list: [
"Jin",
"Lin"
]
}
})
</script>
</body>
index是索引下标 为了提高性能,我们会给循环加一个key值(体现在虚拟DOM上) 这里不推荐用index,正常开发后端都会有一个id,或者是什么别的东西
<body>
<div id="app">
<div v-for="(item,index) of list" :key="item.id">
{{item}} ---- {{index}}
</div>
</div>
<script>
var vm = new Vue({
el: '#app',
data: {
list: [
{
id: '001',
name: 'Jin'
},
{
id: '002',
name: 'Lin'
}
]
}
})
</script>
</body>
现在页面是这个效果 我们需要进行一下改进 我们还可以遍历对象
<body>
<div id="app">
<div v-for="item of userInfo">
{{item}}
</div>
</div>
<script>
var vm = new Vue({
el: '#app',
data: {
userInfo: {
name: "shaka",
age: 18,
gender: "男"
}
}
})
</script>
</body>
我们可以加一个key
<body>
<div id="app">
<div v-for="(item,key) of userInfo">
{{item}}----{{key}}
</div>
</div>
<script>
var vm = new Vue({
el: '#app',
data: {
userInfo: {
name: "shaka",
age: 18,
gender: "男"
}
}
})
</script>
</body>
我们可以发现这个key就是键名,那么item就是键值 当然,我们还可以加index
Vue中的set方法
这是对象的set方法 我们要是操作数组对象的话 我们可以用push、pop、shift等数组的api,这里也可以用set 首先,如果我们直接改的话
<body>
<div id="app">
<div v-for="(item,index) of userInfo">
{{item}}
</div>
</div>
<script>
var vm = new Vue({
el: '#app',
data: {
userInfo: [1, 2, 3, 4]
}
})
</script>
</body>
Vue中的事件绑定
<body>
<div id="app">
<button @click="hand">Button</button>
</div>
<script>
var vm = new Vue({
el: '#app',
methods: {
hand: function (e) {
console.log(e);
}
},
})
</script>
</body>
这是我们正常的写法 那么我们应该怎么办呢 这种写法有什么好处呢 它可以让我们传递一些额外的参数 这就是绑定事件的两种写法 看下面的带代码
<body>
<div id="app">
<form action="/abc" @click="hand">
<input type="submit">
</form>
</div>
<script>
var vm = new Vue({
el: '#app',
methods: {
hand: function (e) {
console.log(e);
}
},
})
</script>
</body>
那么,我们想阻止表单提交的默认行为,怎么去做 这么写未免麻烦,简写形式呢 这个prevent叫做事件修饰符,同样的修饰符还有好几个
<body>
<div id="app">
<input @keydown="hand">
</div>
<script>
var vm = new Vue({
el: '#app',
methods: {
hand: function (e) {
console.log(e.target.value);
}
},
})
</script>
</body>
我们想输入回车的时候再输出到控制台,这个时候就需要按键修饰符了 还有系统修饰符需要注意,比如ctrl,它代表你必须一边按住ctrl一边输入才行 还有监测鼠标右键:@click.right 就可以了
<body>
<div id="app">
<div @click.right="hand">click</div>
</div>
<script>
var vm = new Vue({
el: '#app',
methods: {
hand: function (e) {
console.log("right");
}
},
})
</script>
</body>
Vue中的表单绑定
核心就是v-model指令,之前介绍双向绑定的时候已经给大家介绍过了,这里是想说,不止可以应用在input框中,还可以应用在别的地方 textarea,checkbox都可以应用
<body>
<div id="app">
<select v-model="value">
<option disabled>--请选择--</option>
<option>A</option>
<option>B</option>
<option>C</option>
</select>
{{value}}
</div>
<script>
var vm = new Vue({
el: '#app',
data: {
value: ""
}
})
</script>
</body>
需要注意的是,我们给option加value呢 这样页面会优先显示value的值,如果没有value才会显示text的内容 当然,v-model也有修饰符,比如lazy(失去焦点发生反应),number 就是input框有一个问题,就是我们不管输入字符串还是数字,它都会返给我们一个字符串
<body>
<div id="app">
<input type="text" v-model="value">
{{value}}
</div>
<script>
var vm = new Vue({
el: '#app',
data: {
value: ""
},
watch: {
value: function () {
console.log(typeof this.value);
}
}
})
</script>
</body>
还有一个trim,就是去空格,这个就不多说了
Vue组件
Vue组件的细节点
这是我们正常去写一个表格 那我们想用组件去写呢
<body>
<div id="app">
<table>
<tbody>
<row></row>
<row></row>
<row></row>
</tbody>
</table>
</div>
<script>
Vue.component('row', {
template: '<tr><td>this is row</td></tr>'
})
var vm = new Vue({
el: '#app'
})
</script>
</body>
但是会出bug,违背了我们h5的规范 那么我们就会用is来解决这个问题
<body>
<div id="app">
<table>
<tbody>
<tr is="row"></tr>
<tr is="row"></tr>
<tr is="row"></tr>
</tbody>
</table>
</div>
<script>
Vue.component('row', {
template: '<tr><td>this is row</td></tr>'
})
var vm = new Vue({
el: '#app'
})
</script>
用is属性,不会出bug 既能保证tr里是我们的组件,又能保证它符合h5的编码规范,不会出bug 同理,ul,li也是这个道理 我现在想对代码进行改进 这样可以吗 答案是不可以的,这是为什么 这里要说的是,我们虽然在vm(根组件)里面的data可以写成对象形式,但是在非根组件(也就是子组件)中是不可以的,我们要求必须是个函数 这样写就不会发生问题了 这里就要说,为什么要是个函数了
ref:用来操作DOM
<body>
<div id="app">
<div ref="hello" @click="hand">hello world</div>
</div>
<script>
var vm = new Vue({
el: '#app',
methods: {
hand: function () {
console.log(this.$refs.hello);
}
},
})
</script>
</body>
父子组件的数据传递
首先,我们先注册局部组件
<body>
<div id="app">
<counter></counter>
<counter></counter>
</div>
<script>
var counter = {
template: '<div>0</div>'
}
var vm = new Vue({
el: '#app',
components: {
counter: counter
}
})
</script>
</body>
父组件通过属性的形式向子组件传递数据
<body>
<div id="app">
<counter :count="0"></counter>
<counter :count="1"></counter>
</div>
<script>
var counter = {
props: ['count'],
template: '<div>{{count}}</div>'
}
var vm = new Vue({
el: '#app',
components: {
counter: counter
}
})
</script>
</body>
我现在想做这么一个效果,就是点击后自加1
<body>
<div id="app">
<counter :count="0"></counter>
<counter :count="1"></counter>
</div>
<script>
var counter = {
props: ['count'],
template: '<div @click="hand">{{count}}</div>',
methods: {
hand: function () {
this.count++
}
},
}
var vm = new Vue({
el: '#app',
components: {
counter: counter
}
})
</script>
</body>
这样可以实现,但是这样是不被允许的 这是一个在Vue里面被称作单项数据流的东西,就是,我们只能用父组件传递过来的值,而不能去修改它
所以我们采用这种方式,组件中的this,永远指向自身。即便是父组件传递过来的数据,vue底层也帮你都转到自组件的属性上去了。 那我们,子组件向父组件传值呢:自定义事件
<body>
<div id="app">
<counter :count="3" @inc="handleIncrease"></counter>
<counter :count="2" @inc="handleIncrease"></counter>
<div>{{total}}</div>
</div>
<script>
var counter = {
props: ['count'],
data() {
return {
number: this.count
}
},
template: '<div @click="hand">{{number}}</div>',
methods: {
hand: function () {
this.number = this.number + 2
this.$emit('inc', 2)
}
},
}
var vm = new Vue({
el: '#app',
data: {
total: 5
},
components: {
counter: counter
},
methods: {
handleIncrease: function (step) {
this.total += step
}
}
})
</script>
</body>
组件参数校验与非props特性
<body>
<div id="app">
<child content="hello world"></child>
</div>
<script>
Vue.component('child', {
props: ['content'],
template: '<div>{{content}}</div>'
})
var vm = new Vue({
el: '#app',
})
</script>
</body>
这是一段正常的父传值给子的代码,我们现在有一个需求,子在接受父的数据的时候,我们想对其进行约束,我们应该怎么去做呢 比如,我们只接受字符串 那我们的需求是,字符串或者数字呢 那么什么是非props特性,就是子组件没人接收数据
给组件绑定原生事件
<body>
<div id="app">
<child @click="hand"></child>
</div>
<script>
Vue.component('child', {
template: '<div>Child</div>'
})
var vm = new Vue({
el: '#app',
methods: {
hand: function () {
alert('Jin?Lin')
}
},
})
</script>
</body>
我们发现它是无法生效的 这样才属于我们绑定了原生的事件,可以触发 那如果我想要触发自定义的事件呢 那如果我们不想这么写,我们可以用一个native修饰符
<body>
<div id="app">
<child @click.native="hand"></child>
</div>
<script>
Vue.component('child', {
template: '<div>Child</div>',
})
var vm = new Vue({
el: '#app',
methods: {
hand: function () {
alert('Jin?Lin')
}
},
})
</script>
</body>
也可以达到效果
非父子组件间的传值
我们知道组件的拆分,积类似于原生的div
我们知道了父子组件之间的传递,但是如果我们不是父子之间的传递呢,比如兄弟之间的传值,隔辈之间的传值呢 我们的确可以通过父子传值的方式,一直反复下去,可以达到效果,但是这样太费劲了 那么怎么做到简单的方式呢?
vuex和总线的机制(发布订阅模式、观察者模式)
vuex在后面单说,这里先介绍总线
<body>
<div id="app">
<child content="Jin"></child>
<child content="Lin"></child>
</div>
<script>
Vue.prototype.bus = new Vue()
Vue.component('child', {
props: {
content: String
},
template: '<div @click="hand">{{content}}</div>',
methods: {
hand: function () {
this.bus.$emit('change', this.content)
}
},
mounted: function () {
var this_ = this
this.bus.$on('change', function (msg) {
this_.content = msg
})
}
})
var vm = new Vue({
el: '#app',
})
</script>
</body>
但是我们之前说过了,我们Vue有单向数据流,不能直接修改根组件传过来的值 所以要进行改进 这样就没问题了
在Vue中使用插槽
<body>
<div id="app">
<child></child>
</div>
<script>
Vue.component('child', {
template: '<div><p>hello</p></div>',
})
var vm = new Vue({
el: '#app',
})
</script>
</body>
这是一段正常的代码,相信大家到这里,是没什么问题了 页面显示如下 现在,我们对代码进行更改 我们发现页面出现了一些问题,我们发现父组件传过来的p标签被转义了,那么我们不想让它转义怎么办 我们进行如下的改进就可以了 所以,显然这么写是有问题的 同时,如果用这种方法传的值过多的话,代码就不好看了 这样,我们就需要一个新概念了:插槽(这里是默认插槽)
<body>
<div id="app">
<child>
<p>Lin</p>
</child>
</div>
<script>
Vue.component('child', {
props: ['content'],
template: `<div>
<p>Jin</p>
<slot></slot>
</div>`,
})
var vm = new Vue({
el: '#app',
})
</script>
</body>
也就是说,通过插槽,我们可以更方便地向自组件传递DOM元素 同时,slot还可以设置默认值
我们现在看这段代码
这是它的页面效果 那么,我现在不想要这个效果呢,想一一对应着来呢 这就需要具名插槽了
<body>
<div id="app">
<child>
<div class="header" slot="header">header</div>
<div class="footer" slot="footer">footer</div>
</child>
</div>
<script>
Vue.component('child', {
template: `<div>
<slot name="header"></slot>
<slot name="footer"></slot>
</div>`,
})
var vm = new Vue({
el: '#app',
})
</script>
</body>
这样就OK了 这样的好处是,如果我们插入多个DOM结构 具名插槽也可以有默认值,这里不演示了
|