新建立的了一个交流群, 欢迎在工作的开发者, 尤其是 vue 和小程序的同志们 771402271
好久没更新博客, 确实是自己已经懒癌晚期, 最近毕业刚工作 3 个月, 公司开发一直在用 Vue, 自己个人也比较喜欢这个框架, 今天就对自己学习到和用到的知识点作一些总结, 希望能帮到大家.
Vue
知道 Vue 也一定听说过 react 和 angular , 相对于这两个框架来说, Vue 很轻量, 打包后体积只有 20K+, 同时学习起来也比较简单, Vue 借鉴了两个框架的很多优点. 当然框架没有说最好, 只有最适合, 建议多学习尝试.
众所周知 Vue 是一个 MVVM 框架, 这里的 MVVM 指的仅仅是前端, 和后端无关. 在 MVVM 框架中, 视图和数据不能直接通信, 而是通过中间人 ViewModel,ViewModel 它可以监听到数据的变化, 然后通知视图做更新. 同时它也可以监听到视图在改变, 使数据改变. 我们看下面的例子就大概懂了.
举例:
- <!DOCTYPE html>
- <html>
- <head>
- <meta charset="UTF-8">
- <title></title>
- </head>
- <body>
- // 这是我们的 View 视图
- <p id="app">{{ message }}</p>
- <input type="text" v-model="message"/> // 输入框, 绑定了数据 message
- </body>
- <script src="js/vue.js"></script> // 引入 vue 自行下载
- <script>
- // 这是我们的 Model
- var obj = {
- message: 'Hello World!'
- }
- // 声明一个 Vue 实例 , 即 "ViewModel", 实例中传入一个对象, 用来连接 View 与 Model
- new Vue(
- el: '#app', // 将 id 为 app 的 dom 节点放进来, 即建立了与视图 view 的连接.
- data: obj // 将 obj 放入到实例的 data 属性中, 此时建立与数据 model 的连接.
- })
- // 这样就可以同时监听 view 和 model 了, 当更改 message 的时候, view 会自动改变, 同时当我们更改文本框的值的时候, 会发现 P 标签里的值也在同时改变, 这个时候就是 view 被监听使 model 改变. 这就实现了数据的双向绑定.
- </script>
- </html>
常用语法
# 文本插值
// 绑定的数据对象上 msg 属性发生了改变, 插值处的内容都会更新.
- <span>Message: {{ msg }}</span>
- <span v-text="msg"></span> // 也可以用指令的方式
- # 常用指令
指令 (Directives) 是带有 v- 前缀的特殊属性. 其实就是一种命令, 或者是规则.
v-if v-else-if v-else: 满足某个条件的时候显示.
- <body>
- <div id="app">
- <h1 v-if="age> 50">Yes!</h1> // 当年龄大于 50 的时候才渲染这个标签
- <h1 v-else-if="age> 20 && age <50">{{age}}</h1> // 当年龄大于 20 且小于 50 的时候渲染当前标签
- <h1 v-else>Yes!</h1> // 其他的情况渲染此标签
- </div>
- </body>
- <script>
- var vm = new Vue({
- el: '#app',
- data: {
- age: 80
- }
- })
- </script>
- // v-if 可单独使用, 也可和 v-else-if v-else 一起使用, 来控制不同情况下的视图.
v-show: 简单的切换 display:block 和 none, 和 v-if 不同. 带有 v-show 的元素始终会被渲染
- <h1 v-show="yes">Yes!</h1> // 如果 yes 为真就显示, 为假就不显示
- var vm = new Vue({
- el: '#app',
- data: {
- yes: true
- }
- })
总结: v-show 适用于两种状态的切换, v-if 适用于条件判断.
v-for 指令: 用于循环
- <div id="app">
- <todo-item v-for="item in groceryList">{{item.text }}</todo-item>
- </div>
- var app7 = new Vue({
- el: '#app',
- data: {
- groceryList: [
- { id: 0, text: '蔬菜' },
- { id: 1, text: '奶酪' },
- { id: 2, text: '随便其他什么人吃的东西' }
- ]
- }
- })
v-bind 指令
v-bind 指令可以在后面带一个参数, 中间用冒号隔开, 这个参数一般是 HTML 的属性, 比如 v-bind:class , 可缩写为: class, 这个 class 和原来的 class 并不冲突.
- .show{
- display: block;
- }
- <h1 class="center" v-bind:class="yes ? show : off">Yes!</h1> // 如果 yes 为真就添加名为 show 的 class, 反之添加 off
- var vm = new Vue({
- el: '#app',
- data: {
- yes: true
- }
- })
v-on 指令
专门用于绑定事件的指令, 用法和 v-blind 差不多, 比如添加点击事件 < a v-on:click="方法名 / 执行语句"> , 可直接缩写为 @click, 可直接绑定一个方法, 也可以直接使用内联语句
#修饰符
修饰符 修饰符 (Modifiers) 是以半角句号 . 指明的特殊后缀, 指明一个指令应该以特殊方式绑定. 例如,.prevent 修饰符告诉 v-on 指令对于触发的事件的时候阻止默认事件:
- <form v-on:submit.prevent="onSubmit"></form>
- # 计算属性 computed: 在正常情况下, 代码中可以直接进行简单的运算, 但是如果太多就显得难以维护. 而计算属性就是将这个逻辑提取出来, 专门来维护. 如下例子:
- <div id="example">
- {{ message.split('').reverse().join('') }}
- </div>
- <div id="example">
- <p>{{ message }}"</p>
- <p>{{ reversedMessage}}"</p>
- </div>
- var vm = new Vue({
- el: '#example',
- data: {
- message: 'Hello'
- },
- computed: {
- reversedMessage: function () {
- return this.message.split('').reverse().join('')
- }
- }
- })
# 方法 methods: 可实现和计算属性一样的功能
- <div id="example">
- <p>{{ message }}"</p>
- <p>{{ reversedMessage}}"</p>
- </div>
- var vm = new Vue({
- el: '#example',
- data: {
- message: 'Hello'
- },
- methods: {
- reversedMessage: function () {
- return this.message.split('').reverse().join('')
- }
- }
- })
方法和计算属性区别:
计算属性存在缓存, 只有依赖的变量发现改变的时候才会重新求值, 如上, 只有 message 发生改变才会重新求值, 而 methods 每次渲染都会重新执行. 所以要根据业务来选择.
# 观察 watch
只有一个一个监听数据, 只要这个数据发生变化, 就会在返回两个参数, 第一个是当前的值, 第二个是变化前的值, 每当变化的时候, 则会触发函数体的里的逻辑行为, 来进逻辑后续操作
watch: { 监听 message 的变化, 若改变执行以下语句
- message(new,old) {
- // 要执行的语句
- }
- }
- # 过滤器
过滤器在开发中会经常用到, 比如我们要显示一个日期, 但是后端给我们的数据是像这样的 3463782000 时间戳, 我们就必须做以下转换. 例如:
- {{ message | date}} // date 在这里就是个过滤器. 实际上就是一个函数, 函数的第一个参数就是 | 前面的 message, 也就是说 message 会被当做参数传入到 date 函数中进行处理, 返回的结果就是最终显示的结果, 注意过滤器函数都必须有返回值.
- new Vue({
- filters: {
- date: function (date, fmt) {
- if (!date) {
- return 'timestamp can not be null or undefined';
- }
- date = new Date(date);
- if (isNaN(date.getFullYear())) {
- return 'dateError';
- }
- if (/(y+)/.test(fmt)) {
- fmt = fmt.replace(RegExp.$1, (date.getFullYear() + '').substr(4 - RegExp.$1.length));
- }
- const o = {
- 'M+': date.getMonth() + 1,
- 'd+': date.getDate(),
- 'h+': date.getHours(),
- 'm+': date.getMinutes(),
- 's+': date.getSeconds()
- };
- for (const k in o) {
- if (new RegExp(`(${k})`).test(fmt)) {
- const str = o[k] + '';
- fmt = fmt.replace(RegExp.$1, (RegExp.$1.length === 1) ? str : padLeftZero(str));
- }
- }
- return fmt;
- }
- }
- })
- // 过滤器也可以串联. 如 {{message | filterA | filterB}} message 会当做参数传给 filterA, 处理完返回的结果又会当做参数传入 filterB, 处理完返回的就是最终结果了
过滤器分全局和局部. 全局就是整个项目都可以用到, 具体自行百度.
# 混合 mixins:
我们知道 vue 实例中会传入一个对象, 里面有方法, 计算属性等, 假如有两个 vue 实例, 他们有很多公用的东西, 那么就可以用到混合了, 混合可以当做一个 Vue 实例, 同时它又可以和任何一个
对象进行组合. 如下: am 和 vm 都需要使用方法 foo, 这个时候就可以声明一个混合来复用.
- var mixin = { // 声明一个混合
- methods: {
- foo: function () {
- console.log('foo')
- }
- }
- }
- var vm = new Vue({
- mixins: [mixin], // 引用混合
- methods: {
- bar: function () {
- console.log('bar')
- }
- }
- })
- var am = new Vue({
- mixins: [mixin],
- methods: {
- conflicting: function () {
- console.log('from self')
- }
- }
- })
- # 给一个对象注册一个不存在的属性
假如我们需要监听对象下某个不存在的属性, 那么我们可以通过 set 去创建.
全局注册: vue.set(item, 'checked', true) item.checked = true
局部注册: this.$set(item, 'checked', true)
#组件之间的通信
组件的基础就暂且不说了, 看官方也能懂, 直接说下通信, 组件之间, 有时候需要传递数据或者数据的状态, 比如我这边点了按钮, 需要父组件得到并且做出一定的改变. 所以组件之间需要通信.
这个时候就分三种情况: 父组件传递消息给子组件, 子组件传递消息给父组件, 兄弟组件之间通信
1 父组件传递数据给子组件: props
父组件
<child message="hello!"></child> // 子组件在父组件内被调用, message 是来自于父组件的数据, 直接以属性的形式传递
子组件 需要声明 props 属性来接收数据, 数据可以和 data 里的数据一样使用
- Vue.component('child', {
- // 声明 props
- props: ['message'],
- })
2 子组件传递信息给父组件: 例: 当点击按钮时, 通知父组件
父组件
- <div id="counter-event-example">
- <p>{{ total }}</p>
- <button-counter v-on:increment="incrementTotal"></button-counter> // 子组件调用被监听派发出的时间 increment, 监听到后调用 incrementTotal 方法
- <button-counter v-on:increment="incrementTotal"></button-counter>
- </div>
- new Vue({
- el: '#counter-event-example',
- data: {
- total: 0
- },
- methods: {
- incrementTotal: function () { // 若传递过来有数据, 可以直接接收 incrementTotal(value)
- this.total += 1
- }
- }
- })
子组件:
- Vue.component('button-counter', {
- template: '<button v-on:click="incrementCounter">{{ counter }}</button>',
- data: function () {
- return {
- counter: 0
- }
- },
- methods: {
- incrementCounter: function () {
- this.counter += 1
- this.$emit('increment') // 派发事件 increment, 第二个参数可以是想传递的数据 比如 this.$emit('increment', 1)
- }
- },
- })
注意: 在子组件中不要直接更改 props 的值, 不推荐也不支持, 想要用可以直接赋值给一个变量, 或者用计算属性, 如果需要改变父组件这个值怎么办呢, 就可以利用 watch 监听传来的 props 数据, 然后把这个数据赋给一个变量,
这样我们就可以操作这个变量, 再 $emit 派发事件把想要改变的数据传给父组件, 父组件再监听.
3 兄弟组件通信
var bus = new Vue() 声明 Vue 实例
- bus.$emit('id-selected', 1) // 派发事件和数据
- bus.$on('id-selected', function (id) { // 监听事件, 并在回调函数中, 接受传来的数据.
- // ...
- })
先说到这里.....
来源: https://www.cnblogs.com/moqing/p/9105864.html