对 vue2 的从 0 开始学习,本篇了解基础语法即可。
MVVM
实现model和view 分开
viewModel实现双向绑定,可以完整描述View层
创建一个vue 应用
双括号将数据渲染进 DOM 中
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
| <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> </head> <body> <script src="./vue.js"></script>
<div id="a"> {{message}} </div> </body>
<script> var app = new Vue({ el: '#a', data: { message: 'Hello Vue!' } }) </script> </html>
|
实现了双向绑定,view层 model层双向绑定
使用 attribute 绑定元素
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| <body> <script src="./vue.js"></script>
<div id="app-2"> <span v-bind:title="message"> 鼠标悬停几秒钟查看此处动态绑定的提示信息! </span> </div> </body>
<script> var app2 = new Vue({ el: '#app-2', data: { message: '页面加载于 ' + new Date().toLocaleString() } }) </script>
|
v-bind
attribute 被称为 指令 。指令带有前缀 v-
,以表示它们是 Vue 提供的特殊 attribute。
条件和循环
v-if
指令
让元素显示或者消失
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| <body> <script src="./vue.js"></script>
<div id="app-2"> <p v-if="seen"> seen=true </p> </div> </body>
<script> var app2 = new Vue({ el: '#app-2', data: { seen:true } }) </script>
|
v-for
指令可以绑定数组的数据来渲染一个项目列表
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| <body> <script src="./vue.js"></script>
<div id="app3"> <ol> <li v-for="pet in pets"> {{pet.name}} </li> </ol> </div> </body>
<script> var app2 = new Vue({ el: '#app3', data: { pets:[ {name:'dog1'}, {name:'dog2'}, {name:'dog3'} ] } }) </script>
|
控制台可以直接 push 进去新元素
1
| app2.pets.push({name:'cat1'})
|
处理用户输入
事件监听
用 v-on
建立事件监听器
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| <body> <script src="./vue.js"></script>
<div id="app3"> <p>{{message}}</p> <button v-on:click="myFunction1">abcdefg</button> </div> </body>
<script> var app2 = new Vue({ el: '#app3', data: { message:"我是一条消息" }, methods: { myFunction1 : function () { this.message = this.message.split('').reverse().join('') } } }) </script>
|
双向绑定
v-model
指令,它能轻松实现表单输入和应用状态之间的双向绑定。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| <body> <script src="./vue.js"></script>
<div id="app3"> <p>{{message}}</p> <input type="text" v-model="message"> </div> </body>
<script> var app2 = new Vue({ el: '#app3', data: { message:"v-modle绑定" } }) </script>
|
这样前端绑到后端在回来
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| <body> <script src="./vue.js"></script>
<div id="app3"> <p>{{message}}</p> <textarea type="text" v-model="message"></textarea> </div> </body>
<script> var app2 = new Vue({ el: '#app3', data: { message:'' } }) </script>
|
组件基础
组件系统是 Vue 的另一个重要概念,因为它是一种抽象,允许我们使用小型、独立和通常可复用的组件构建大型应用。
几乎任意类型的应用界面都可以抽象为一个组件树:
就像嵌套的frame一样
在 Vue 里,一个组件本质上是一个拥有预定义选项的一个 Vue 实例。
在 Vue 中注册组件很简单:
定义一个组件
1 2 3 4
| Vue.component('todo-item', { template: '<li>这是个待办项</li>' })
|
学习一下文档里给的注册组件。
1 2 3 4
| <ol> <todo-item></todo-item> </ol>
|
们应该能从父作用域将数据传到子组件才对。让我们来修改一下组件的定义,使之能够接受一个 prop:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37
| <body> <script src="./vue.js"></script> <div id="app-7"> <ol>
<todo-item v-for="item in groceryList" v-bind:todo="item" v-bind:key="item.id" ></todo-item> </ol> </div> </body>
<script> Vue.component('todo-item', { props: ['todo'], template: '<li>{{ todo.text }}</li>' })
var app7 = new Vue({ el: '#app-7', data: { groceryList: [ { id: 0, text: '蔬菜' }, { id: 1, text: '奶酪' }, { id: 2, text: '随便其它什么人吃的东西' } ] } }) </script>
|
用v-for遍历groceryList,v-bind绑定
重新和狂神学了一遍
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
| <body> <script src="./vue.js"></script> <div id="app-1"> <aeqaq v-for="item in items" v-bind:it="item"></aeqaq> </div>
</body>
<script> Vue.component( "aeqaq", { props:['it'], template:"<li>{{it}}</li>", });
var vm = new Vue({ el:'#app-1', data:{ items:[ "item1", "item2", "item3" ] } }); </script>
|
这里名字为aeqaq的组件里的props是参数,是为了能把外面的参数传递进来的
因为实际上16行那个vue实例和组件是不通的,如果要在aeqaq组件里面遍历items,就需要有一个参数,这个参数就是it
随后在第四行用v-bind
来绑定一下it和item
创建一个vue实例
每个 Vue 应用都是通过用 Vue
函数创建一个新的 Vue 实例开始的
1 2 3
| var vm = new Vue({ // 选项 })
|
数据和方法
实例生命周期钩子
同时在这个过程中也会运行一些叫做生命周期钩子的函数,这给了用户在不同阶段添加自己的代码的机会。
比如 created
钩子可以用来在一个实例被创建之后执行代码:
1 2 3 4 5 6 7 8 9
| new Vue({ data: { a: 1 }, created: function () { console.log('a is: ' + this.a) } })
|
生命周期图示:
模板语法
插值
文本
数据绑定最常见的形式就是使用“Mustache”语法 (双大括号) 的文本插值:
1
| <span>Message: {{ msg }}</span>
|
Mustache 标签将会被替代为对应数据对象上 msg
property 的值。无论何时,绑定的数据对象上 msg
property 发生了改变,插值处的内容都会更新。
通过使用 v-once 指令,你也能执行一次性地插值,当数据改变时,插值处的内容不会更新。但请留心这会影响到该节点上的其它数据绑定:
1
| <span v-once>这个将不会改变: {{ msg }}</span>
|
原始html
1
| <p>Using v-html directive: <span v-html="rawHtml"></span></p>
|
指令
指令 (Directives) 是带有 v-
前缀的特殊 attribute。指令 attribute 的值预期是单个 JavaScript 表达式 (v-for
是例外情况,稍后我们再讨论)。指令的职责是,当表达式的值改变时,将其产生的连带影响,响应式地作用于 DOM。回顾我们在介绍中看到的例子:
1
| <p v-if="seen">现在你看到我了</p>
|
这里,v-if
指令将根据表达式 seen
的值的真假来插入/移除 <p>
元素。
事件
事件肯定有对应的方法
网络通信
axios
Vue笔记——Axios异步通信
http://axios-js.com/zh-cn/docs/index.html
vue的生命周期
使用axios来进行异步请求,把请求到的数据的绑定给info
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33
| <script src="./vue.js"></script> <script src="https://unpkg.com/axios/dist/axios.min.js"></script> <div id="app-1"> <li>{{info.name}}</li> <li>{{info.url}}</li> <li>{{info.page}}</li> <li>{{info.isNonProfit}}</li> </div> <script> var vm = new Vue({ el:'#app-1', data() { return { info:{ "name": null, "url": null, "page": null, "isNonProfit": null } } }, mounted() { axios.get('./data.json') .then(res => { this.info = res.data }) .catch(err => { console.error(err); }) }, }); </script>
|
计算属性
计算属性相当于vue做的缓存,是一个特色
methods要通过方法来调,但是computed
可以通过属性调,相当于提前计算好了
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| <div id="app-1"> <li>{{myFunction1()}}</li> <li>{{myComputed1}}</li> </div> <script> var vm = new Vue({ el:'#app-1', methods: { myFunction1: function(){ return Date.now(); } }, computed: { myComputed1: function(){ return Date.now(); } } }); </script>
|
插槽slot
slot标签用来定义插槽
用插槽我们可以连接组件和组件
https://v2.cn.vuejs.org/v2/guide/components-slots.html
1 2 3
| v-bind:title="title" 可以简写为 :title="title"
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46
| #view层 <div id="app-1"> <todo> <todo-title slot="todo-title" :title="title"></todo-title> <todo-lists slot="todo-lists" v-for="list in lists" :list="list"></todo-lists> </todo> </div> <script> Vue.component( 'todo', { template:'<div>\ <slot name="todo-title"></slot>\ <ul>\ <slot name="todo-lists"></slot>\ </ul>\ </div>' });
Vue.component( 'todo-title',{ props:['title'], template:'<li>{{title}}</li>', } );
Vue.component( 'todo-lists',{ props:['list'], template:'<li>{{list}}</li>', } ); var vm = new Vue({ el:'#app-1', data:{ title:'这是一个标题', lists:[ 'item1 in lists', 'item2 in lists', 'item3 in lists' ] }
}); </script>
|
第二第三个组件通过slot插入第一个组件
自定义事件内容分发
组件和vue实例是不通的,必须要通过前端才能让组件去调用vue实例中的东西
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64
| <script src="./vue.js"></script> <script src="https://unpkg.com/axios/dist/axios.min.js"></script>
<div id="app-1"> <todo> <todo-title slot="todo-title" :title="title"></todo-title> <todo-lists slot="todo-lists" v-for="(list,index) in lists" :list="list" :index="index" @remove="removeFromList(index)" :key="index"></todo-lists> </todo> </div>
<script> Vue.component( 'todo', { template:'<div>\ <slot name="todo-title"></slot>\ <ul>\ <slot name="todo-lists"></slot>\ </ul>\ </div>' });
Vue.component( 'todo-title',{ props:['title'], template:'<li>{{title}}</li>',
} );
Vue.component( 'todo-lists',{ props:['list','index'], template:'<li>{{list}}<button @click="remove">删除</button></li>', methods:{ remove: function(index){ this.$emit('remove',index) } } } ); var vm = new Vue({ el:'#app-1', data:{ title:'这是一个标题', lists:[ 'item1 in lists', 'item2 in lists', 'item3 in lists' ] }, methods: { removeFromList: function(index){ this.lists.splice(index,1); } },
}); </script>
|