1. 生命周期
1.1 生命周期图
1.2 生命周期函数
钩子函数 | 描述 |
---|
beforeCreate | 创建Vue实例之前调用(没有任何的数据) | created | 创建Vue实例成功后调用(可以在此处发送异步请求后端数据) | beforeMount | 渲染DOM之前调用 | mounted | 渲染DOM之后调用 | beforeUpdate | 重新渲染之前调用(数据更新等操作时,控制DOM重新渲染) | updated | 重新渲染完成之后调用 | beforeDestroy | 销毁之前调用 | destroyed | 销毁之后调用 |
created: 向后端发请求拿数据,发送ajax请求
mounted: 定时任务, 延迟任务
beforeDestroy: 定时任务关闭, 销毁一些操作
1.3 创建/挂载/更新
create创建: 定义一个对象或组件.
var app = new Vue({
el: '',
data: {name: 'kid'},
methods: { func(){} }
})
组件定义的变量, 方法只能给自己的模板使用.
Vue.component('组件名', {
template:`
<div>
{{ name }}
</div>`,
data(){
return {
name: 'kid'
}
},
methods: {
func(){}
}
})
mount挂载: 将Vue或组件放置到页面, 让页面能够使用.
<div id='app'> xxx </div>
var app = new Vue({
el: 'app',
...
}
<组件名></组件名>
Vue.component('组件名', ...)
update更新: 更新数据会重新渲染, (并不是所有的数据改变都会重新渲染!!!)
1.4 钩子函数测试
Vue对象没法看见效果过程, 定义一个组件来测试.
钩子函数与参数同级.
console.group()分组展示
console.groupEnd() 结束分组
this.属性 查看当前对象data属性中定义属性值.
this.$属性, 查看当前对象的属性,
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Vue生命周期</title>
<script src="js/vue.js"></script>
</head>
<body>
<div id="app">
<button @click="headerClick">组件(添加/删除)</button>
<model1 v-if="is_show">展示组件</model1>
</div>
</body>
<script>
var vm = new Vue({
el: '#app',
data: {
is_show: false,
},
methods: {
headerClick() {
this.is_show = !this.is_show
}
}
})
Vue.component('model1',
{
template: `
<div>
<p>我的名字: {{ name }}</p>
<p>
<button @click="vary">点击修改名字</button>
</p>
</div>
`,
data() {
return {
name: 'kid'
}
},
methods: {
vary() {
this.name = 'qq'
},
},
beforeCreate() {
console.group('当前状态:beforeCreate')
console.log('当前el状态:', this.$el)
console.log('当前data状态:', this.$data)
console.log('当前name状态:', this.name)
console.groupEnd()
},
created() {
console.group('当前状态:created')
console.log('当前el状态:', this.$el)
console.log('当前data状态:', this.$data)
console.log('当前name状态:', this.name)
console.groupEnd()
},
beforeMount() {
console.group('当前状态:beforeMount')
console.log('当前el状态:', this.$el)
console.log('当前data状态:', this.$data)
console.log('当前name状态:', this.name)
console.groupEnd()
},
mounted() {
console.group('当前状态:mounted')
console.log('当前el状态:', this.$el)
console.log('当前data状态:', this.$data)
console.log('当前name状态:', this.name)
console.groupEnd()
},
beforeUpdate() {
console.group('当前状态:beforeUpdate')
console.log('当前el状态:', this.$el)
console.log('当前data状态:', this.$data)
console.log('当前name状态:', this.name)
console.groupEnd()
},
updated() {
console.group('当前状态:updated')
console.log('当前el状态:', this.$el)
console.log('当前data状态:', this.$data)
console.log('当前name状态:', this.name)
console.groupEnd()
},
beforeDestroy() {
console.group('当前状态:beforeDestroy')
console.log('当前el状态:', this.$el)
console.log('当前data状态:', this.$data)
console.log('当前name状态:', this.name)
console.groupEnd()
},
destroyed() {
console.group('当前状态:destroyed')
console.log('当前el状态:', this.$el)
console.log('当前data状态:', this.$data)
console.log('当前name状态:', this.name)
console.groupEnd()
},
}
)
</script>
</html>
添加组件展示:
组件数据更新:
没建任务, 没有任务销毁, 看不到实际的效果.
1.5 创建任务销毁任务
1. mounted钩子函数中创建任务
2. beforeDestroy钩子函数重销毁创建的任务
setInterval: 定时执行,每秒钟打印一下信息.
组件销毁, 清理定时器
clearInterval(this.f)
this.f = null
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Vue生命周期</title>
<script src="js/vue.js"></script>
</head>
<body>
<div id="app">
<button @click="headerClick">组件(添加/删除)</button>
<model1 v-if="is_show">展示组件</model1>
</div>
</body>
<script>
var vm = new Vue({
el: '#app',
data: {
is_show: false,
},
methods: {
headerClick() {
this.is_show = !this.is_show
}
}
})
Vue.component('model1',
{
template: `
<div>{{text}}</div>
`,
data() {
return {
func: null,
text: '打印信息中'
}
},
mounted() {
this.func = setInterval(()=>{
console.log('hello word!')
}, 1000)
},
beforeDestroy() {
clearInterval(this.func)
this.func = null
},
}
)
</script>
</html>
2. Vue与后端交互
在页面渲染之前, created钩子函数向后端发送请求, 获取数据, 再将data的自定义对象的属性值修改.
方式一: jquery的ajax方法发送请求(基本不用了)
方式二: js官方提供的fetch方法(XMLHttpRequest)(官方的, 用的也少)
方式三: axios第三方, 做ajax请求(目录使用较多)
2.1 后端服务
* 1. 安装flask
pip install flask
* 2. 创建一个flask项目
from flask import Flask, make_response, jsonify
app = Flask(__name__)
@app.route('/')
def index():
obj = make_response(jsonify({'name': 'kid', 'age': 18}))
obj.headers['Access-Control-Allow-Origin'] = '*'
return obj
if __name__ == '__main__':
app.run()
2.2 ajax
在钩子函数created中发送jquery的ajax请求获取数据, 之后修改data的属性值.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Vue与后端交互</title>
<script src="js/vue.js"></script>
<script src="js/jquery-3.6.0.min.js"></script>
</head>
<body>
<div id="app">
<p>我的名字:{{name}}</p>
<p>我的年龄:{{age}}</p>
</div>
</body>
<script>
var vm = new Vue({
el: '#app',
data: {
name: '',
age: ''
},
created() {
$.ajax({
url: 'http://127.0.0.1:5000',
type: 'get',
success: args => {
this.name = args.name
this.age = args.age
}
})
}
})
</script>
</html>
先开启flask服务
打开页面
2.3 fetch
在钩子函数created中发送js原生的fetch请求获取数据, 之后修改data的属性值.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Vue与后端交互</title>
<script src="js/vue.js"></script>
<script src="js/jquery-3.6.0.min.js"></script>
</head>
<body>
<div id="app">
<p>我的名字:{{name}}</p>
<p>我的年龄:{{age}}</p>
</div>
</body>
<script>
var vm = new Vue({
el: '#app',
data: {
name: '',
age: ''
},
created() {
fetch('http://127.0.0.1:5000/').then(res => res.json()).then(res => {
console.log(res)
this.name = res.name
this.age = res.age
})
}
})
</script>
</html>
2.4 axios
在钩子函数created中发送ajax请求获取数据, 之后修改data的属性值.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Vue与后端交互</title>
<script src="js/vue.js"></script>
<script src="js/jquery-3.6.0.min.js"></script>
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
</head>
<body>
<div id="app">
<p>我的名字:{{name}}</p>
<p>我的年龄:{{age}}</p>
</div>
</body>
<script>
var vm = new Vue({
el: '#app',
data: {
name: '',
age: ''
},
created() {
axios.get('http://127.0.0.1:5000').then(data => {
console.log(data.data)
this.name = data.data.name
this.age = data.data.age
})
}
})
</script>
</html>
2.5 练习
获取一些电影的数据
地址: https://m.maizuo.com/v5/?co=mzmovie#/city
获取服务器返回的给页面的数据.
将数据复制到项目的Movie.json文件中
from flask import Flask, make_response, jsonify
app = Flask(__name__)
@app.route('/films')
def films():
import json
with open('./Movie.json', mode='r', encoding='utf-8') as f:
res = json.load(f)
obj = make_response(jsonify(res))
obj.headers['Access-Control-Allow-Origin'] = '*'
return obj
if __name__ == '__main__':
app.run()
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Vue与后端交互</title>
<script src="js/vue.js"></script>
<script src="js/jquery-3.6.0.min.js"></script>
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
</head>
<body>
<div id="app">
<h1>电影列表</h1>
<ul>
<li v-for="obj in movie">
<p>电影名称: {{obj.name}}</p>
<img :src="obj.poster" alt="" height="100px">
<p>介绍:{{obj.synopsis}}</p>
<hr>
</li>
</ul>
</div>
</body>
<script>
var vm = new Vue({
el: '#app',
data: {
movie: '',
},
created() {
axios.get('http://127.0.0.1:5000/films').then(data => {
console.log(data.data.data.films)
this.movie = data.data.data.films
})
}
})
</script>
</html>
3. 计算属性
3.1 引入1
实现名字首字母大写
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>计算属性</title>
<script src="js/vue.js"></script>
</head>
<body>
<div id="app">
输入英文: <input type="text" v-model="text"> -->
{{text.substring(0, 1).toUpperCase() + text.substring(1)}}
</div>
</body>
<script>
var vm = new Vue({
el: '#app',
data: {
text: '',
},
})
</script>
</html>
不推荐在插值中写过长的代码, 将代码打包到methods的函数中.
3.2 引入2
实现名字首字母大写
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>计算属性</title>
<script src="js/vue.js"></script>
</head>
<body>
<div id="app">
输入英文: <input type="text" v-model="text"> -->
{{Capitalize()}}
</div>
</body>
<script>
var vm = new Vue({
el: '#app',
data: {
text: '',
},
methods: {
Capitalize() {
console.log('Capitalize函数被触发')
return this.text.substring(0, 1).toUpperCase() + this.text.substring(1)
}
}
})
</script>
</html>
3.3 引入3
写一个input框, 使用v-model双向绑定一个数据.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>计算属性</title>
<script src="js/vue.js"></script>
</head>
<body>
<div id="app">
<p>
输入英文: <input type="text" v-model="text"> -->
{{Capitalize()}}
</p>
<p>
输入英文(没有绑定函数): <input type="text" v-model="text2"> --> {{text2}}
</p>
</div>
</body>
<script>
var vm = new Vue({
el: '#app',
data: {
text: '',
text2: '',
},
methods: {
Capitalize() {
console.log('Capitalize函数被触发')
return this.text.substring(0, 1).toUpperCase() + this.text.substring(1)
}
}
})
</script>
</html>
页面中只要数据发生变化了, 在 methods 中定义的函数, 也会重新触发. 这样就会消耗不必要的资源.
3.4 计算属性
computed-->把方法变成属性-->延缓计算
在页面中直接使用函数, 页面只要刷新, 函数就会重新运行,使用计算属性
只有当前函数使用的变量发生变化时, 才重新运算.
计算属性只有在它的相关依赖发生改变时才会重新求值.
计算属性在computed中定义, 写法与函数一样. 调用不需要加().
函数需要返回一个值, 这个值就是属性的值, 调用数据时展示.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>计算属性</title>
<script src="js/vue.js"></script>
</head>
<body>
<div id="app">
<p>
输入英文: <input type="text" v-model="text"> -->
{{Capitalize}}
</p>
<p>
输入框(没有绑定函数): <input type="text" v-model="text2"> --> {{text2}}
</p>
</div>
</body>
<script>
var vm = new Vue({
el: '#app',
data: {
text: '',
text2: '',
},
computed: {
Capitalize() {
console.log('Capitalize函数被触发')
return this.text.substring(0, 1).toUpperCase() + this.text.substring(1)
}
}
})
</script>
</html>
3.5 过滤案例
使用计算属性写过滤案例.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>计算属性</title>
<script src="js/vue.js"></script>
</head>
<body>
<div id="app">
<input type="text" v-model="test">
<ul>
<li v-for="i in filter_array">{{i}}</li>
</ul>
</div>
</body>
<script>
var vm = new Vue({
el: '#app',
data: {
array1: ['a', 'ab', 'abc', 'x', 'xy', 'xyz'],
test: ''
},
computed: {
filter_array() {
console.log('计算属性被触发了!')
var array2 = this.array1.filter(value => {
return value.indexOf(this.test) > -1
})
return array2
}
}
})
</script>
</html>
计算属性默认触发以, 遍历数组的值判断值中是否有'', 返回0, 0 > -1, 返回一个完整的列表.
4. 监听属性
watch: 监听属性只要监听的变量发生变化,就会执行方法.
监听一个属性, 当它的值发生变化, 触发绑定的函数.
监听属性在Vue对象的watch属性中定义.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>监听属性</title>
<script src="js/vue.js"></script>
</head>
<body>
<div id="app">
<input type="text" v-model="test"> --> {{test}}
</div>
</body>
<script>
var vm = new Vue({
el: '#app',
data: {
test: ''
},
watch: {
test: function (){
console.log('触发侦听属性')
}
}
})
</script>
</html>
5. 组件化开发
组件: 将html, css(样式), js(逻辑)封装成一个组件, 在使用的的使用可以直接调用即可.
组件只能够在Vue对象el绑定的标签中使用, 每个组件的数据都是独立的.
全局组件: 可以在任意位置中调用, 可以局部中调用全局组件.
局部组件: 只能局部使用.
5.1 全局组件
全局组件:Vue.component()
组件有自己的html,css,js,相互不影响
template 一定要放在一个标签中
data必须是函数data(){retrun {} }
全局组件定义格式:
Vue.('组件名',
{
template:``,
data:{
return {
}
},
methods: {},
})
最后定义一个vue对象.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>全局组件</title>
<script src="js/vue.js"></script>
</head>
<body>
<div id="box">
<xx1></xx1>
<xx2></xx2>
</div>
<xx1></xx1>
<script>
Vue.component('xx1',
{
template: `
<div>
<p style="size: 30px; color: aqua">全局组件</p>
<p>我的名字:{{ name }}</p>
<p>
<button @click="func">打开弹框1</button>
</p>
</div>
`,
data() {
return {
name: 'kid'
}
},
methods: {
func() {
alert('我的弹框!1')
}
}
}
)
Vue.component('xx2',
{
template: `
<div>
<p style="size: 30px; color: red">全局组件</p>
<p>我的名字:{{ name }}</p>
<p>
<button @click="func">打开弹框2</button>
</p>
</div>
`,
data() {
return {
name: 'qq'
}
},
methods: {
func() {
alert('我的弹框!2')
}
}
}
)
var vm = new Vue({
el: '#box',
data: {},
})
</script>
</body>
</html>
5.2 局部组件
局部组件: 写在组件内部 Vue.components中, 格式与全局组件一致.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>局部组件</title>
<script src="js/vue.js"></script>
</head>
<body>
<div id="box">
<xx1></xx1>
<xx2></xx2>
</div>
<script>
var vm = new Vue({
el: '#box',
data: {},
components:{
'xx1': {
template: `
<div>
<p style="size: 30px; color: aqua">全局组件</p>
<p>我的名字:{{ name }}</p>
<p>
<button @click="func">打开弹框1</button>
</p>
</div>
`,
data() {
return {
name: 'kid'
}
},
methods: {
func() {
alert('我的弹框!1')
}
}
},
'xx2': {
template: `
<div>
<p style="size: 30px; color: red">全局组件</p>
<p>我的名字:{{ name }}</p>
<p>
<button @click="func">打开弹框2</button>
</p>
</div>
`,
data() {
return {
name: 'qq'
}
},
methods: {
func() {
alert('我的弹框!2')
}
}
}
}
})
</script>
</body>
</html>
6. 组件数据传递
通过自定义属性:父传子-自定义的属性写在自定义的组件上, 自定义组件 --> props:['自定义属性名']
通过自定义事件:子传父-子中调用this.$emit('自定义事件名', 参数1, ...) -->触发写在定义组件上的
@自定义事件名='函数'--> 函数执行(父组件)
ref属性:
放在普通标签--通过this.$refs.属性值-->原生dom
放在组件上--通过this.$refs.属性值--> 当前组价对象--> 拿到组件中的值, 执行组件中的方法
6.1 父组件传值给子组件
父组件传值给子组件
1.1 在父组件的data中定义数据
1.2 使用子组件, 为子组定义一个自定义属性, 使用属性赋值的方式将父组件变量赋值自定义属性.
1.3 为子组件中的props属性定义一个数组, 组件中以字符串形式存放上面接收变量的自定义属性名.
1.4 在子组件中便可以通过插值语法, 属性赋值语法调用自定义属性, 得到父组件传递的值.
一次传递一个, 创建多个就把值封装成一个对象.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>数据传递</title>
<script src="js/vue.js"></script>
</head>
<body>
<div id="box">
<p>父组件: <input type="text" v-model="text"> --> {{text}}</p>
<xx1 :my_text="text"></xx1>
</div>
<script>
Vue.component('xx1',
{
template: `
<div>
<p style="size: 30px; color: aqua">子组件:{{ my_text }}</p>
</div>
`,
props: ['my_text']
}
)
var vm = new Vue({
el: '#box',
data: {
text: ''
},
})
</script>
</body>
</html>
6.2 子组件传值给父组件
子组件传值给父组件
1.1 子组件中, 使用v-model对数据进行双向绑定, 在设置一个提交按钮
1.2 为按键绑定一个点击事件, 在点击事件中使用 this.$emit('事件名', 参数1..)触发父组件的事件
1.3 使用子组件, 为子组件标签定义一个自定义事件并绑定一个父组件的方法.
1.4 在父组件中使用的参数及是子组件的数据, 通过该数据改变父组件的数据.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>数据传递</title>
<script src="js/vue.js"></script>
</head>
<body>
<div id="box">
<xx1 @transfer="update_text"></xx1>
<hr>
<p>父组件</p>
<p>接收的值:{{text}}</p>
</div>
<script>
Vue.component('xx1',
{
template: `
<div>
<p>子组件</p>
<p><input type="text" v-model="text"> --> {{ text }}</p>
<p>
<button @click="text_submit">提交数据给父组件</button>
</p>
</div>
`,
data() {
return {
text: ''
}
},
methods: {
text_submit() {
this.$emit('transfer', this.text)
}
}
}
)
var vm = new Vue({
el: '#box',
data: {
text: '',
},
methods: {
update_text(text) {
this.text = text
}
}
})
</script>
</body>
</html>
6.3 ref属性
1. 在标签中定义ref属性, 该属性是Vue提供的. ref='键'
2. 在定义之后, 该标签被打包成一个对象的值. ref='键: 标签对象{属性: 值, ..}'
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>ref属性</title>
<script src="js/vue.js"></script>
</head>
<body>
<div id="box">
<input type="text" ref="my_input" value="123">
<button @click="button_c">按键</button>
</div>
<script>
var vm = new Vue({
el: '#box',
methods: {
button_c() {
console.log(this.$refs)
console.log(this.$refs.my_input)
console.log(this.$refs.my_input.value)
}
}
})
</script>
</body>
</html>
input中存放了所有的属性, 默认展示标签中定义的属性与值.
6.4 ref数据传递
ref定义在子组件中, 那个就可以拿到整个子组件对象. 相当于父组打开了一条通往子组件通道.
子组件没打打开父组件的通道.拿不到Vue对象.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>ref属性</title>
<script src="js/vue.js"></script>
</head>
<body>
<div id="box">
<Subassembly ref="my_subassembly"></Subassembly>
<hr>
<button @click="button_c">按键</button>
</div>
<script>
Vue.component('Subassembly', {
template: `
<p>子组件展示的信息:{{ text }}</p>
`,
data() {
return {
text: '子组件'
}
},
methods: {
print_text() {
console.log('子组件的方法!')
}
}
}
)
var vm = new Vue({
el: '#box',
methods: {
button_c() {
let my_subassembly = this.$refs.my_subassembly
console.log(my_subassembly)
my_subassembly.text = '你好啊'
my_subassembly.print_text()
}
}
})
</script>
</body>
</html>
6.4 $on的使用
$on用于监听当前实例对象的自定义事件, 事件可以由vm.$emit触发.
vm.$emit('事件名', 参数1, ...)
$on('事件名', 函数(参数1, ...))
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="js/vue.js"></script>
</head>
<body>
<div id="box">
<module1></module1>
<module2></module2>
</div>
</body>
<script>
var bus = new Vue()
Vue.component('module1',
{template:`<div>发送信息:<input type="text" v-model="text"> <button @click="Click1">提交</button></div>`,
data(){ return {text: ''}},
methods:{Click1(){bus.$emit('submit', this.text)}}
})
Vue.component('module2',{
template: `<div>接收信息:{{text}}</div>`,
data(){return{ text: ''}},
mounted(){bus.$on('submit', (args)=>{this.text = args})}
})
var vm = new Vue({
el: '#box',
})
</script>
</html>
7. 动态组件
多个组件切换, 通过动态组件的:is来决定显示哪个组件
1. 定义对个组件
2. component标签中 :is的值是那个组件就会展示那个组件.
<component :is="sho"></component>
3. 通过动态改变sho的值切换使用的组件
menu_Zh = {
'home':
'主页', 'order':
'订单', 'commodity':
'商品'
}
for (i in menu_Zh) {
console.log(i, typeof i)
console.log(menu_Zh.i)
console.log(menu_Zh[i])
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>动态组件</title>
<script src="js/vue.js"></script>
</head>
<body>
<div id="box">
<ul>
<li style=" list-style-type:none; display:inline;" v-for="i in menu_list"
@click="ClickA(i)"> {{menu_Zh[i]}}
</li>
</ul>
<component :is="sho"></component>
</div>
<script>
Vue.component('home', {
template: `
<div style="height: 400px; width: 800px; background-color: aqua">
<p>首页内容</p>
</div>
`
})
Vue.component('order', {
template: `
<div style="height: 400px; width: 800px; background-color: fuchsia">
<p>订单内容</p>
</div>
`
})
Vue.component('commodity', {
template: `
<div style="height: 400px; width: 800px; background-color: orange">
<p>商品内容</p>
</div>
`
})
var vm = new Vue({
el: '#box',
data: {
menu_list: ['home', 'order', 'commodity'],
menu_Zh: {'home': '主页', 'order': '订单', 'commodity': '商品'},
sho: 'home'
},
methods: {
ClickA(i) {
this.sho = i
}
}
})
</script>
</body>
</html>
8. keep-alive
keep-alive: 组件切换的时候数据不销毁.
在页面切换的时候, 之前页面中输入的信息不会被保存.
使用keep-alive标签, 包裹需要要保留信息的标签, 输入的值再切换页面会被保留.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>ref属性</title>
<script src="js/vue.js"></script>
</head>
<body>
<div id="box">
<ul>
<li style=" list-style-type:none; display:inline;" v-for="i in menu_list"
@click="ClickA(i)"> {{menu_Zh[i]}}
</li>
</ul>
<keep-alive>
<component :is="sho"></component>
</keep-alive>
</div>
<script>
Vue.component('home', {
template: `
<div style="height: 400px; width: 800px; background-color: aqua">
<p>首页内容</p>
<input type="text" style="margin-left: 30px ">
</div>
`
})
Vue.component('order', {
template: `
<div style="height: 400px; width: 800px; background-color: fuchsia">
<p>订单内容</p>
</div>
`
})
Vue.component('commodity', {
template: `
<div style="height: 400px; width: 800px; background-color: orange">
<p>商品内容</p>
</div>
`
})
var vm = new Vue({
el: '#box',
data: {
menu_list: ['home', 'order', 'commodity'],
menu_Zh: {'home': '主页', 'order': '订单', 'commodity': '商品'},
sho: 'home'
},
methods: {
ClickA(i) {
this.sho = i
}
}
})
</script>
</body>
</html>
9. 插槽
<组件>写内容</组件> --> 内容无效
组件中定义插槽 --> 内容替换到插槽中
具名插槽 --> 给插槽起名字--> 使用的时候, 指定替换哪个插槽的内容
9.1 插槽的使用
自定义的组件在使用的时候, 标签中写内容是没有作用的.
插槽: 在组件的模板中是定义<slot>插槽标签, 使用组件标签中时写的内容会替换<slot>标签.
插槽的位置很重要, 依据插槽的位置替换内容.
<xxx 子组件>
<xx></xx>
</xxx 子组件>
组件模板中
`
<slot> </slot>
`
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>插槽</title>
<script src="js/vue.js"></script>
</head>
<body>
<div id="box">
<Subassembly>
<p>账户: <input type="text"></p>
<p>密码: <input type="text"></p>
</Subassembly>
</div>
<script>
Vue.component('Subassembly', {
template: `
<div>
<h1>子组件</h1>
<slot></slot>
</div>
`
})
var vm = new Vue({
el: '#box',
})
</script>
</body>
</html>
9.2 具名插槽
在子组件的模板中可以定义多个插槽, 为了区分使用, 可以为插槽起名字.
在使用子组件标签的使用, 内容指定使用的插槽.
<xxx 子组件>
<xx slot='指定名称'></xx>
</xxx 子组件>
组件模板中
`
<slot name='起名字'> </slot>
`
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>插槽</title>
<script src="js/vue.js"></script>
</head>
<body>
<div id="box">
<Subassembly>
<div slot="a">
<p>账户: <input type="text"></p>
</div>
<div slot="b">
<p>密码: <input type="text"></p>
</div>
</Subassembly>
</div>
<script>
Vue.component('Subassembly', {
template: `
<div>
<slot name="a"></slot>
<h1>子组件</h1>
<slot name="b"></slot>
</div>
`
})
var vm = new Vue({
el: '#box',
})
</script>
</body>
</html>
|