一、vue初识
1、vue概念
- vue是一个渐进式,响应式的javascript框架。
所谓**渐进式
**,指的是vue可以逐渐地嵌入html界面之中;而响应式
指的是vue关注图层,以当数据改变时,界面标签等也会随之而变。 尽可能简单的 API 实现响应的数据绑定和组合的视图组件
- 一个简单的实例
<div id="app">{{message}}</div>
...
<script>
//let 实例化vue
let app=new Vue({
el:'#app',
data:{
message:'hello world'
},
methods:{}
})
</script>
其中el挂载id为app的div,
- data为vue实例中的数据,有自定义与vue库中定义的。
- 而methods中定义了调用函数。通过
return
返回函数值 - {{ }}为插值表达式用于插入内容
- 注意语句之间用‘,’隔开。
2、vue安装
三种安装方法:
- 独立版本,到官网安装vue.js然后引入
- cnn引入:`
- npm引入:构建大型用时安装`
3、vue数据与方法
- vue实例创建,data对象能找到的所有属性均加入了vue响应系统,数据更改,视图响应更改
二、vue基本语法
1、模板语法
- 文本插值(v-text)
<p>{{文本内容}}</p>===<p v-text="文本内容"></p>
- v-html输出html代码
当v-html插入的是html标签结构时是添加标签,否则与v-text一样功能 - 属性设置v-bind
v-bind:class={class1:torf}===:class={class1:torf}//缩写
- 指令v-if与v-show
v-if=“seen”或者v-show=“seen”,系统会根据seen的布尔值来判断标签是否显示,不同点在于v-if操作dom元素而v-show操纵元素样式,故经常切换的应使用v-show,减小损耗。 - v-on指令监听dom事件
<button v-on:keyup.enter="push">===<button -@keyup.enter="push">//简写
若有参数则用实心点’.'修饰。
6. v-model完成表单数据的双向绑定
<input v-model="message">
则与vue实例中的message数据双向绑定,用户输改变message即会改变
<input v-model="message">
...
methods:{
reverse:function(){
this.message.split(''),reverse().join('')}
}
reverse方法将表单中用户输入的字符串message颠倒过来。
7. 表达式
vue.js提供完全的js表达式支持。
<div id="app">
{{message.split('').reverse().join('')}}}//颠倒字符串
{{5+5}}//10
{{ok? yes:no}}//yes(data中ok定义为true)++
- 过滤器
- vue可自定义过滤器,用作常见文本格式化。
- 过滤器本质是js函数
- 过滤器可以串联
{{ message | filterA('arg1', arg2) }}
...
//vue实例中将输入的值第一个字母大写
filters: {
capitalize: function (value) {
if (!value) return '';
value = value.toString();
return value.charAt(0).toUpperCase() + value.slice(1);
}
}
{{ message | filterA('arg1', arg2) }}
此表达式中,message为filterA的第一个参数,字符串arg1作为第二个参数,而表达式arg2运算后的值则是第三个参数。
2、条件语句
- v-if v-show(上节)
- v-else与v-else-if
<div id="app">
<div v-if="Math.random() > 0.5">
Sorry
</div>
<div v-else-if="math.random()=0.5">
ssssorry
</div>
<div v-else>
not sorry
</div>
</div>
3、循环语句
v-for
- 渲染数组到列表
<ul>
<li v-for="item in items">
{{item.name}}
</li>
</ul>
...
data:{
items:[{name:'jack'},{name:'bode'},}name:'lucy'}]
}
- 模板中也可使用:
<ul>
<template v-for="item in items">
<li>{{item.name}}</li>
<li>{{item.phone}}</li>
</template>
</ul>
- v-for 通过对象的属性来迭代数据
<ul>
<li v-for="value in object">
{{ value }}
</li>
</ul>
。。。
object:{
name:'lyf',
phone:'2521-55455',
school:'dadasd'
}
/*- lyf
- 2521-55455
- dadasd*/
- 第二个参数为键名,第三个参数为索引
<div id="app">
<ul>
<li v-for="(value,key,index in items)">
{{index}}.{{key}}:{{value}}
</li>
</ul>
</div>
4、计算属性
- 关键字computed
<div id="app">
<p>原始字符串: {{ message }}</p>
<p>计算后反转字符串: {{ reversedMessage }}</p>
</div>
。。。
computed: {
// 计算属性reversemessage的 getter
reversedMessage: function () {
// `this` 指向 vm 实例
return this.message.split('').reverse().join('')
}
}
- 区别于methods的是computed是基于他的依赖缓存,app.a依赖于app.b,缓存后,以后的计算都会根据缓存来输出,不再走逻辑,而methods每渲染一次都会调用那个函数。
<div id="app">{{site}}</div>
...
computed: {
site: {
// getter
get: function () {
return this.name + ' ' + this.url
},
// setter
set: function (newValue) {
var names = newValue.split(' ')
this.name = names[0]
this.url = names[names.length V- 1]
}
}
}
})
// 调用 setter, vm.name 和 vm.url 也会被对应更新
5、监听属性
- 两种写法:
直接vm实例中写watch:{}
属性或者vm实例外部用vm方法调用:vm.$watch('firstname',function{})
watch:{
firstname:function(newValue.oldValue){//firstname属性值发生了改变
this.fullName=newValue+''+this.lastName;
}
}
6、v-bind
v-bind几个特殊情况:
- class多个类动态绑定
<div v-bind:class="classObject"></div>
...
data:{
classObject:{active:isActive,danger:isDanger}
}
- 数组传入
<div v-bind:class=“[active,danger,acesse]”></div>
- style(内联样式)
将样式对象应用到模板
<div v-bind:style=""[style1,style2]></div>
...
data:{
style1:{
color:white,
background-color:red
},
style2:{
position:fixed,
z-index:5
}
}
7、事件处理器
除了直接绑定函数,几个特殊情况:
- 内联js语句
<button v-on="say('hi')">say hi</button>
...
methods:{
say:function(message){
alert(message);
}
}
- 事件修饰符
<!-- 阻止单击事件冒泡 -->
<a v-on:click.stop="doThis"></a>
<!-- 提交事件不再重载页面 -->
<form v-on:submit.prevent="onSubmit"></form>
<!-- 修饰符可以串联 -->
<a v-on:click.stop.prevent="doThat"></a>
<!-- 只有修饰符 -->
<form v-on:submit.prevent></form>
<!-- 添加事件侦听器时使用事件捕获模式 -->
<div v-on:click.capture="doThis">...</div>
<!-- 只当事件在该元素本身(而不是子元素)触发时触发回调 -->
<div v-on:click.self="doThat">...</div>
<!-- click 事件只能点击一次,2.1.4版本新增 -->
<a v-on:click.once="doThis"></a>
- 按键修饰符
如
<button @keyuo.enter="click">111</button>
初次之外,还有其他许多按键别名(esc、space、tab等)
三、vue表单
- v-bond实现表单数据双向绑定
- 复选框如果是一个为逻辑值,为多个则是绑定到一个数组
<input type="checkbox" id="checkbox" v-model="checked">
<label for="checkbox">{{ checked }}</label>//input标注
- 单选框则绑定选中的数据
- 修饰符
v-bond.lazy表示从在input事件中同步输入值 转变为 在change事件中同步;
v-bind.number表示自动将用户输入值转变为数字;
v-bind,trim自动清除空格
四、vue组件
组件(component)用作扩展html元素以及封装可重用性代码。
组件与模块的区别:
- 组件化是从ui界面划分
- 模块化是从代码角度划分
1、语法
Vue.component(tagname,options)
(tagname为组件名,options为配置选项);
调试时就用<tagName></tagName>
即可(注意tagname中不要有大写,测试时出错
)
2、组件位置
- 所有实例都可用的全局组件,写在vue实例外部:
vue.component();
- 只在本vue内部使用的局部组件,写在vue内部:
component:{‘tagname’,options}
3、prop属性
prop为子组件接受父组件传输数据的一个自定义属性
子组件需要显示地用props选项声明prop。
(? )注册组件为子,html中使用为父
<div id="app">
<child message="hello!"></child>
</div>
...
Vue.component('child', {
// 声明 props
props: ['message'],
// 同样也可以在 vm 实例中像 “this.message” 这样使用
template: '<span>{{ message }}</span>'
})
4、动态prop
即用v-bind指令在父组件中绑定props值,父子组件数据即可双向绑定。
div id="app">
<ol>
<selfelement v-for="item in sites" v-bind:self="item"></selfelement>
</ol>
</div>
...
Vue.component('selfelement',
{props:['self'],template:'<li>{{self.text}}</li>'
})
...
data:{
sites:[
{text:'liuyifan'},
{text:'liusanfeng'},
{text:'zhenqiuhe'}
5、prop验证
Vue.component('my-component', {
props: {
// 基础的类型检查 (`null` 和 `undefined` 会通过任何类型验证)
propA: Number,
// 多个可能的类型
propB: [String, Number],
// 必填的字符串
propC: {
type: String,
required: true
},
// 带有默认值的数字
propD: {
type: Number,
default: 100
},
// 带有默认值的对象
propE: {
type: Object,
// 对象或数组默认值必须从一个工厂函数获取
default: function () {
return { message: 'hello' }
}
},
// 自定义验证函数
propF: {
validator: function (value) {
// 这个值必须匹配下列字符串中的一个
return ['success', 'warning', 'danger'].indexOf(value) !== -1
}
}
}
})
6、自定义事件
子组件传数据给父组件需要自定义事件。
- $on(eventname)监听事件
- $emit(eventname)触发事件、
- 父组件可以在使用子组件的地方直接用 v-on 来监听子组件触发的事件。
- 在某个组件的跟元素监听原生事件用.native修饰v-on。
<div id="app">
<button v-on:自定义事件="function2" ></button>
</div>
...
Vue.component('组件名',{
template:'<button v-on:click="function1">{{message}}</button>,
data:function(){},
methods:{
function1:function(){
this.$emit('自定义事件')
}
}
})
...
//vue实例中:
methods:{
function2:function(){}
}
子组件与外部完全解耦,只做了父组件关心的内部事件
注意
:其中data必须为一个函数,好处在于每个实例可以维护一份被返回对象的独立的拷贝,如果 data 是一个对象则会影响到其他实例
五、自定义指令
1、基本使用
关键字directive,下面为一个全局
自定义指令v-focus实例
Vue.directive('focus', {
// 指令定义
inserted: function (el) {
// 聚焦元素
el.focus()
}
})
注意
:全局时用directive,局部用directives,必须对应。否则出错
2、钩子
- 钩子函数
钩子函数为指令定义函数提供(可选)
- bind:定义一个在绑定时执行一次的初始化动作
- inserted:被绑定的元素插入父节点时调用
- update:被绑定元素模板更新时调用
- componentUpdated:被绑定元素所在模板完成一次更新周期后调用
- unbind:只调用一次,解绑时调用
- 钩子函数参数
- el:指令绑定元素可用来直接操纵dom元素
- binding:一个对象,有以下属性
- name:指令名,不包含v-前缀
- value:指令绑定值(计算结果)
- oldValue: 仅update 和 componentUpdated 钩子中可用,绑定前的值
- expression:绑定值的表达式或变量名
- arg:传给指令的参数
- modifiers:一个包含修饰符的对象,如v-self.foo.too的modifiers为{foo:true,bar:true}
- vnode:Vue编译生成的虚拟节点
- oldVnode:仅update 和 componentUpdated 钩子中可用,上一个虚拟节点。
实例
:
<div id="app" v-runoob:hello.a.b="message">
</div>
<script>
Vue.directive('runoob', {
bind: function (el, binding, vnode) {
var s = JSON.stringify//js对象转换为json字符串
el.innerHTML =
'name: ' + s(binding.name) + '<br>' +
'value: ' + s(binding.value) + '<br>' +
'expression: ' + s(binding.expression) + '<br>' +
'argument: ' + s(binding.arg) + '<br>' +
'modifiers: ' + s(binding.modifiers) + '<br>' +
'vnode keys: ' + Object.keys(vnode).join(', ')
}
})
new Vue({
el: '#app',
data: {
message: '菜鸟教程!'
}
})
</script>
- 简写
在不需其他钩子函数时可简写
Vue.directive('runoob', function (el, binding) {
// 设置指令的背景颜色
el.style.backgroundColor = binding.value.color
})
- 传入合理的js表达式,例如对象
div id="app">
<div v-runoob="{ color: 'green', text: '菜鸟教程!' }"></div>
</div>
<script>
Vue.directive('runoob', function (el, binding) {
// 简写方式设置文本及背景颜色
el.innerHTML = binding.value.text
el.style.backgroundColor = binding.value.color
})
new Vue({
el: '#app'
})
六、vue-ruter(路由,SPA路径管理器)
vue-ruter允许我们通过不同url访问不同的内容——>通过vue.js实现多视图的单页web应用(single page web application, SPA)
https://unpkg.com/vue-router/dist/vue-router.js
<div id="app">
<h1>Hello App!</h1>
<p>
<!-- 使用 router-link 组件来导航. -->
<!-- 通过传入 `to` 属性指定链接. -->
<!-- <router-link> 默认会被渲染成一个 `<a>` 标签 -->
<router-link to="/foo">Go to Foo</router-link>
<router-link to="/bar">Go to Bar</router-link>
</p>
<!-- 路由出口 -->
<!-- 路由匹配到的组件将渲染在这里 -->
<router-view></router-view>
</div>
1、三个基本概念
客户端的路由实际就是dom元素的显示与隐藏
路由的两种实现方式:基于hash与基于html5 history api
- route一条路由:如home键——>home内容
- routes一组路由:如[{home键——>home内容},{pacage1键——>package1内容}]
- router管理路由的机制,用户点击按钮时他去把静置的内容呈现出来
2、实现步骤
- html中模块实现
vue-router中定义了两个标签:router-link(点击的部分)
与router-view(显示部分)
router-link有个重要属性to,即到转到的地方:<router-link to="/home">Home</router-link>
- js中配置路由
首先定义route
const routes=[
{path:'/home',component:home},//path指路径,component为组件
{path:'/page1',component:page1}
]
其次创建router对route进行管理,
const router=new VueRouter({
routes//routes:routes的简写
})
- 配置完成,将router实例注入至vue根实例即可
const app = new Vue({
router
}).$mount('#app')
3、router-link相关属性
- to
用户点击后,to的值立刻传至router.push(),to的值可以是一个字符串或者是描述目标位置的对象,例如
<!-- 命名的路由 -->
<router-link :to="{ name: 'user', params: { userId: 123 }}">User</router-link>
<!-- 带查询参数,下面的结果为 /register?plan=private -->
<router-link :to="{ path: 'register', query: { plan: 'private' }}">Register</router-link>
- replace
设置了replace属性,点击事件发生后调用router.relplace()。导航不会留下history记录
<router-link :to="{ path: '/abc'}" replace></router-link>
- append
设置 append 属性后,则在当前 (相对) 路径前添加基路径。例如,我们从 /a 导航到一个相对路径 b,如果没有配置 append,则路径为 /b,如果配了,则为 /a/b
<router-link :to="{ path: 'relative/path'}" append></router-link>
- tag
有时候想要 渲染成某种标签,例如<li>
。 于是我们使用 tag prop 类指定何种标签,同样它还是会监听点击,触发导航。
<router-link to="/foo" tag="li">foo</router-link>
<!-- 渲染结果 -->
<li>foo</li>
- active-class
设置链接激活时使用的class类名active-class = "_active"
- exact-active-class
配置当链接被精确匹配的时候应该激活的 class。与active-class区别在于
当目的地址为/file时用户访问file/file2也会激活active-class,而不会激活exact-active-class。 - event
声明可以用来触发导航的事件。可以是一个字符串或是一个包含字符串的数组。
七、过渡、动画
在操纵dom时vue提供多种过渡效果;
vue提供封装的过渡组件用于包裹要实现过渡效果的组件
基本书写格式为:
<transition name = "nameoftransition">
<div></div>
</transition>
过渡就是一个淡入淡出效果,vue在元素显示与隐藏之间提供了6个类来切换
其中v为transition的name属性的值。
2、css过渡
通常过渡写在css中、
<style>
/* 可以设置不同的进入和离开动画 */
/* 设置持续时间和动画函数 */
.slide-fade-enter-active {
transition: all .3s ease;
}
.slide-fade-leave-active {
transition: all .8s cubic-bezier(1.0, 0.5, 0.8, 1.0);
}
.slide-fade-enter, .slide-fade-leave-to
/* .slide-fade-leave-active 用于 2.1.8 以下版本 */ {
transform: translateX(10px);
opacity: 0;
}
</style>
3、css动画
css动画类似过渡,但在动画中v-enter在节点插入dom后不立即删除,而是在 animationend 事件触发时删除
。动画有时也与过渡同时使用
类似
<style>
.bounce-enter-active {
animation: bounce-in .5s;
}
.bounce-leave-active {
animation: bounce-in .5s reverse;
}
@keyframes bounce-in {
0% {
transform: scale(0);
}
50% {
transform: scale(1.5);
}
100% {
transform: scale(1);
}
}
</style>
4、自定义过渡类名
自定义过渡类名优先级高于普通的,从而更好的与第三方(如animate.css)动画库结合使用。可以以下的特性来自定义过渡类名
- enter-class
- enter-active-class
- enter-to-class (2.1.8+)
- leave-class
- leave-active-class
- leave-to-class (2.1.8+)
<link href="https://cdn.jsdelivr.net/npm/animate.css@3.5.1" rel="stylesheet" type="text/css">
...
<transition>
name="custom-classes-transition"
enter-active-class="animated tada"
leave-active-class="animated bounceOutRight"
>
<p v-if="show">111111111111111111111</p>
</transition>
5 duration 属性可定制一个显性的过渡持续时间(过渡内部嵌套元素相比跟元素有更长的过渡效果或延迟时)
<transition :duration="{ enter: 500, leave: 800 }">...</transition>
6、javascript钩子
可在属性中声明javascript钩子
<transition
v-on:before-enter="beforeEnter"
v-on:enter="enter"
v-on:after-enter="afterEnter"
v-on:enter-cancelled="enterCancelled"
v-on:before-leave="beforeLeave"
v-on:leave="leave"
v-on:after-leave="afterLeave"
v-on:leave-cancelled="leaveCancelled"
>
<!-- ... -->
</transition>
javascript中声明回调函数
// ...
methods: {
// --------
// 进入中
// --------
beforeEnter: function (el) {
// ...
},
// 此回调函数是可选项的设置
// 与 CSS 结合时使用
enter: function (el, done) {
// ...
done()
},
afterEnter: function (el) {
// ...
},
enterCancelled: function (el) {
// ...
},
// --------
// 离开时
// --------
beforeLeave: function (el) {
// ...
},
// 此回调函数是可选项的设置
// 与 CSS 结合时使用
leave: function (el, done) {
// ...
done()
},
afterLeave: function (el) {
// ...
},
// leaveCancelled 只用于 v-show 中
leaveCancelled: function (el) {
// ...
}
}
- 这些钩子可结合 CSS transitions/animations 使用,也可单独使用
- 当只用javascript过渡时,
在 enter 和 leave 中必须使用 done 进行回调
。否则,它们将被同步调用,过渡会立即完成。 - 仅使用 JavaScript 过渡的元素添加 v-bind:css=“false”,Vue 会跳过 CSS 的检测。这也可以避免过渡过程中 CSS 的影响。qu’f
- Velocity.js(一个javascript动画库)
7、初始渲染的过渡
可以通过 appear 特性设置节点在初始渲染的过渡
<transition appear>
<!-- ... -->
</transition>
亦可自定义css类名
<transition
appear
appear-class="custom-appear-class"
appear-to-class="custom-appear-to-class" (2.1.8+)
appear-active-class="custom-appear-active-class"
>
<!-- ... -->
</transition>
亦可定义钩子
8、多个元素的过渡
注意:当有多个相同标签名的元素需过渡则需要设置key属性来让vue区分
<transition>
<button v-if="isEditing" key="save">
Save
</button>
<button v-else key="edit">
Edit
</button>
</transition>
也可以通过给同一个元素的 key 特性设置不同的状态来代替 v-if 和 v-else
<transition>
<button v-bind:key="isEditing">
{{ isEditing ? 'Save' : 'Edit' }}
</button>
</transition>
使用多个 v-if 的多个元素的过渡可以重写为绑定了动态属性
的单个元素过渡。
<transition>
<button v-if="docState === 'saved'" key="saved">
Edit
</button>
<button v-if="docState === 'edited'" key="edited">
Save
</button>
<button v-if="docState === 'editing'" key="editing">
Cancel
</button>
</transition>
——>
<transition>
<button v-bind:key="docState">
{{ buttonMessage }}
</button>
</transition>
// ...
computed: {
buttonMessage: function () {
switch (this.docState) {
case 'saved': return 'Edit'
case 'edited': return 'Save'
case 'editing': return 'Cancel'
}
}
}
八、vue混入
- 混入(mixins)定义了一部分可复用的方法和计算属性,混入对象在加入组件时,混入对象的组件选项将一并加入组件原来的组建选项。
// 定义一个混入对象(vue实例外部)
var myMixin = {
created: function () {
this.startmixin()
},
methods: {
startmixin: function () {
document.write("欢迎来到混入实例");
}
}
};
var Component = Vue.extend({
mixins: [myMixin]
})
var component = new Component();
- 当组件和混入对象含有同名选项时,这些选项将以恰当的方式混合。
var mixin = {
created: function () {
document.write('混入调用' + '<br>')
}
}
new Vue({
mixins: [mixin],
created: function () {
document.write('组件调用' + '<br>')
}
});
- 若混入对象和vue实例methods中有相同的方法名,则vue实例中的优先级高
var mixin = {
methods: {
hellworld: function () {
document.write('HelloWorld 方法' + '<br>');
},
samemethod: function () {
document.write('Mixin:相同方法名' + '<br>');
}
}
};
var vm = new Vue({
mixins: [mixin],
methods: {
start: function () {
document.write('start 方法' + '<br>');
},
samemethod: function () {
document.write('Main:相同方法名' + '<br>');
}
}
});
vm.hellworld();
vm.start();
vm.samemethod();
输出结果为main:相同方法名
4. 全局混入
全局混入对象会影响之后的所有vue实例
// 为自定义的选项 'myOption' 注入一个处理器。
Vue.mixin({
created: function () {
var myOption = this.$options.myOption
if (myOption) {
console.log(myOption)
}
}
})
new Vue({
myOption: 'hello!'
})
// => "hello!"
九、vue.js(axios)
详见vuelearncodes。
十、vue.js(vue-resource)
在实现异步加载时就需应用vue3-resurce库。
1、get请求
methods:{
get:function(){
//发送get请求
this.$http.get('/try/ajax/ajax_info.txt').then(function(res){
document.write(res.body);
},function(){
console.log('请求失败处理');
});
}
如果需要传递数据
,可以使用 this.$http.get('get.php',{params : jsonData})
格式,第二个参数 jsonData 就是传到后端的数据
this.$http.get('get.php',{params : {a:1,b:2}}).then(function(res){
document.write(res.body);
},function(res){
console.log(res.status);
});
2、post请求
- post 发送数据到后端,需要第三个参数
{emulateJSON:true}
。 - emulateJSON 的作用: 如果Web服务器无法处理编码为 application/json 的请求,你可以启用 emulateJSON 选项。
methods:{
post:function(){
//发送 post 请求,.php为一段php代码
this.$http.post('/try/ajax/demo_test_post.php',{name:"菜鸟教程",url:"http://www.runoob.com"},{emulateJSON:true}).then(function(res){
document.write(res.body);
},function(res){
console.log(res.status);
});
}
}
3、语法&api
发起http请求:
- 使用全局对象方式 Vue.http
// 基于全局Vue对象使用http
Vue.http.get('/someUrl', [options]).then(successCallback, errorCallback);
Vue.http.post('/someUrl', [body], [options]).then(successCallback, errorCallback);
- 在一个 Vue 实例的内部使用 this.$http来发起 HTTP 请求
// 在一个Vue实例内使用$http
this.$http.get('/someUrl', [options]).then(successCallback, errorCallback);
this.$http.post('/someUrl', [body], [options]).then(successCallback, errorCallback);
vue-resource 提供了 7 种请求 API(REST 风格):(除jsonp外其他都是标准http方法)
- get(url, [options])
- head(url, [options])
- delete(url, [options])
- jsonp(url, [options])
- post(url, [body], [options])
- put(url, [body], [options])
- patch(url, [body], [options])
option参数说明
通过如下属性和方法处理一个请求获取到的响应对象:
十一、vue响应接口
vue可添加数据动态响应接口,
<div id = "app">
<p style = "font-size:25px;">计数器: {{ counter }}</p>
<button @click = "counter++" style = "font-size:25px;">点我</button>
</div>
...
vm.$watch('counter', function(nval, oval) {
alert('计数器值的变化 :' + oval + ' 变为 ' + nval + '!');
});
setTimeout(
function(){
vm.counter += 20;
},10000
);
以上实例在vue实例外部使用$watch监听数据,并且10s后计数器值自动加20
注意:
- Vue 不允许在已经创建的实例上动态添加新的根级响应式属性。
- Vue 不能检测到对象属性的添加或删除,最好的方式就是在初始化实例前声明根级响应式属性,哪怕只是一个空值。
- 用全局 Vue,Vue.set 和 Vue.delete 方法实现在运行过程中添加或删除属性。
- vue.set
设置对象的属性,它可以解决 Vue 无法检测添加属性的限制,
语法为Vue.set( target, key, value )
,其中target为对象或数组
,key为字符串或数字
,value为任意类型
<div id = "app">
<p style = "font-size:25px;">计数器: {{ products.id }}</p>
<button @click = "products.id++" style = "font-size:25px;">点我</button>
</div>
<script type = "text/javascript">
var myproduct = {"id":1, name:"book", "price":"20.00"};
var vm = new Vue({
el: '#app',
data: {
products: myproduct
}
});
//vue.set
Vue.set(myproduct, 'qty', 1);
console.log(vm);
vm.$watch('products.id', function(nval, oval) {
alert('计数器值的变化 :' + oval + ' 变为 ' + nval + '!');
});
</script>
以上代码中,vm外部创建了一个变量myproduct,然后在vm内部将myproduct赋予data中对象,如果想要给myproduct数组添加属性,就需要在vue实例外部使用Vue.set(myproduct, 'qty', 1);
这样,get或set方法才能应用于qty属性。
2. vue.delete
用于删除动态添加的属性,语法为
Vue.delete( target, key )
target为对象或数组,key为字符串或数字,删除后key的get与set方法也会删除