vue基础语法
1、插值语法
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>插值语法</title>
<script src="../vu/js/vue.js"></script>
</head>
<body>
<!--插值语法示例-->
<div id="insertValue">
<p>插值语法</p>
<hr>
<p>{{str}}</p>
<p>这是一个数字插值: {{num}}</p>
<p>这是一个数组插值语法根据索引取值:{{arr[0]}}</p>
<p>这是一个对象插值:{{obj.c}}</p>
</div>
</body>
<script>
var insertValue = new Vue({
el: "#insertValue", // /根据id找到div,这个div就是被vue托管
data: {
str: "这是一个插值字符串",
num: 10,
arr: ['A', 'B', 'C'],
obj: {c: 100, d: 200},
}
})
</script>
</html>
2、v-html和v-text示例
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>v-html和v-text</title>
<script src="../vu/js/vue.js"></script>
<style>
.box1{
width: 150px;
height: 150px;
background-color: red;
text-align: center;
line-height: 150px;
}
.box2{
width: 200px;
height: 200px;
background-color: blue;
text-align: center;
line-height: 200px;
}
</style>
</head>
<body>
<!--v-html和v-text示例-->
<div id="htmlText">
<hr>
<p>文本指令</p>
<hr>
<!--将v-html:htmlText功能里面的data html变量里面的input渲染成html标签语法-->
<h3>v-html指令</h3>
<p v-html="html"></p>
<h3>v-text指令</h3>
<!-- v-text渲染成字符串, 如果p标签里面有内容v-text会把<p>测试</p>内容替换-->
<p v-text="content">这是老而v-text</p>
<hr>
<h3>v-show和v-if指令</h3>
<!-- v-show:如果是false 对内容或设置的样式不进行显示,但是标签存在,会将标签样式设置为display: none -->
<!-- v-if:如果是false 对内容或设置的样式不进行显示,但是标签不存在(注:删除和添加标签,效率低) -->
<div class="box1" v-show="b1">v-show-class-box1</div>
<p>v-if指令</p>
<div class="box2" v-if="b2">v-show-class-box2</div>
</div>
</body>
<script>
var htmlText = new Vue({
el: "#htmlText",
data: {
html: '<input type="text">',
content: '新的v-text指令',
b1: false,
b2: true,
}
})
</script>
</html>
3、点击事件on-click和v-bind
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>on-click和v-bind</title>
<script src="../vu/js/vue.js"></script>
</head>
<body>
<!--点击事件on-click(注:@click)和v-bind示例-->
<div id="onBind">
<hr>
<h3>这个是v-on:</h3>
<button v-on:click="handledClick">点击显示alert</button>
<!--v-on:click="handledClick" 可以写 @click="handledClick"-->
<button @click="handledClick">点击</button>
<hr>
<h3>v-bind</h3>
<img v-bind:src="url" alt="">
<hr>
<h3>结合点击事件click和bind图片进行切换</h3>
<img v-bind:src="url" alt="" @click="imgClick">
</div>
</body>
<script>
var onBind = new Vue({
el: "#onBind",
data:{
url: 'http://gips2.baidu.com/it/u=195724436,3554684702&fm=3028&app=3028&f=JPEG&fmt=auto?w=1280&h=960',
url_list: [
"http://gips0.baidu.com/it/u=2298867753,3464105574&fm=3028&app=3028&f=JPEG&fmt=auto?w=960&h=1280",
"http://gips1.baidu.com/it/u=1410005327,4082018016&fm=3028&app=3028&f=JPEG&fmt=auto?w=960&h=1280",
"http://gips2.baidu.com/it/u=1192674964,3939660937&fm=3028&app=3028&f=JPEG&fmt=auto?w=1280&h=960",
]
},
methods:{
handledClick(){
alert("这个是点击显示alert内容")
},
imgClick(){
this.url=this.url_list[Math.floor(Math.random()*3)]
}
}
})
</script>
</html>
4、style和class指令绑定css样式
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>style和class指令绑定css样式</title>
<script src="../vu/js/vue.js"></script>
<style>
.font{
font-size: 20px;
}
.back{
background-color: orange;
}
.color{
color: blue;
}
</style>
</head>
<body>
<h3>style和class指令绑定css样式示例</h3>
<div id="styleClass">
<hr>
<div>
<h3>:class指定绑定css样式</h3>
<p :class="fontSize">字符绑定class指令 css类class字体大小</p>
<p :class="arrClass">数组绑定class指令,css类class 字体大小,字体颜色,背景色</p>
<p :class="objClass">对象绑定class指令,css类class 字体大小,字体颜色</p>
</div>
<hr>
<div>
<h3>:style指定绑定style属性css样式</h3>
<p :style="styleStr">字符串绑定style指定实现style属性css样式字体大小,字体颜色</p>
<p :style="styleList">数组绑定style指令实现style属性css样式字体颜色,背景色</p>
<p :style="styleObj">数组绑定style指令实现style属性css样式字体颜色,字体大小,背景色</p>
</div>
</div>
</body>
<script>
var styleClass = new Vue({
el: '#styleClass',
data: {
// 1-1 class指令绑定css样式
// 字符串方式
fontSize: '',
// 推荐使用数据组进行css class类样式设置
arrClass: ['font', 'color', 'back'],
// 对象方式绑定class类样式。注:font, color, back代表css样式类,true代表使用此类,false代表不使用
objClass: {
font: true,
color: true,
back: false,
},
// style指定字符串模式绑定style属性实现css样式
styleStr: "font-size: 30px; color: red",
// 数组方式
styleList: [{color: "green"}, {backgroundColor: "red"}],
// 对象方式, 推荐使用对象方式进行style样式设置
styleObj: {
color: "red",
backgroundColor: "green",
fontSize: "35px",
}
}
})
</script>
</html>
5、v-if和v-for渲染
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>v-if和v-for渲染</title>
<script src="../vu/js/vue.js"></script>
</head>
<body>
<h3>v-if条件渲染和v-for循环渲染</h3>
<div id="forIf">
<div>
<h5>条件判断显示正确而数据渲染</h5>
<!--v-if:代码开始的if判断, 代表的else if或elif判断 v-else:else判断-->
<!--根据条件判断正确的显示-->
<p v-if="score >= 90">优秀</p>
<p v-else-if="score > 70 && score < 90">良好</p>
<p v-else-if="score > 60 && score < 70">及格</p>
<p v-else>差</p>
</div>
<h5>v-for循显示数据</h5>
<div>
<p>循环列表显示数据</p>
<ul>
<li v-for="item in list">{{item}}</li>
</ul>
<p>循环列表数据值和索引号</p>
<ul>
<!--item代表获取数据值 index代表的索引,索引从0开始(注: 位置不能换,第一个只能是值,第二个索引-->
<li v-for="(item, index) in list">{{index}}: {{item}}</li>
</ul>
<p>循环对象获取key和值</p>
<ul>
<!-- v-for循环对象value:代表获取对象的值,key:代表获取对象的key-->
<li v-for="(value, key) in obj">{{key}}: {{value}}</li>
</ul>
<ul>
<!--v-for循环对象单独变量获取对象是值-->
<li v-for="value in obj">{{value}}</li>
</ul>
</div>
</div>
</body>
<script>
var forIf = new Vue({
el: "#forIf",
data: {
score: 65,
list: ['A', 'B', 'C', 'D'],
obj: {
beijing: "北京",
shanghai: "上海",
shenzhen: "深圳",
}
}
})
</script>
</html>
6、v-model双向绑定
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>v-model</title>
<script src="../vu/js/vue.js"></script>
</head>
<body>
<h3>v-model双向绑定示例</h3>
<div id="model">
<!--
v-model:数据会根据变化而变化
v-model.lazy: input框内输入完后鼠标移除input框后内容才会显示
v-model.number:input框内开头是数字后面输入字母或字符,字母或字符不会取值。如果开头是字母会正常显示
v-model.trim:去除两侧空白
-->
<h5>v-model随着数据变化而变化</h5>
<p><input type="text" v-model="bind">{{bind}}</p>
<h5>v-model.lazy离开input框数据发生变化</h5>
<p><input type="text" v-model.lazy="bindLazy">{{bindLazy}}</p>
<h5>v-model.number input框中开头输入数字后面数据内容不会取值显示,如果开头字母或字符正常取值显示</h5>
<p><input type="text" v-model.number="bindNumber">{{bindNumber}}</p>
<h5>v-model.trim 去除input框输入内容两侧空白</h5>
<p><input type="text" v-model.trim="bindTrim">{{bindTrim}}</p>
</div>
</body>
<script>
var model = new Vue({
el: "#model",
data: {
bind: "",
bindLazy: "",
bindNumber: "",
bindTrim: "",
}
})
</script>
</html>
6-1、v-model表单案例
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>表单</title>
<script src="../../vu/js/vue.js"></script>
</head>
<body>
<div id="app">
<p>用户名:<input type="text" v-model="username"></p>
<p>密码:<input type="password" v-model="password"></p>
<p><input type="checkbox" v-model="isCheck">记住密码</p>
<p>
<input type="radio" value="1" v-model="gender">男
<input type="radio" value="2" v-model="gender">女
<input type="radio" value="0" v-model="gender">未知
</p>
<p>
<input type="checkbox" value="Linux" v-model="book">Linux
<input type="checkbox" value="PHP" v-model="book">PHP
<input type="checkbox" value="Go" v-model="book">Go
<input type="checkbox" value="Python" v-model="book">Python
<input type="checkbox" value="JAVA" v-model="book">JAVA
</p>
<p><input type="submit" value="提交" @click="handledSubmit"></p>
<hr>
记住密码:{{isCheck}}
<hr>
gender:{{gender}}
<hr>
book:{{book}}
</div>
</body>
<script>
new Vue({
el: "#app",
data: {
username: '',
password: '',
isCheck: false,
gender: '',
book: [],
},
methods: {
handledSubmit(){
console.log(this.username)
console.log(this.password)
console.log(this.isCheck)
console.log(this.gender)
console.log(this.book)
}
}
})
</script>
</html>
7、blur change input事件
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>blur change input事件</title>
<script src="../vu/js/vue.js"></script>
</head>
<body>
<h3>blur change input事件示例</h3>
<div id="blurChangeInput">
<p><input type="text" v-model="blur" @blur="blurClick"></p>
<p><input type="text" v-model="change" @change="changeClick"></p>
<p><input type="text" v-model="input" @input="inputClick"></p>
</div>
</body>
<script>
var blurChangeInput = new Vue({
el: "#blurChangeInput",
data: {
blur: "鼠标移开失去焦点事件",
change: "数据发生变化触发事件",
input: "输入内容触发事件",
},
methods: {
blurClick(){
console.log(this.blur)
},
changeClick(){
console.log(this.change)
},
inputClick(){
console.log(this.input)
}
}
})
</script>
</html>
8、背景颜色切换
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>背景颜色切换</title>
<script src="../vu/js/vue.js"></script>
<style>
.clsIn{
background-color: red;
text-align: center;
width: 200px;
height: 200px;
line-height: 200px;
}
.clsOut{
background-color: orange;
text-align: center;
width: 200px;
height: 200px;
line-height: 200px;
}
</style>
</head>
<body>
<h3>动态背景颜色切换</h3>
<div id="mousemove">
<!--mousemove鼠标移近发生变化,mouseout鼠标移除发生变化-->
<div :class="cls" @mousemove="seMove" @mouseout="seOut">OK</div>
</div>
</body>
<script>
var mousemove = new Vue({
el: "#mousemove",
data: {
// 绑定css 样式类,将样式类分别设置为true,false
cls: {clsIn: true, clsOut: false}
},
methods: {
seMove(){
// 鼠标移进将
this.cls.clsIn=false
this.cls.clsOut = true
},
seOut(){
this.cls.clsIn=true
this.cls.clsOut = false
}
}
})
</script>
</html>
9、事件修复符
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>事件修复符</title>
<script src="../vu/js/vue.js"></script>
</head>
<body>
<div id="clickModify">
<h1>点击子标签,父标签的事件也触发,事件冒泡</h1>
<ul @click="handledUl">
<!--@click.stop:只处理自己的事件,不再冒泡到父标签 -->
<li @click.stop="handledLi">第一次点击</li>
<li>点击触发父标签冒泡</li>
</ul>
<h1>子标签的冒泡不处理:父标签写self, 父标签只处理自己的事件,冒泡的事件不管</h1>
<!--@click.self:只处理自己的事件,子控件冒泡的事件不处理-->
<ul @click.self="handledUl">
<li @click.stop="handledLi">第一次点击</li>
<li>第二次点击</li>
</ul>
<h1>阻止a标签的跳转</h1>
<!--@click.prevent:阻止a标签的跳转-->
<a href="https://www.baidu.com" @click.prevent="handledA">点击跳转到百度</a>
<h1>只能点击1次</h1>
<!--@click.once:只能点击1次,如果需要多次点击需要刷新才可以点击-->
<button @click.once="handledBut">点击获取</button>
</div>
</body>
<script>
var clickModify = new Vue({
el: "#clickModify",
data: {},
methods:{
handledLi(){
console.log("li被点击")
},
handledUl(){
console.log("触发ul父标签冒泡")
},
handledA(){
console.log("禁止访问")
},
handledBut(){
alert("只能被点击一次,在点击需要刷新")
}
}
})
</script>
</html>
10、按键修饰符
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>按键修饰符</title>
<script src="../../vu/js/vue.js"></script>
</head>
<body>
<div id="app">
<h1>按键修饰符</h1>
<!--可以根据keyup获取相应的按键-->
<input type="text" @keyup="handledKeyUp($event)">
<br>
<!-- @keyup.enter源代码默认设置了enter回车键-->
<input type="text" @keyup.enter="handledKeyEnter($event)">
</div>
</body>
<script>
new Vue({
el: "#app",
data:{},
methods: {
handledKeyUp(event){
if (event.code === "Enter"){
console.log(event)
}
},
handledKeyEnter(event){
console.log("回车键")
}
}
})
</script>
</html>
11、vue生命周期
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>vue对象的生命周期</title>
<script src="../../vu/js/vue.js"></script>
</head>
<body>
<div id="app">
<button @click="handleShow">点击隐藏组件</button>
<home v-if="show"></home>
</div>
</body>
<script>
Vue.component("home", {
template: `
<div>
<p>这个是组件</p>
<p>{{content}}</p>
<button @click="handleClick">更新</button>
</div>
`,
data(){
return {
content: "这个是组件里面的data",
timer: "",
}
},
methods: {
handleClick(){
this.content = "组件data数据更新"
}
},
// 创建Vue实例,组件实例对象创建之前调用
beforeCreate(){
console.log("beforeCreate")
// this.$data数据和this.$el模板是:undefined
console.log("当前data状态:", this.$data) //数据
console.log("当前el状态:", this.$el) //模板
// console.log(this.$refs)
},
// 创建Vue实例成功后调用(可以在此处发送ajax请求后端数据)
// 当前函数执行时,vue实例对象已经初始化完成
// 在开发中,我们可以在这个函数中进行初始化数据相关的操作,例如:使用ajax从服务器中读取数据,并赋值给data
created(){
// 一般使用多,用于发送ajax请求。data数据好了,在发送请求,去后端拿数据
console.log("create")
// this.$data:已经有数据,this.$el: undefined
console.log("当前data状态:", this.$data) //数据
console.log("当前el状态:", this.$el) //模板
// 启动一个定时器,每隔一段执行一次
this.timer = setInterval(function () {
// 每隔3秒打印一次
console.log("hello word")
}, 3000)
// 定时器:延迟调用,执行一次
// setTimeout()
},
// 渲染DOM之前调用
// 已经把对应的vue语法的变量替换成了html内容了,但是并没有挂载到el标签的内容中
beforeMount(){
console.log("beforeMount")
console.log("当前data状态:", this.$data) //数据
console.log("当前el状态:", this.$el) //模板
},
// 渲染DOM之后调用
// vue生成的HTML内容已经挂载到了$el属性中
mounted(){
console.log("mounted")
console.log("当前data状态:", this.$data) //数据
console.log("当前el状态:", this.$el) //模板
},
// 变量更新前,data选项中的数据发生了改变,但是没有重新生成虚拟DOM,所以HTML中的变量值没有被同步
// 修改数据前,判断本次修改是否合法?发送ajax,
beforeUpdate(){
console.log("beforeUpdate")
console.log("当前data状态:", this.$data) //数据
console.log("当前el状态:", this.$el) //模板
},
// 变量更新后,html内容已经与data选项中的数据同步了,因为重新生成了虚拟DOM
// 修改数据后,发送ajax,同步数据库
updated(){
// 一般使用多,数据变化,页面更新完后,执行
console.log("updated")
console.log("当前data状态:", this.$data) //数据
console.log("当前el状态:", this.$el) //模板
},
// 销毁之前调用
beforeDestroy() {
console.log("beforeDestroy")
console.log("当前data状态:", this.$data) //数据
console.log("当前el状态:", this.$el) //模板
},
// 销毁之后调用
destroyed(){
// 组件销毁,会触发,也会使用
console.log("destroyed")
console.log("当前data状态:", this.$data) //数据
console.log("当前el状态:", this.$el) //模板
//释放定时器,(会将created 设置的定时器打印hello word释放消除)
clearInterval(this.timer)
this.timer = null
}
})
var app = new Vue({
el: "#app",
data: {
show: true,
},
methods: {
handleShow(){
this.show =! this.show
}
},
})
</script>
</html>
12、计算属性
12-1、计算属性示例1
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>计算属性</title>
<script src="../../vu/js/vue.js"></script>
</head>
<body>
<div id="app">
<input type="text" v-model="search">
<ul>
<li v-for="item in data">{{item}}</li>
</ul>
</div>
</body>
<script>
new Vue({
el: "#app",
data: {
search: '',
data_list: ["beijing", "shanghai", "shenzhen", "guangzhou", "hebei"],
},
// 只要input框数据发生变化search, data会重新运算,只要一运算,v-for重新循环,实现联动
// computed计算属性需要使用return
computed: {
data (){
return this.data_list.filter(item=>{
return item.indexOf(this.search) > -1
})
}
}
})
</script>
</html>
12-2、计算属性示例2
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>计算属性</title>
<script src="../vu/js/vue.js"></script>
</head>
<body>
<div id="app">
<input type="text" v-model.number="num1">+
<input type="text" v-model.number="num2">={{result}}
</div>
</body>
<script>
var app = new Vue({
el: "#app",
data: {
num1: 10,
num2: 20,
},
<!--所谓的计算属性,是vue提供给开发者用于编写代码时保存计算出新的数据结果的变量。主要通过computed选项进行声明的-->
computed: {
result(){
return this.num1 + this.num2
}
}
})
</script>
</html>
13、监听属性
13-1、分组向后端发送请求数据
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>监听属性</title>
<script src="../../vu/js/vue.js"></script>
</head>
<body>
<div id="app">
<!--监听属性相当于分组,添加点击事件后会选择对应内容 例如@click="group='书籍'" 会选择这里group='书籍'作为选项内容-->
<span @click="group='书籍'">书籍</span>
<span @click="group='古城'">古城</span>
<span @click="group='景色'">景色</span>
</div>
</body>
<script>
new Vue({
el: "#app",
data: {
group :'',
},
// 监听的是data里面而group,只要group watch里的函数触发
// watch一般用于向后端发送请求,请求回应相应的分类数据展示,一般对相关数据的分类或分组,减少监听事件使用
watch: {
group: function (val) {
console.log("group发生变化")
console.log(val)
}
}
})
</script>
</html>
13-2、判断用户和密码规则
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>监听属性</title>
<script src="../vu/js/vue.js"></script>
<style>
input{
outline: none;
border: 1px solid #333;
}
</style>
</head>
<body>
<div id="app">
<p><input ref="username" type="text" v-model="username" @blur="handledBlur"></p>
<p><input ref="password" type="text" v-model="password"></p>
</div>
</body>
<script>
var app = new Vue({
el: "#app",
data: {
username: '',
password: '',
},
methods: {
handledBlur() {
console.log("check_name执行")
}
},
watch: { // 侦听选项API,成员就是data变量名
// 这里的username指定是data里面设置的username变量
username(new_data, old_data){
// 侦听data中的username
console.log(`old_data=${old_data}, new_data=${new_data}`)
let length = this.username.length;
if(length>=6 && length<=16){
// 这里的username是设置的ref="username"
this.$refs.username.style.border="1px solid blue";
}else{
this.$refs.username.style.border="1px solid red";
}
},
password(new_value, old_value){ // 参数为:修改前的变量值以及修改后的变量值
if(/^\d+$/.test(this.password)){
this.$refs.password.style.border="1px solid red";
}else{
this.$refs.password.style.border="1px solid blue";
}
}
},
})
</script>
</html>
14、全局和局部
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>全局和局部组件</title>
<script src="../../vu/js/vue.js"></script>
</head>
<body>
<div id="app">
<navbar></navbar>
<com></com>
</div>
</body>
<script>
var obj = {
// 全局组件
// template这里是反引号Esc按键下面的按键上面的反引号
template: `
<div>
<h1>全局组件</h1>
<button @click="handledClick">点击获取</button>
<p>全局内容:{{book}}</p>
</div>
`,
data(){
return {
book: "水浒传"
}
},
methods: {
handledClick(){
alert("点击数据展示")
}
}
}
Vue.component('navbar', obj)
new Vue({
el: "#app",
data: {
},
// 定义局部组件,自定组件只能在div id=app中使用,不能在子组件'navbar'中模板使用
components:{
com:{
template:`
<div>
<hr>
<p>局部组件显示</p>
<p>局部内容:{{book}}</p>
</div>
`,
data(){
return {
book: "西游记"
}
},
methods: {
}
}
}
})
</script>
</html>
15、自定义父传子组件
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>组件通信父传子</title>
<script src="../../vu/js/vue.js"></script>
</head>
<body>
<h1>组件通信父传子</h1>
<div id="app">
<p>父变量city数据:{{city}}</p>
<hr>
<!--在组件中自定义属性添加父data里面的变量到自定义属性里面,在组件中使用props获取自定义属性,组件中使用自定义的属性获取父变量数据-->
<navbar :mycity="city"></navbar>
</div>
</body>
<script>
<!--"注:Vue.component('自定义标签名称'{})需要在 new Vue({})上面,如果在下面则会不显示" -->
Vue.component('navbar', {
template: `
<div>
<p>继承父变量数据内容</p>
<!--这里mycity是自定义属性获取的父变量数据-->
<p>继承父city变量数据:{{mycity}}</p>
</div>
`,
data(){
return {}
},
<!--{{mycity}}这里的mycity是定义在 navbar:里面的自定义属性 再把自定义mycity属性添加到props组列表里面进行获取-->
props: ["mycity"],
methods:{}
})
new Vue({
el: "#app",
data: {
city: "北京",
},
})
</script>
</html>
16、自定义子传父组件
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>组件通信子传父</title>
<script src="../../vu/js/vue.js"></script>
</head>
<body>
<div id="app">
<p>接受子组件传递的数据:{{accept_data}}</p>
<hr>
<!--
设定自定义触发事件,将子组件的数据传递到父组件,自定义触发事件绑定函数名称父组件会使用到
@event 设置的自定义事件名称
acceptSonData 绑定的事件触发函数名称(注:这里的名称父组件函数名称需要使用)
-->
<home @event="acceptSonData"></home>
</div>
</body>
<script>
Vue.component('home', {
template: `
<div>
<p>这个是子组件</p>
<p><input type="text" v-model="send_data"></p>
<button @click="sendClick">点击传递数据给父组件</button>
</div>
`,
data(){
return {
send_data: "",
}
},
methods: {
sendClick(){
// 触发自定义事件执行,并且传入当前子组件的send_data数据
// 将子组件数据传递到父组件,$emit是不可以改变。
// event需要跟 <home @event="acceptSonData"></home> 自定义的事件名称保持一致
// this.send_data 是传递子组件的数据
this.$emit('event', this.send_data)
}
}
})
var app = new Vue({
el: '#app',
data: {
accept_data: ''
},
methods: {
<!--
这里是绑定子组件自定义触发事件绑定的函数名称
value: 接受子组件传递的数据参数(value参数名称可以自定义)
-->
acceptSonData(value){
// 将子组件传递过来的数据赋值给this.accept_data
this.accept_data = value
}
}
})
</script>
</html>
17、ref属性实现组件通信
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>ref属性实现组件通信</title>
<script src="../../vu/js/vue.js"></script>
</head>
<body>
<div id="app">
<h1>ref属性实现组件通信</h1>
<p>获取子组件input值:{{name}}</p>
<!--放在普通标签,通过this.$refs.ref -->
<input type="text" v-model="name" ref="myref">
<button @click="handledClick">点击获取</button>
<hr>
<navbar ref="navbar"></navbar>
<!--设置子组件点击事件操作-->
<button @click="handledClickNav">点击</button>
</div>
</body>
<script>
Vue.component("navbar", {
template: `
<div>
<p>获取父组件input数据值:{{navname}}</p>
<input type="text" v-model="navname">
</div>
`,
data(){
return{
navname: "",
}
},
methods: {
handledClick(){
console.log("远程调用子组件"+this.navname)
}
}
})
new Vue({
el: "#app",
data: {
name:'',
},
methods:{
handledClick(){
// 获取了组件对象
console.log(this.$refs)
// this.$refs.ref对应的名字,拿到的原生dom对象。也就是获取的上面input标签
console.log(this.$refs.myref)
// this.$refs.myref.value这个是获取的是输入input的value值内容
console.log(this.$refs.myref.value)
// 将父组件变量值赋值给子组件里面的navname变量重
this.$refs.navbar.navname=this.name
// 调用子组件methods里面的handledClick函数
this.$refs.navbar.handledClick()
},
handledClickNav(){
// 获取到是子组件对象
console.log(this.$refs.navbar)
// 将子组件值赋值给父组件变量name
this.name=this.$refs.navbar.navname
}
}
})
</script>
</html>
18、动态组件
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>动态组件</title>
<script src="../../vu/js/vue.js"></script>
</head>
<body>
<div id="app">
<h1>动态组件</h1>
<ul>
<!--这里的home,shop, book分别是指定的自定义的组件名称-->
<li @click="myType='home'">首页</li>
<li @click="myType='shop'">商品</li>
<li @click="myType='book'">书籍</li>
</ul>
<!--动态组件,is是哪个组件名称,这里会显示哪个组件-->
<component :is="myType"></component>
</div>
</body>
<script>
Vue.component("home", {
template: `
<div>
<h2>首页</h2>
</div>
`,
})
Vue.component("shop", {
template: `
<div>
<h2>商店</h2>
</div>
`,
})
Vue.component("book", {
template: `
<div>
<h2>书籍</h2>
</div>
`,
})
new Vue({
el: "#app",
data:{
// 这里的home指的就是定义的组件名称,home组件
myType: "home",
},
})
</script>
</html>
19、keep-alive保留input框内容
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>动态组件</title>
<script src="../../vu/js/vue.js"></script>
</head>
<body>
<div id="app">
<h1>动态组件</h1>
<ul>
<li @click="myType='home'">首页</li>
<li @click="myType='shop'">商品</li>
<li @click="myType='book'">书籍</li>
</ul>
<!--keep-alive 切换页面会保留input搜索框里输入的内容-->
<keep-alive>
<!--动态组件,is是哪个组件名称,这里会显示哪个组件-->
<component :is="myType"></component>
</keep-alive>
</div>
</body>
<script>
Vue.component("home", {
template: `
<div>
<h2>首页</h2>
</div>
`,
})
Vue.component("shop", {
template: `
<div>
<h2>商店</h2>
</div>
`,
})
Vue.component("book", {
template: `
<div>
<h2>书籍</h2>
<input type="text">
</div>
`,
})
new Vue({
el: "#app",
data:{
myType: "首页",
},
})
</script>
</html>
20、插槽
20-1、无名插槽
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>不具名插槽</title>
<script src="../../vu/js/vue.js"></script>
</head>
<body>
<div id="app">
<h1>插槽页面显示</h1>
<hr>
<home>
<!--不具名插槽利用slot显示-->
<div style="width: 200px; height: 200px; background-color: red; text-align: center; line-height: 200px">
<h1>不具名插槽</h1>
</div>
</home>
<hr>
</div>
</body>
<script>
Vue.component("home", {
template: `
<div>
<h2>插入页面显示</h2>
<!--不具名插槽显示-->
<slot></slot>
</div>
`
})
new Vue({
el: "#app",
data: {},
})
</script>
</html>
20-2、有名插槽
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>有名查询</title>
<script src="../../vu/js/vue.js"></script>
</head>
<body>
<div id="app">
<navbar>
<div slot="bottom" style="width: 200px; height: 200px; background-color: orange">
<span>这是具名插槽</span>
</div>
</navbar>
</div>
</body>
<script>
Vue.component("navbar", {
template: `
<div>
<!--lot 添加name属性是具名插槽-->
<slot name="top"></slot>
<p>这是自组件</p>
<slot name="bottom"></slot>
</div>
`
})
new Vue({
el: "#app",
data: {},
})
</script>
</html>
21、小案例
21-1、购物车案例
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>购物车</title>
<link rel="stylesheet" href="https://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/3.4.1/css/bootstrap.min.css">
<script src="../../vu/js/vue.js"></script>
<style>
.container-fluid .row .table thead tr th{
text-align: center;
}
.row .table button{
text-align: center; /* 设置按钮内文本居中 */
vertical-align: middle; /* 设置按钮内文本垂直居中 */
background-color: transparent;
border: none;
}
#plus-right{
float: right;
}
#minus-left{
float: left;
}
</style>
</head>
<body>
<div id="app">
<div class="container-fluid">
<div class="row">
<div class="col-md-6 col-md-offset-3">
<table class="table table-bordered">
<thead>
<tr>
<th>商品id</th>
<th>商品名称</th>
<th>商品价格</th>
<th>商品数量</th>
<th><input type="checkbox" v-model="checkAll" @change="handledCheckAll"></th>
</tr>
</thead>
<tbody>
<tr v-for="book in shopList" class="text-center">
<td>{{book.id}}</td>
<td>{{book.name}}</td>
<td>{{book.price}}</td>
<td><button id="minus-left" @click="handledMinus(book)">-</button>{{book.count}}<button id="plus-right" @click="book.count++">+</button></td>
<td><input type="checkbox" :value="book" v-model="shopCar" @change="checkAllOne"></td>
</tr>
</tbody>
</table>
<hr>
商品购物车: {{shopCar}}
<hr>
商品总价格: {{getPrice()}}
</div>
</div>
</div>
</div>
</body>
<script>
new Vue({
el: "#app",
data: {
shopList:[
{id: "1", name: "Linux", price: 50, count: 5},
{id: "2", name: "Go", price: 55, count: 10},
{id: "3", name: "PHP", price: 30, count: 3},
{id: "4", name: "JAVA", price: 40, count: 6},
{id: "5", name: "Python", price: 35, count: 8},
{id: "6", name: "MySQL", price: 25, count: 5},
],
shopCar: [],
checkAll: false
},
methods: {
getPrice(){
var sum=0
// forEach循环计算
// this.shopCar.forEach(function (v) {
// sum+=v.count*v.price
//
// })
// 普通方式for计算
for (i=0; i<this.shopCar.length; i++){
const book = this.shopCar[i]
sum+=book.price*book.count
}
return sum
},
// 实现全部选中
handledCheckAll(){
if (this.checkAll){
this.shopCar = this.shopList
}else{
this.shopCar=[]
}
},
// 如果没有全部选中,取消全部选中图标
checkAllOne(){
this.checkAll = this.shopCar.length === this.shopList.length
},
handledMinus(num){
if (num.count <= 1){
alert("数量为"+num.count+"不能在减")
}else{
num.count--
}
}
}
})
</script>
</html>
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· winform 绘制太阳,地球,月球 运作规律
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· 写一个简单的SQL生成工具
· AI 智能体引爆开源社区「GitHub 热点速览」