前端-vue用法
vue成员获取
1.methods数据的获取
使用:$options.methods 方法获取
2.data数据的获取
使用:$data 方法获取
3.自定义属性的获取
使用:$options.自定义属性名
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
</head>
<body>
<div id="app">
<h1 @click="btnClick">{{ msg }}</h1>
<p>{{ 10 | add }}</p>
<!--获取data数据({ }形式)-->
<p>{{ $data }}</p>
<!--获取自定义数据-->
<p>{{ $options.arr }}</p>
</div>
</body>
<script src="js/vue.js"></script>
<script>
let app = new Vue({
el: '#app',
data: {
msg: '数据',
a: 1,
b: 2,
},
methods: {
btnClick() {
console.log(this.msg)
}
},
filters: {
add(v) {
return v+1
}
},
arr: [1, 2, 3, 4],
});
console.log(app.msg);
console.log(app.$data);
console.log(app.$options.methods);
console.log(app.$options.arr);
</script>
</html>
pre指令
标签内使用 v-pre 指令,可以解除vue的控制
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
</head>
<body>
<div id="app">
<p v-pre>
<!--v-pre的内部解除vue控制-->
<!--解除之后,{{}}不是插值表达式,msg不是变量,v-on不是指令,都是原义输出-->
<p>{{ msg }}</p>
<span v-on="abc"></span>
</p>
</div>
</body>
<script src="js/vue.js"></script>
<script>
new Vue({
el: '#app',
data: {
msg: "message"
}
})
</script>
</html>
循环指令
针对data数据中数组使用 v-for 方法进行循环遍历取值,然后渲染到前端页面中
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
</head>
<body>
<div id="app">
<p>{{ arr }}</p>
<p>
<span>{{ arr[0] }}</span>
<span>{{ arr[1] }}</span>
<span>{{ arr[2] }}</span>
<span>{{ arr[3] }}</span>
<span>{{ arr[4] }}</span>
</p>
<div>
<!--值 遍历-->
<p v-for="v in arr">
<span>{{ v }}</span>
</p>
</div>
<div>
<!--值,索引 遍历-->
<p v-for="(v, i) in arr">
<span>第{{ i + 1 }}个值:{{ v }}</span>
</p>
</div>
<p>{{ student }}</p>
<div>
<p v-for="(v, k, i) in student">
<span>{{ k, v, i | f1 }}</span>
</p>
</div>
<div>
<!--
name: Bob | aendge:18 | ger:男
name: Tom | age:1 | gender:男
-->
<p v-for="stu in stus">
<!--<span v-for="(v, k, i) in stu">{{i?' | ':''}}{{k}}:{{v}}</span>-->
<span v-for="(v, k, i) in stu">{{i|f2}}{{k}}:{{v}}</span>
</p>
</div>
</div>
</body>
<script src="js/vue.js"></script>
<script>
new Vue({
el: '#app',
data: {
arr: [1, 4, 2, 3, 5],
student: {
'name': 'Bob',
'age': 18,
'gender': '男'
},
stus: [
{
'name': 'Bob',
'age': 18,
'gender': '男'
},
{
'name': 'Tom',
'age': 20,
'gender': '男'
}
]
},
filters: {
f1(k, v, i) {
// return k + ":" + v + '(' + i + ')'
return `${k}:${v}(${i})`
},
f2(i) {
// i为0代表假,返回'',其它索引时返回' | '
return i ? ' | ' : ''
}
}
})
</script>
</html>
todolist案例(实现留言板功能)
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>todolist</title>
<style>
li:hover {
color: red;
cursor: pointer;
}
</style>
</head>
<body>
<div id="app">
<p>
<input type="text" v-model="info">
<button @click="add_msg">留言</button>
<ul>
<li v-for="(msg, i) in msgs" @click="del_fn(i)">{{ msg }}</li>
</ul>
</p>
</div>
</body>
<script src="js/vue.js"></script>
<script>
new Vue({
el: '#app',
data: {
info: '',
// msgs: sessionStorage.msgs && JSON.parse(sessionStorage.msgs) || [],
// sessionStorage存放数组和字典需要JSON字符串参与
msgs: JSON.parse(sessionStorage.msgs || '[]'),
},
methods: {
add_msg() {
let info = this.info;
if (info) {
// this.msgs.push(this.info); // 尾增
this.msgs.unshift(this.info); // 首增
// 清空留言框
this.info = '';
sessionStorage.msgs = JSON.stringify(this.msgs);
}
},
del_fn(i) {
// 删除选中的某条评论内容
this.msgs.splice(i, 1);
sessionStorage.msgs = JSON.stringify(this.msgs);
}
}
})
</script>
</html>
分隔符成员
delimiters 方法可以修改插值表达式符号
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
</head>
<body>
<div id="app">
{{ msg }}
[[ msg }}
${ msg }
</div>
</body>
<script src="js/vue.js"></script>
<script>
new Vue({
el: '#app',
data: {
msg: 'message'
},
// 修改插值表达式符号
delimiters: ['[[', '}}'],
// delimiters: ['${', '}'],
})
</script>
</html>
计算属性成员
computed 方法
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
</head>
<body>
<div id="app">
<p>
<input type="text" v-model="a">
<input type="text" v-model="b">
</p>
<!--报错:计算后属性为只读属性-->
<!--<input type="text" v-model="xyz">-->
<!--关键:计算后属性必须渲染后,绑定的方法才会生效-->
<p>{{ xyz }}</p>
</div>
</body>
<script src="js/vue.js"></script>
<script>
new Vue({
el: '#app',
data: {
a: '',
b: '',
// 报错:计算后属性不需要在data中重复定义
// xyz: '',
},
computed: {
// 1) 计算后属性不需要在data中重复定义
// 2) 计算后属性必须渲染后,绑定的方法才会生效
// 3) 计算后属性绑定的方法中的任意变量值更新,方法都会被调用
// 4) 计算后属性为只读属性(不可写)
xyz () {
// a值一变化,该方法就会被回调
// 原因:计算后属性绑定的方法中的任意变量值更新,方法都会被调用
console.log('该方法调用了')
// 计算两数之和a+b
return parseInt(this.a) + parseInt(this.b)? parseInt(this.a) + parseInt(this.b) : '';
}
// 使用场景:一个计算后属性的值,可以来源于多个属性值
}
})
</script>
</html>
监听属性成员
watch 方法
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
</head>
<body>
<div id="app">
<input type="text" v-model="num_a">
<p>num_a: {{ num_a }}</p>
<p>num_b: {{ num_b }}</p>
<p>num_c: {{ num_c }}</p>
</div>
</body>
<script src="js/vue.js"></script>
<script>
new Vue({
el: '#app',
data: {
num_a: '',
num_b: '',
num_c: '',
},
watch: {
// 1) 监听绑定的属性,该属性可以get、set
// 2) 监听的属性一旦发生值更新,绑定的方法就会被调用
// 3) 监听的属性是已定义的属性(必须在data中定义)
num_a() {
console.log('num_a值更新,该方法被调用');
this.num_b = this.num_a * 10;
this.num_c = this.num_a * 20;
},
}
// computed: {
// num_b() {
// return this.num_a * 10
// },
// num_c() {
// return this.num_a * 20
// },
// }
})
</script>
</html>
组件
组件介绍
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
</head>
<body>
<div id="app">
{{ msg }}
</div>
</body>
<script src="js/vue.js"></script>
<script>
// 组件:由 template + css + js 三部分组成(.vue文件)
// 1)组件具有复用性
// 2) 复用组件时,数据要隔离
// 3) 复用组件时,方法不需要隔离,因为方法使用隔离数据就可以产生区别
// 组件介绍:
// 1) 每一个组件都有自己的template(虚拟DOM),最后要替换掉真实DOM(渲染)
// 2) 挂载点el,在根组件没有规定template,用挂载的真实DOM拷贝出虚拟DOM,完成实例创建后再替换掉真实DOM(渲染)
// 3) 挂载点el,在根组件规定template,就采用自己的template作为虚拟DOM,挂载点还是必须的,用于占位
// 4) 所有 new Vue() 产生的组件都称之为根组件 - 项目开发时,整个项目只有一个根组件
// 5) template只能解析一个根标签
let num = 100;
new Vue({
el: '#app',
data: {
msg: 'message'
},
// template: '<div id="main"><p>{{ msg }}</p><p>{{ msg }}</p></div>'
template: `
<div id="main">
<p>{{ msg }}</p>
<p>{{ msg }}</p>
<div>{{ msg }}</div>
<div>${ num }</div>
</div>
`,
})
</script>
</html>
局部组件
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
<style>
.ad {
width: 200px;
padding: 5px;
margin: 5px;
box-shadow: 0 0 5px 0 gold;
float: left;
}
.ad img {
width: 100%;
}
.ad h4 {
margin: 0;
font: normal 20px/30px '微软雅黑';
text-align: center;
}
</style>
</head>
<body>
<div id="app">
<!--<div class="ad">-->
<!--<img src="img/mn.jpg" alt="">-->
<!--<h4>美女</h4>-->
<!--</div>-->
<!--<ad></ad>-->
<!--<ad></ad>-->
<!--3)组件渲染-->
<local-tag></local-tag>
<local-tag></local-tag>
<local-tag></local-tag>
</div>
</body>
<script src="js/vue.js"></script>
<script>
// 1)创建组件
let localTag = {
template: `
<div class="ad">
<img src="img/mn.jpg" alt="">
<h4>美女</h4>
</div>
`
};
new Vue({
el: '#app',
// 2)注册组件
components: {
// localTag: localTag,
localTag
}
})
</script>
</html>
全局组件
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
<style>
.ad {
width: 200px;
padding: 5px;
margin: 5px;
box-shadow: 0 0 5px 0 gold;
float: left;
}
.ad img {
width: 100%;
}
.ad h4 {
margin: 0;
font: normal 20px/30px '微软雅黑';
text-align: center;
}
</style>
</head>
<body>
<div id="app">
<local-tag></local-tag>
<global-tag></global-tag>
</div>
<div id="main">
<local-tag></local-tag>
<global-tag></global-tag>
</div>
</body>
<script src="js/vue.js"></script>
<script>
// 局部组件
// 1)创建组件
// 2)注册组件
// 3)渲染组件
let localTag = {
template: `
<div class="ad">
<img src="img/mn.jpg" alt="">
<h4>美女</h4>
</div>
`
};
// 全局组件
// 1)创建组件
// 2)渲染组件
Vue.component('global-tag', {
template: `
<div class="ad">
<img src="img/mn.jpg" alt="">
<h4>共享美女</h4>
</div>
`
});
new Vue({
el: '#app',
components: {
localTag
}
});
new Vue({
el: '#main',
components: {
localTag
}
});
</script>
</html>
组件复用的数据隔离
局部组件和全局组件隔离开来各自处理数据,互不影响
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
<style>
.ad {
width: 200px;
padding: 5px;
margin: 5px;
box-shadow: 0 0 5px 0 gold;
float: left;
}
.ad img {
width: 100%;
}
.ad h4 {
margin: 0;
font: normal 20px/30px '微软雅黑';
text-align: center;
}
</style>
</head>
<body>
<div id="app">
<local-tag></local-tag>
<global-tag></global-tag>
</div>
<div id="main">
<local-tag></local-tag>
<global-tag></global-tag>
</div>
</body>
<script src="js/vue.js"></script>
<script>
// 局部组件
// 1)创建组件
// 2)注册组件
// 3)渲染组件
let localTag = {
template: `
<div @click="click1" class="ad">
<img src="img/mn.jpg" alt="">
<h4>美女被点了{{ num }}下</h4>
</div>
`,
// 除了根组件,数据都是函数的返回值字典
data () {
return {
num: 0
}
},
methods: {
click1() {
this.num ++
}
},
};
// 全局组件
// 1)创建组件
// 2)渲染组件
Vue.component('global-tag', {
template: `
<div class="ad" @click="click2">
<img src="img/mn.jpg" alt="">
<h4>共享{{ count }}次美女</h4>
</div>
`,
data() {
return {
count: 0
}
},
methods: {
click2() {
this.count ++
}
}
});
new Vue({
el: '#app',
components: {
localTag
}
});
new Vue({
el: '#main',
components: {
localTag
}
});
</script>
</html>
组件信息交互—父传子
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
<style>
.ad {
width: 200px;
padding: 5px;
margin: 5px;
box-shadow: 0 0 5px 0 gold;
float: left;
}
.ad img {
width: 100%;
}
.ad h4 {
margin: 0;
font: normal 20px/30px '微软雅黑';
text-align: center;
}
</style>
</head>
<body>
<div id="app">
<local-tag :ad_dic="ad" v-for="ad in ads" :key="ad.img"></local-tag>
</div>
</body>
<script src="js/vue.js"></script>
<script>
let localTag = {
props: ['ad_dic'],
template: `
<div class="ad">
<img :src="ad_dic.img" alt="">
<h4>{{ ad_dic.title }}</h4>
</div>
`,
};
// 模拟后台的数据
let ads = [
{
'img': 'img/001.png',
'title': '小猫'
},
{
'img': 'img/002.png',
'title': '黄蛋'
},
{
'img': 'img/003.png',
'title': '蓝蛋'
},
{
'img': 'img/004.png',
'title': '短腿'
},
];
new Vue({
el: '#app',
data: {
ads, // 后期项目是后台返回的数据
},
components: {
localTag
}
})
// 分析数据 父传子
// 1)父组件提供数据
// 2)在父组件模板中,为子组件标签设置自定义属性绑定父级数据
// 3)在子组件props成员中,接收自定义属性
// 4)在子组件模板和方法中,使用自定义属性名就可以访问父级数据
</script>
</html>
组件信息交互—子传父
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
<style>
body {
font-size: 30px;
}
li:hover {
color: orange;
cursor: pointer;
}
.del:hover {
color: red;
}
</style>
</head>
<body>
<div id="app">
<p>
<input type="text" v-model="info">
<button @click="add_msg">留言</button>
<ul>
<msg-tag @del_action="del_li" :msg="msg" :index="i" v-for="(msg, i) in msgs" :key="msg"></msg-tag>
</ul>
</p>
</div>
</body>
<script src="js/vue.js"></script>
<script>
let msgTag = {
props: ['msg', 'index'],
template: `
<li>
<span @click="del_fn" class="del">x</span>
<span>{{ msg }}</span>
</li>
`,
methods: {
del_fn() {
this.$emit('del_action', this.index)
}
}
};
new Vue({
el: '#app',
components: {
msgTag
},
data: {
info: '',
msgs: JSON.parse(sessionStorage.msgs || '[]'),
},
methods: {
add_msg() {
let info = this.info;
if (info) {
this.msgs.unshift(this.info);
this.info = '';
sessionStorage.msgs = JSON.stringify(this.msgs);
}
},
del_li(index) {
console.log(index);
this.msgs.splice(index, 1);
sessionStorage.msgs = JSON.stringify(this.msgs);
}
}
});
// 分析数据 子传父
// 1)子组件提供数据
// 2)子组件通过系统事件激活自己的绑定方法,发送一个自定义事件,携带自身数据
// 3)在父组件模板中的子组件标签中为自定义事件绑定父组件方法
// 4)父组件实现方法获取到子组件数据
</script>
</html>