vue 计算 侦听属性 局部组件和全局组件 插槽
今日内容
1 计算属性
# 插值的普通函数,只要页面一刷新,函数就会重写计算,跟函数没关的值的变化,函数也会重写计算
# 把函数当成属性来用---》只有这个函数使用的属性(变量)变化,函数才重写运算
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="./js/vue.js"></script>
</head>
<body>
<div id="app">
<input type="text" v-model="mytest2">-->{{mytest2}}
<br>
<input type="text" v-model="mytext">--->{{mytext.substring(0,1).toUpperCase()+mytext.substring(1)}}
<br>
函数方式:{{getName()}}
<br>
计算属性:{{getName2}}
</div>
</body>
<script>
var vm = new Vue({
el: '#app',
data: {
mytext: '',
mytest2: '',
},
methods:{
getName(){
console.log("我执行了")
return this.mytext.substring(0,1).toUpperCase()+this.mytext.substring(1)
}
},
// 8生命周期
computed:{
getName2(){
console.log("计算属性我执行了")
return this.mytext.substring(0,1).toUpperCase()+this.mytext.substring(1)
}
}
})
</script>
</html>
1.1 通过计算属性,重写过滤案例
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>过滤案例</title>
<script src="https://cdn.bootcdn.net/ajax/libs/vue/2.6.12/vue.min.js"></script>
</head>
<body>
<div id="box">
<p><input type="text" v-model="myText" placeholder="请输入要筛选的内容:"></p>
<ul>
<li v-for="data in newList">{{data}}</li>
</ul>
</div>
</body>
<script>
var vm = new Vue({
el: '#box',
data: {
myText: '',
dataList: ['a', 'at', 'atom', 'be', 'beyond', 'cs', 'csrf'],
},
computed:{
newList(){
console.log('我执行了')
var datalist2 = this.dataList.filter(item => {
return item.indexOf(this.myText) > -1
})
return datalist2
}
}
})
</script>
</html>
2 侦听属性
只要变量发生变化,就会执行监听属性中的方法
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="./js/vue.js"></script>
</head>
<body>
<div id="app">
<input type="text" v-model="mytext">--->{{mytext}}
</div>
</body>
<script>
var vm = new Vue({
el: '#app',
data: {
mytext: '',
},
watch: {
// 只要mytext发生变化,就会执行该函数
mytext: function () {
console.log('我变化了,执行')
}
}
})
</script>
</html>
3 局部组件和全局组件
# 扩展 HTML 元素,封装可重用的代码,目的是复用
-例如:有一个轮播,可以在很多页面中使用,一个轮播有js,css,html
-组件把js,css,html放到一起,有逻辑,有样式,有html
# 局部组件,全局组件
-
# 注意事项
1 自定义组件需要有一个root element,一般包裹在一个div中
2 父子组件的data是无法共享
3 组件可以有data,methods,computed....,但是data 必须是一个函数
3.1 局部组件
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="./js/vue.js"></script>
</head>
<body>
<div id="app">
<Top></Top>
<br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br>
<Bottom></Bottom>
</div>
</body>
<script>
var vm = new Vue({
// el data methods watch computed 8个
el: '#app',
data: {},
// 定义再这里面的叫局部组件,只能再局部使用,只能再id为app的标签内使用
components: {
'Top': {
template: `
<div>
<h1 style="background: pink;font-size: 60px;text-align: center">{{name}}</h1>
<hr>
<button @click="handleC">点我看美女</button>
</div>
`,
data() {
return {
name: "我是头部"
}
},
methods: {
handleC() {
alert('美女')
}
},
},
'Bottom': {
template: `
<div>
<hr>
<h1 style="background: green;font-size: 60px;text-align: center">{{name}}</h1>
</div>
`,
data() {
return {
name: "我是尾部"
}
},
},
},
})
</script>
</html>
3.2 全局组件
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="./js/vue.js"></script>
</head>
<body>
<div id="app">
<top></top>
</div>
</body>
<script>
// 定义全局组件--->任意位置都可以用
Vue.component('top', {
template: `
<div>
<h1 style="background: pink;font-size: 60px;text-align: center">{{name}}</h1>
<hr>
<button @click="handleC">点我看美女</button>
</div>
`,
data() {
return {
name: "我是头部"
}
},
methods: {
handleC() {
alert('美女')
}
},
},)
var vm = new Vue({
// el data methods watch computed 8个
el: '#app',
data: {},
})
</script>
</html>
4 组件通信之父传子
# 组件间data数据不同享,数据传递
-从父组件传到子组件
-自定义属性
-从子组件传到父组件
-自定义事件
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="./js/vue.js"></script>
</head>
<body>
<div id="app">
<!--通过自定义属性:myheader-->
<top :myheader="headerName"></top>
{{headerName}}
<input type="text" v-model="headerName">
</div>
</body>
<script>
// 定义全局组件--->任意位置都可以用
Vue.component('top', {
template: `
<div>
<h1 style="background: pink;font-size: 60px;text-align: center">{{myheader}}</h1>
</div>
`,
data() {
return {
name: "我是头部"
}
},
// 必须叫props,数组内放自定义属性的名字
// props:['myheader',],
// 属性验证
props:{
myheader:String, // key是自定义属性名,value是类型名,如果是别的类型就报错
},
},)
var vm = new Vue({
// el data methods watch computed 8个
el: '#app',
data: {
headerName:999
},
})
</script>
</html>
5 组件通信之子传父
# 通过自定义事件实现子传父
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="./js/vue.js"></script>
</head>
<body>
<div id="app">
<!-- 自定义了一个myevent事件 -->
<top @myevent="handelRecv"></top>
<hr>
接收到子组件的数据是:{{childText}}
</div>
</body>
<script>
// 定义全局组件--->任意位置都可以用
Vue.component('top', {
template: `
<div>
<h1 style="background: pink;font-size: 60px;text-align: center">{{myheader}}</h1>
<input type="text" v-model="text">
<button @click="handleSend">点我传出去</button>
</div>
`,
data() {
return {
myheader: "我是头部",
text: '',
}
},
methods:{
handleSend(){
// 触发绑定在该组件上的事件,myevent---》父组件中会执行事件对应的函数handelRecv--》
this.$emit('myevent',this.text)
}
}
},)
var vm = new Vue({
// el data methods watch computed 8个
el: '#app',
data: {
childText: ''
},
methods:{
handelRecv(text){
// 接收一个参数,赋值给父组件的childText
this.childText=text
}
}
})
</script>
</html>
6 ref属性(组件间通信)--》事件总线(不讲)
# ref属性,如果放在普通标签上,就是普通标签的原生html,操作,设置
# ref属性,如果放在组件上,就是当前组件对象
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="./js/vue.js"></script>
</head>
<body>
<div id="app">
<top ref="top"></top>
<input type="text" v-model="text" ref="myinput">
<img src="" alt="" ref="myimg" height="80px" width="80px">
<hr>
<button @click="handleC">点我</button>
</div>
</body>
<script>
// 定义全局组件--->任意位置都可以用
Vue.component('top', {
template: `
<div>
<h1>{{myheader}}</h1>
<button @click="handleC">点我看美女</button>
<hr>
</div>
`,
data() {
return {
myheader: "我是头部",
}
},
methods:{
handleC(){
alert("美女")
}
}
},)
var vm = new Vue({
el: '#app',
data: {
text:''
},
methods:{
handleC(){
console.log('我被点了')
//把所有有ref属性的标签 弄到 一个对象中
console.log(this.$refs) // 是所有标签写了ref属性的对象{myinput:真正的标签,myimg:真正的标签}
//111111 放在普通标签上示例
// 取到input的value值
// console.log(this.$refs.myinput.value)
// this.$refs.myinput.value='lqz is nb'
// this.$refs.myimg.src='https://tva1.sinaimg.cn/large/00831rSTly1gd1u0jw182j30u00u043b.jpg'
//222222 放在组件上示例
// console.log(this.$refs.top)
// 既然能够拿到组件对象,组件中的data中的值也可以拿到,组件中的方法也可调用
console.log(this.$refs.top.myheader) // 父组件中拿到了子组件的值
// 不区分是子传父还是父传子了
// 想子传父--》下面就是子传父
// console.log(this.$refs.top.myheader)
// this.text=this.$refs.top.myheader
// 想父传子
// this.$refs.top.myheader='刘清政 is nb'
// this.$refs.top.myheader=this.text
// 还可以调用组件的方法
this.$refs.top.handleC() //如果有参数,是不是也可以传到子组件中
}
}
})
</script>
</html>
7 动态组件和keep-alive
keep-alive:组件不销毁
component:有个is属性,指定显示的组件是哪个
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="./js/vue.js"></script>
</head>
<body>
<div id="app">
<ul>
<li @click="changeC('index')">首页</li>
<li @click="changeC('order')">订单</li>
<li @click="changeC('good')">商品</li>
</ul>
<!-- 笨办法-->
<!--<index v-if="index_show"></index>-->
<!--<order v-if="order_show"></order>-->
<!--<good v-if="good_show"></good>-->
<keep-alive>
<component :is='who'></component>
</keep-alive>
</div>
</body>
<script>
// 定义全局组件--->任意位置都可以用
Vue.component('index', {
template: `
<div>
<h1>我是首页</h1>
</div>
`,
},)
Vue.component('order', {
template: `
<div>
<h1>我是订单</h1>
请输入要查询的订单:<input type="text">
</div>
`,
},)
Vue.component('good', {
template: `
<div>
<h1>我是商品</h1>
</div>
`,
},)
var vm = new Vue({
el: '#app',
data: {
// index_show:true,
// order_show:false,
// good_show:false,
who:'index'
},
methods:{
changeC(i){
this.who=i
}
}
})
</script>
</html>
8 插槽
8.1普通插槽
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="./js/vue.js"></script>
</head>
<body>
<div id="app">
<index>
<div>
用户名:<input type="text">
密码:<input type="text">
</div>
</index>
</div>
</body>
<script>
Vue.component('index', {
template: `
<div>
<h1>我是首页</h1>
<slot></slot>
</div>
`,
},)
var vm = new Vue({
el: '#app',
data: {
},
methods:{
}
})
</script>
</html>
8.2 具名插槽
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="./js/vue.js"></script>
</head>
<body>
<div id="app">
<index>
<p slot="a">pppp</p>
<div slot="b">
div--div
</div>
</index>
</div>
</body>
<script>
Vue.component('index', {
template: `
<div>
<slot name="a"></slot>
<h1>我是首页</h1>
<slot name="b"></slot>
</div>
`,
},)
var vm = new Vue({
el: '#app',
data: {},
})
</script>
</html>
# 在这nodejs(python 解释器)---》后端语言,安装在操作系统上
-http://nodejs.cn/---》一路下一步
-node:python,解释器命令
-npm: pip命令,用来安装模块的
# vue脚手架---》vue-cli安装完
npm install -g @vue/cli # vue命令
# 等同于 pip install django---》 djangoadmin
# 创建一个vue项目
-vue create 项目名 ---》创建出一个vue项目,使用pycharm打开