Vue常用特性
表单基本操作
- 基于Vue的表单操作:绑定默认值
Input
单行文本<input type="text" v-model='uname'>
- Vue中:
uname: 'wing1377'
textarea
多行文本<textarea v-model='desc'></textarea>
- Vue中:
desc: 'Hello world!'
select
下拉多选<select v-model='occupation' multiple>...</select>
- Vue中:
occupation: ['1','3']
radio
单选框<input type="radio" id="male" value="1" v-model='gender'>
- Vue中:
gender: 2
checkbox
多选框<input type="checkbox" id="ball" value="1" v-model='hobby'>
- Vue中:
hobby: ['2','3']
<style type="text/css">
form div {
height: 40px;
line-height: 40px;
}
form div:nth-child(4) {
height: auto;
}
form div span:first-child {
display: inline-block;
width: 100px;
}
</style>
<body>
<section id="app">
<form action="www.baidu.com">
<div>
<span>姓名:</span>
<span><input type="text" v-model='uname'></span>
</div>
<div>
<span>性别:</span>
<span>
<input type="radio" id="male" value="1" v-model='gender'>
<label for="male">男</label>
<input type="radio" id="female" value="2" v-model='gender'>
<label for="female">女</label>
</span>
</div>
<div>
<span>爱好:</span>
<input type="checkbox" id="ball" value="1" v-model='hobby'>
<label for="ball">摄影</label>
<input type="checkbox" id="sing" value="2" v-model='hobby'>
<label for="sing">绘画</label>
<input type="checkbox" id="code" value="3" v-model='hobby'>
<label for="code">设计</label>
</div>
<div>
<span>职业:</span>
<select v-model='occupation' multiple>
<option value="0">请选择职业...</option>
<option value="1">摄影师</option>
<option value="2">设计师</option>
<option value="3">工程师</option>
</select>
</div>
<div>
<span>个人简介:</span>
<textarea v-model='desc'></textarea>
</div>
<div>
<input type="submit" value="提交" @click.prevent='handle'>
</div>
</form>
</section>
</body>
<script type="text/javascript" src="js/vue.js"></script>
<script type="text/javascript">
/* 表单基本操作 */
var vm = new Vue({
el: '#app',
data: {
uname: 'wing1377',
gender: 2,
hobby: ['2','3'],
// occupation: 3
occupation: ['1','3'],
desc: 'Hello world!'
},
methods: {
handle: function(){
console.log(this.uname)
console.log(this.gender)
console.log(this.hobby)
console.log(this.occupation.toString())
console.log(this.desc)
}
}
});
</script>
- 获取单选框中的值
- 通过v-model
<!--
1、 两个单选框需要同时通过v-model 双向绑定 一个值
2、 每一个单选框必须要有value属性 且value 值不能一样
3、 当某一个单选框选中的时候 v-model 会将当前的 value值 改变 data 中的 数据
gender 的值就是选中的值,我们只需要实时监控他的值就可以了
-->
<input type="radio" id="male" value="1" v-model='gender'>
<label for="male">男</label>
<input type="radio" id="female" value="2" v-model='gender'>
<label for="female">女</label>
<script>
new Vue({
data: {
gender: 2, // 默认会让当前的 value 值为 2 的单选框选中
},
})
</script>
- 获取复选框中的值
- 通过v-model
- 和获取单选框中的值一样
- 复选框
checkbox
这种的组合时 data 中的 hobby 我们要定义成数组 否则无法实现多选
<!--
1、 复选框需要同时通过v-model 双向绑定 一个值
2、 每一个复选框必须要有value属性 且value 值不能一样
3、 当某一个单选框选中的时候 v-model 会将当前的 value值 改变 data 中的 数据
hobby 的值就是选中的值,我们只需要实时监控他的值就可以了
-->
<div>
<span>爱好:</span>
<input type="checkbox" id="ball" value="1" v-model='hobby'>
<label for="ball">篮球</label>
<input type="checkbox" id="sing" value="2" v-model='hobby'>
<label for="sing">唱歌</label>
<input type="checkbox" id="code" value="3" v-model='hobby'>
<label for="code">写代码</label>
</div>
<script>
new Vue({
data: {
// 默认会让当前的 value 值为 2 和 3 的复选框选中
hobby: ['2', '3'],
},
})
</script>
- 获取下拉框和文本框中的值
- 通过v-model
<span>职业:</span>
<!--
1、 需要给select 通过v-model 双向绑定 一个值
2、 每一个option 必须要有value属性 且value 值不能一样
3、 当某一个option选中的时候 v-model 会将当前的 value值 改变 data 中的 数据
occupation 的值就是选中的值,我们只需要实时监控他的值就可以了
-->
<!-- multiple 多选 -->
<select v-model='occupation' multiple>
<option value="0">请选择职业...</option>
<option value="1">教师</option>
<option value="2">软件工程师</option>
<option value="3">律师</option>
</select>
<!-- textarea 是 一个双标签 不需要绑定value 属性的 -->
<textarea v-model='desc'></textarea>
<script>
new Vue({
data: {
// 默认会让当前的 value 值为 2 和 3 的下拉框选中
occupation: ['2', '3'],
desc: 'hello'
},
})
</script>
表单修饰符
-
.number
转换为数值- 注意点:
- 当开始输入非数字的字符串时,因为Vue无法将字符串转换成数值
- 所以属性值将实时更新成相同的字符串。即使后面输入数字,也将被视作字符串。
-
.trim
自动过滤用户输入的首尾空白字符- 只能去掉首尾的 不能去除中间的空格
-
.lazy
将input事件切换成change事件.lazy
修饰符延迟了同步更新属性值的时机。- 默认情况下,
v-model
为input
事件 - 即将原本绑定在
input
事件的同步逻辑转变为绑定在change
事件上 - 在失去焦点 或者 按下回车键时才更新
<!-- 自动将用户的输入值转为数值类型 -->
<input v-model.number="age" type="number">
<!--自动过滤用户输入的首尾空白字符 -->
<input v-model.trim="msg">
<!-- 在“change”时而非“input”时更新 -->
<input v-model.lazy="msg" >
Vue
中change
input
enter
输入框事件对比
<section id="app">
<input type="text" @change="specifiName($event)" value='change' /><br>
<!-- change事件:当input内部数据变化,且input失去焦点时,反馈数据 -->>
<input type="text" @input="specifiName($event)" value="input" /><br>
<!-- input事件:当input内部数据变化时,实时反馈数据 -->>
<input type="text" @keyup.enter="specifiName($event)" value='enter' /><br>
<!-- enter事件:不管input内部数据是否变化,回车键触发时反馈数据 -->>
</section>
<script>
var vm = new Vue({
el: "#app",
methods: {
specifiName(e) {
var that = this;
var val = e.target.value;
console.log(val);
},
}
});
</script>
自定义指令
-
自定义指令
- 内置指令不能满足我们特殊的需求
- Vue允许我们自定义指令
-
钩子函数
- 一个指令定义对象可以提供如下几个钩子函数:
bind
只调用一次,指令第一次绑定到元素时调用,在这里可以进行一次性的初始化设置inserted
被绑定元素插入父节点时调用(仅保证父节点存在,但不一定已被插入文档中)update
所在组件的VNode更新时调用,但是可能发生在其子VNode更新之前,指令的值可能发生了改变,也可能没有,但是你可以通过比较更新前后的值来忽略不必要的模板更新(详细的钩子函数参数见下)- 在 bind 之后立即以初始值为参数第一次调用,之后每当绑定值变化时调用,参数为新值与旧值。
componentUpdated
指令所在组件的VNode及其子VNode全部更新后调用unbind
只调用一次,指令与元素解绑时调用
<!-- 第一步:注册自定义全局指令 -->
<script>
Vue.directive('my-directive', {
bind: function () {
// 准备工作
// 例如,添加事件处理器或只需要运行一次的高耗任务
},
update: function (newValue, oldValue) {
// 值更新时的工作
// 也会以初始值为参数调用一次
},
unbind: function () {
// 清理工作
// 例如,删除 bind() 添加的事件监听器
}
})
</script>
<!-- 第二步:在 Vue.js 模板中调用(记着添加前缀 v-) -->
<section id="app">
<div v-my-directive="someValue"></div>
</section>
<!-- 第三步:当只需要 update 函数时,可以传入一个函数替代定义对象 -->
<script>
Vue.directive('my-directive', function (value) {
// 这个函数用作 update()
})
var vm = new Vue({
el: '#app',
data: {
},
methods: {
}
});
</script>
Vue.directive
注册全局指令
<section id="app">
<input type="text">
<input type="text" v-focus>
</section>
<script>
Vue.directive('focus',{
inserted: function(el){
// el表示指令所绑定的元素
el.focus();
}
});
var vm = new Vue({
el: "#app",
data: {
},
methods: {
}
});
</script>
- 钩子函数参数
- 所有的钩子函数将被复制到实际的指令对象中
- 钩子内 this 指向这个指令对象。这个对象暴露了一些有用的属性
el
指令所绑定的元素,可以用来直接操作DOMvm
拥有该指令的上下文 ViewModelexpression
指令的表达式,不包括参数和过滤器binding
一个对象,包含以下属性name
指令名,不包括-v
前缀value
指令的绑定值,例如:v-m-directive='1+1'
中,绑定值为2oldValue
指令绑定的前一个值,仅在update
和componentUpdated
钩子中可用,无论值是否改变都可用expression
字符串形式的指令表达式。例如:v-my-directive='1+1'
中,表达式为1+1
arg
传给指令的参数,可选。例如v-my-directive.foo
中,参数为foo
modifiers
一个包含修饰符的对象。例如:v-my-directive.foo.bar
中,修饰符对象为{foo:true,bar:true}
vnode
Vue编译生成的虚拟节点。oldVnode
上一个虚拟节点,仅在update
和componentUpdated
钩子中使用。
<div id="demo" v-demo:hello.a.b="msg"></div>
<script>
Vue.directive('demo', {
bind: function () {
console.log('demo bound!')
},
update: function (value) {
this.el.innerHTML =
'name - ' + this.name + '<br>' +
'expression - ' + this.expression + '<br>' +
'argument - ' + this.arg + '<br>' +
'modifiers - ' + JSON.stringify(this.modifiers) + '<br>' +
'value - ' + value
}
})
var demo = new Vue({
el: '#demo',
data: {
msg: 'hello!'
}
})
</script>
Vue.directive
注册全局指令 带参数
<section id='app'>
<input type="text" v-color='msg'>
</section>
<script type="text/javascript">
/*
自定义指令-带参数
bind - 只调用一次,在指令第一次绑定到元素上时候调用
*/
Vue.directive('color', {
// bind声明周期, 只调用一次,指令第一次绑定到元素时调用。在这里可以进行一次性的初始化设置
// el 为当前自定义指令的DOM元素
// binding 为自定义的函数形参 通过自定义属性传递过来的值 存在 binding.value 里面
bind: function(el, binding){
// 根据指令的参数设置背景色
// console.log(binding.value.color)
el.style.backgroundColor = binding.value.color;
}
});
var vm = new Vue({
el: '#app',
data: {
msg: {
color: 'blue'
}
}
});
</script>
<section id='app'>
<input type="text" v-color='msg'>
</section>
<script type="text/javascript">
/*
自定义指令-带参数
bind - 只调用一次,在指令第一次绑定到元素上时候调用
*/
Vue.directive('color', {
// bind声明周期, 只调用一次,指令第一次绑定到元素时调用。在这里可以进行一次性的初始化设置
// el 为当前自定义指令的DOM元素
// binding 为自定义的函数形参 通过自定义属性传递过来的值 存在 binding.value 里面
inserted: function(el, binding){
// 根据指令的参数设置背景色
// console.log(binding.value.color)
el.style.backgroundColor = binding.value.color;
}
});
var vm = new Vue({
el: '#app',
data: {
msg: {
color: 'orange'
}
}
});
</script>
- 自定义指令局部指令
- 局部指令,需要定义在 directives 的选项 用法和全局用法一样
- 局部指令只能在当前组件里面使用
- 当全局指令和局部指令同名时以局部指令为准
<section id='app'>
<input type="text" v-color='msg'>
<input type="text" v-focus>
</section>
<script type="text/javascript">
/*
自定义指令-局部指令
*/
var vm = new Vue({
el: '#app',
data: {
msg: {
color: 'red'
}
},
//局部指令,需要定义在 directives 的选项
directives: {
color: {
bind: function(el, binding){
el.style.backgroundColor = binding.value.color;
}
},
focus: {
inserted: function(el) {
el.focus();
}
}
}
});
</script>
计算属性 computed
- 计算属性
- 模板中放入太多的逻辑会让模板过重且难以维护 使用计算属性可以让模板更加的简洁
- 计算属性是基于它们的响应式依赖进行缓存的
- computed比较适合对多个变量或者对象进行处理后返回一个结果值,
- 也就是数多个变量中的某一个值发生了变化则我们监控的这个值也就会发生变化
<section id="app">
<!--
当多次调用 reverseString 的时候
只要里面的 num 值不改变 他会把第一次计算的结果直接返回
直到data 中的num值改变 计算属性才会重新发生计算
-->
<div>{{reverseString}}</div>
<div>{{reverseString}}</div>
<!-- 调用methods中的方法的时候 他每次会重新调用 -->
<div>{{reverseMessage()}}</div>
<div>{{reverseMessage()}}</div>
</section>
<script type="text/javascript">
/*
计算属性与方法的区别:计算属性是基于依赖进行缓存的,而方法不缓存
*/
var vm = new Vue({
el: '#app',
data: {
msg: 'Nihao',
num: 100
},
methods: {
reverseMessage: function(){
console.log('methods')
return this.msg.split('').reverse().join('');
}
},
//computed 属性 定义 和 data 已经 methods 平级
computed: {
// reverseString 这个是我们自己定义的名字
reverseString: function(){
console.log('computed')
var total = 0;
// 当data 中的 num 的值改变的时候 reverseString 会自动发生计算
for(var i=0;i<=this.num;i++){
total += i;
}
// 这里一定要有return 否则 调用 reverseString 的 时候无法拿到结果
return total;
}
}
});
</script>
侦听器 watch
- 侦听器
- 使用watch来响应数据的变化
- 一般用于异步或者开销较大的操作
- watch 中的属性 一定是data 中已经存在的数据
- 当需要监听一个对象的改变时,普通的watch方法无法监听到对象内部属性的改变
- 只有data中的数据才能够监听到变化
- 此时就需要deep属性对对象进行深度监听
<section id="app">
<div>
<span>名:</span>
<span>
<input type="text" v-model='firstName'>
</span>
</div>
<div>
<span>姓:</span>
<span>
<input type="text" v-model='lastName'>
</span>
</div>
<div>{{fullName}}</div>
</section>
<script type="text/javascript">
/* 侦听器 */
var vm = new Vue({
el: '#app',
data: {
firstName: 'Jim',
lastName: 'Green',
fullName: 'Jim Green'
},
//watch 属性 定义 和 data 已经 methods 平级
watch: {
// 注意: 这里firstName 对应着data 中的 firstName
// 当 firstName 值 改变的时候 会自动触发 watch
firstName: function(val) {
this.fullName = val + ' ' + this.lastName;
},
// 注意: 这里 lastName 对应着data 中的 lastName
lastName: function(val) {
this.fullName = this.firstName + ' ' + val;
}
}
});
</script>
<section id="app">
<div>
<span>名:</span>
<span>
<input type="text" v-model='firstName'>
</span>
</div>
<div>
<span>姓:</span>
<span>
<input type="text" v-model='lastName'>
</span>
</div>
<div>{{fullName}}</div>
</section>
<script type="text/javascript">
/* 侦听器 */
var vm = new Vue({
el: '#app',
data: {
firstName: 'Jim',
lastName: 'Green',
},
//watch 属性 定义 和 data 已经 methods 平级
computed: {
fullName: function(){
return this.fullName = this.firstName+ ''+ this.lastName;
}
});
</script>
- 案例:用户名输入
<section id="app">
<span>用户名:</span>
<input type="text" v-model.lazy='uname' >
<span v-text='msg'></span>
<div v-text='uname'></div>
</section>
<script type="text/javascript">
var vm= new Vue({
el: '#app',
data: {
uname: '',
msg: '请输入用户名',
},
methods: {
checkName: function(uname){
var that = this;
setTimeout(function(){
if(uname == 'admin'){
that.msg = '用户名重复,请换一个';
}else if(uname == ''){
that.msg = '请输入用户名';
}else{
that.msg = '用户名可以使用';
}
},2000)
}
},
watch: {
uname: function(value){
this.checkName(value);
this.msg='正在验证。。。';
}
}
});
</script>
过滤器
- 过滤器
- Vue.js允许自定义过滤器,可被用于一些常见的文本格式化。
- 过滤器可以用在两个地方:双花括号插值和v-bind表达式。
- 过滤器应该被添加在JavaScript表达式的尾部,由“管道”符号指示
- 支持级联操作
- 过滤器不改变真正的
data
,而只是改变渲染的结果,并返回过滤后的版本 - 全局注册时是filter,没有s的。而局部过滤器是filters,是有s的
<section id="app">
<input type="text" v-model='msg'>
<div>{{ msg | upper | reverse | lower }}</div>
</section>
<script type="text/javascript">
Vue.filter('lower', function(value){
// 字符串API自锁
return value.charAt(0).toLowerCase()+ value.slice(-1);
})
var vm = new Vue({
el: '#app',
data: {
msg: ''
},
filters: {
reverse: function(value){
return value.split('').reverse().join('');
},
upper: function(value){
return value.charAt(0).toUpperCase()+ value.slice(1);
}
}
});
</script>
- 过滤器中传递参数
<section id="app">
<div>{{ date | format('yyyy-MM-dd', 'Hello time') }}</div>
</section>
<script type="text/javascript">
var vm= new Vue({
el: '#app',
data: {
date: new Date(),
},
filters: {
format: function(value, arg1, arg2){
if(arg1 == 'yyyy-MM-dd'){
let year = value.getFullYear();
let month = (value.getMonth()+ 1)> 10? (value.getMonth()+ 1): '0'+(value.getMonth()+ 1);
let day = value.getDate()> 10? value.getDate(): '0'+ value.getDate();
return year+ '-'+ month+ '-'+ day+ ' '+ arg2;
}
}
}
});
</script>
<section id="app">
<div>{{date | format('yyyy-MM-dd hh:mm:ss')}}</div>
</section>
<script type="text/javascript" src="js/vue.js"></script>
<script type="text/javascript">
/* 过滤器案例:格式化日期 */
// Vue.filter('format', function(value, arg) {
// if(arg == 'yyyy-MM-dd') {
// var ret = '';
// ret += value.getFullYear() + '-' + (value.getMonth() + 1) + '-' + value.getDate();
// return ret;
// }
// return value;
// })
Vue.filter('format', function(value, arg) {
function dateFormat(date, format) {
if (typeof date === "string") {
var mts = date.match(/(\/Date\((\d+)\)\/)/);
if (mts && mts.length >= 3) {
date = parseInt(mts[2]);
}
}
date = new Date(date);
if (!date || date.toUTCString() == "Invalid Date") {
return "";
}
var map = {
"M": date.getMonth() + 1, //月份
"d": date.getDate(), //日
"h": date.getHours(), //小时
"m": date.getMinutes(), //分
"s": date.getSeconds(), //秒
"q": Math.floor((date.getMonth() + 3) / 3), //季度
"S": date.getMilliseconds() //毫秒
};
format = format.replace(/([yMdhmsqS])+/g, function(all, t) {
var v = map[t];
if (v !== undefined) {
if (all.length > 1) {
v = '0' + v;
v = v.substr(v.length - 2);
}
return v;
} else if (t === 'y') {
return (date.getFullYear() + '').substr(4 - all.length);
}
return all;
});
return format;
}
return dateFormat(value, arg);
})
var vm = new Vue({
el: '#app',
data: {
date: new Date()
}
});
</script>
生命周期
-
生命周期
- 事物从出生到死亡的过程
- Vue实例从创建 到销毁的过程 ,这些过程中会伴随着一些函数的自调用。
- 我们称这些函数为钩子函数
-
主要阶段
- 挂载(初始化相关属性)
beforeCreate
created
beforeMount
mounted
- 更新(元素或组件的变更操作)
beforeUpdate
updated
- 销毁(销毁相关属性)
beforeDestroy
destroyed
- 挂载(初始化相关属性)
-
常用的钩子函数
beforeCreate
在实例初始化之后,数据观测和事件配置之前被调用- 此时data 和 methods 以及页面的DOM结构都没有初始化,什么都做不了
created
在实例创建完成后被立即调用- 此时data 和 methods已经可以使用,但是页面还没有渲染出来
beforeMount
在挂载开始之前被调用- 此时页面上还看不到真实数据 只是一个模板页面而已
mounted
el被新创建的vm.$el替换,并挂载到实例上去之后调用该钩子。- 数据已经真实渲染到页面上
- 在这个钩子函数里面我们可以使用一些第三方的插件
beforeUpdate
数据更新时调用,发生在虚拟DOM打补丁之前。- 页面上数据还是旧的
updated
由于数据更改导致的虚拟DOM重新渲染和打补丁,- 在这之后会调用该钩子。
- 页面上数据已经替换成最新的
beforeDestroy
实例销毁之前调用destroyed
实例销毁后调用
<section id="app">
<div>{{msg}}</div>
<button @click='update'>更新</button>
<button @click='destroy'>销毁</button>
</section>
<script type="text/javascript" src="js/vue.js"></script>
<script type="text/javascript">
/* Vue实例的生命周期 */
var vm = new Vue({
el: '#app',
data: {
msg: '生命周期'
},
methods: {
update: function(){
this.msg = 'hello';
},
destroy: function(){
this.$destroy();
}
},
beforeCreate: function(){
console.log('beforeCreate');
},
created: function(){
console.log('created');
},
beforeMount: function(){
console.log('beforeMount');
},
mounted: function(){
console.log('mounted');
},
beforeUpdate: function(){
console.log('beforeUpdate');
},
updated: function(){
console.log('updated');
},
beforeDestroy: function(){
console.log('beforeDestroy');
},
destroyed: function(){
console.log('destroyed');
}
});
</script>
mounted
el
被新创建的vm.$el
替换,并挂载到实例上去之后调用该钩子- 如果
root
实例挂载了一个文档内元素,当mounted
被调用时,vm.$el
也在文档内 - 该钩子在服务器端渲染期间不被调用
数组方法
-
数组变异方法
- 在 Vue 中,直接修改对象属性的值无法触发响应式。
- 当你直接修改了对象属性的值,你会发现,只有数据改了,但是页面内容并没有改变
- 变异数组方法即保持数组方法原有功能不变的前提下对其进行功能拓展
-
变异数组:修改原有数组
push()
往数组最后面添加一个元素,成功返回当前数组的长度pop()
删除数组的最后一个元素,成功返回删除元素的值shift()
删除数组的第一个元素,成功返回删除元素的值unshift()
往数组最前面添加一个元素,成功返回当前数组的长度splice
有三个参数,第一个是想要删除的元素的下标(必选),第二个是想要删除的个数(必选),第三个是删除 后想要在原位置替换的值sort
使数组按照字符编码默认从小到大排序,成功返回排序后的数组reverse
将数组倒序,成功返回倒序后的数组
-
替换数组:不会改变原始数组,但总是返回一个新数组
filter
此方法创建一个新的数组,新数组中的元素是通过检查指定数组中符合条件的所有元素。content
此方法用于连接两个或多个数组。该方法不会改变现有的数组slice
此方法可从已有的数组中返回选定的元素。该方法并不会修改数组,而是返回一个子数组
<section id="app">
<div>
<span>
<input type="text" v-model='fname'>
<button v-on:click='add'>添加</button>
<button v-on:click='del'>删除</button>
<button v-on:click='change'>替换</button>
</span>
</div>
<ul>
<li v-bind:key='index' v-for='(item, index) in list' v-text='item'></li>
</ul>
</section>
<script type="text/javascript">
var vm= new Vue({
el: '#app',
data: {
fname:'',
list: ['apple','orange','banana'],
},
methods: {
add: function(){
this.list.push(this.fname);
},
del: function(){
this.list.pop(this.fname);
},
change: function(){
this.list= this.list.slice(0,2)
}
}
});
</script>
动态数组响应式数据
- 修改响应式数据:可动态的处理数组与对象
- Vue.set(vm.items, indexOfItem, newValue)
- 参数1:表示要处理的数组名称
- 参数2:表示要处理的数组的索引
- 参数3:表示要处理的数组的值
- vm.$set(vm.items, indexOfItem, newValue)
- 参数1:表示要处理的数组名称
- 参数2:表示要处理的数组的索引
- 参数3:表示要处理的数组的值
- Vue.set(vm.items, indexOfItem, newValue)
<section id="app">
<ul>
<li v-bind:key='index' v-for='(item, index) in list' v-text='item'></li>
</ul>
<div>
<div>{{ info.name }}</div>
<div>{{ info.age }}</div>
<div>{{ info.gender }}</div>
</div>
</section>
<script type="text/javascript">
var vm= new Vue({
el: '#app',
data: {
list: ['apple','orange','banana'],
info: {
name: 'list',
age: 12
}
}
});
vm.$set(vm.list, 0, '苹果');
Vue.set(vm.list, 1, '橘子');
// 这不是数据响应式,但是受到上面响应式的影响,也刷新了数据
vm.list[2]= '香蕉';
// 这不是数据响应式,但是受到上面响应式的影响,也刷新了数据
vm.info.gender = 'male';
vm.$set(vm.info, 'gender', 'girl');
</script>