乐趣区

Vue基础一

基础知识

基础环境

  • vscode
  • 所需的插件:

jshint:JS 代码检查
Beautify:代码美化(选中代码 –>format doc)
Vetur: Vue 插件
JavaScript (ES6) code snippets:ES6 语法
Auto Rename Tag:自动重命名标签
Vue-helper:Vue 提示
vscode-icons:文件夹图标
open in browser

vscode 快捷键

ctrl+k以及 ctrl+s 打开快捷键窗口,以便查看快捷键

Vue 介绍

是一套构建前后端分离的架构

Vue 的安装和使用

三种方式:

  • script 标签引用
<!-- development version, includes helpful console warnings -->
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<!-- production version, optimized for size and speed -->
<script src="https://cdn.jsdelivr.net/npm/vue"></script>
  • npm 安装
  • vue-cli 安装

Vue 体验

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <script src="../lib/vue.js"></script>
  <title>01VueStudy</title>
</head>

<body>
  <div id="app">
    <p>{{greet() }}</p>
    <p>{{username}}</p>
    <button @click="username=' 隔壁老王 '"> 更改值 </button>
  </div>
</body>
<script>
  new Vue({
    el: '#app',
    data: {username: "Hello"},
    methods: {greet() {return "你好啊"}
    }
  })
</script>

</html>

Vue 的模板语法

  • v-bind: 属性绑定
  • v-once: 在模板中只读取一次变量,后续变量更改了,不会跟着变化
  • v-html: 解析 html 标签
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <script src="../lib/vue.js"></script>
  <title>vue v-bind</title>
</head>
<body>
  <div id="app">
    <p v-once>{{username}}</p>
    <p v-html='code'>{{code}}</p>
    <button @click="username=' 隔壁老王 '"> 改变 </button>
    <img v-bind:src="logo" alt="">
  </div>
  
</body>
  <script>
    new Vue({
      el: "#app",
      data: {
        username: "Alex",
        code: "<a href='https://www.baidu.com'>BAT</a>",
        logo: "https://vuejs.org/images/logo.png"
      }
    })
  </script>
</html>

Vscode 添加自定义代码片段

  1. ctrl+shift+p
  2. 搜索 Snippets 关键字,选择 Preferance
  3. 选择 html.json,修改成如下的样子
{
 "my vue html code": {
  "prefix": "html",
  "body": [
   "<!DOCTYPE html>",
   "<html lang='en'>",
   "<head>",
   "<meta charset='UTF-8'>",
   "<meta name='viewport'content='width=device-width, initial-scale=1.0'>",
   "<meta http-equiv='X-UA-Compatible'content='ie=edge'>",
   "<script src='../lib/vue.js'></script>",
   "<title>$1</title>",
   "</head>",
   "<body>",
   "<div id='app'>",

   "</div>",
   "</body>",
   "<script>",
   "new Vue({",
   "el:'#app',",
   "data: {",
   "$2",
   "}",
   "})",
   "</script>",
   "</html>",
  ],
  "description": "my vue html code"
 }
}

属性绑定

  • 绑定 class 的两种形式
<!DOCTYPE html>
<html lang='en'>
<head>
  <meta charset='UTF-8'>
  <meta name='viewport' content='width=device-width, initial-scale=1.0'>
  <meta http-equiv='X-UA-Compatible' content='ie=edge'>
  <script src='../lib/vue.js'></script>
  <title></title>
  <style>
    .title{
      font-size: 20px;
      color: red
    }
    .main-title{font-weight: 1800;}

  </style>
</head>
<body>
  <div id='app'>
    <!-- 数组方式 -->
    <p v-bind:class="[pclass1,pclass2]">I like Vue</p>
    <!-- 对象方式 -->
    <p :class="{'title':true,'main-title':strong}"> 我是隔壁老王 </p>
    <button @click="strong=true"> 文字加粗 </button>
    <!-- 对象方式 -->
    <p :style="{backgroundColor:backgroundColor}"> 属性绑定样例 </p>
    <!-- 数组方式 -->
    <p :style="[Pstyle1,Pstyle2]"> 属性绑定样例 2 </p>
  </div>
</body>
  <script>
    new Vue({
      el: '#app',
      data: {
       pclass1: "title",
       pclass2: "main-title",
       strong: false,
       backgroundColor: "red",
       Pstyle1: {
         'background-color':'blue',
         'font-size': '30px'
       },
       Pstyle2: {"border-bottom":"2px solid #000"}
     }
    })
  </script>
</html>

使用 JS 表达式

在属性绑定和变量读取中,可以使用表达式。常见的表达式有:变量读取,变量运算,三目运算符,函数调用,取反等

<!DOCTYPE html>
<html lang='en'>
<head>
  <meta charset='UTF-8'>
  <meta name='viewport' content='width=device-width, initial-scale=1.0'>
  <meta http-equiv='X-UA-Compatible' content='ie=edge'>
  <script src='../lib/vue.js'></script>
  <title></title>
</head>
<body>
  <div id='app'>
    <div :style="{color: danger?'red':'black'}">{{message.split("").reverse().join(" ") }}</div>
    <div>{{greet() }}</div>
    <div>{{!is_adult}}</div>
  </div>
</body>
  <script>
    new Vue({
      el: '#app',
      data: {
        // 条件?条件成立的值:条件不成立的值
      // danger: true
      danger: false,
      message: "Hello World Hello China",
      is_adult: true
      },
      methods: {greet() {return "Good Morning!!"}
      }

    })
  </script>
</html>

条件判断

if 系列

<!DOCTYPE html>
<html lang='en'>
<head>
  <meta charset='UTF-8'>
  <meta name='viewport' content='width=device-width, initial-scale=1.0'>
  <meta http-equiv='X-UA-Compatible' content='ie=edge'>
  <script src='../lib/vue.js'></script>
  <title>Vue 判断 </title>
</head>
<body>
  <div id='app'>
    <p v-if="weather=='sun'">GoPark</p>
    <p v-else-if="weather='rain'">WatchMovie</p>
    <p v-else>StayHome</p>
  </div>
</body>
  <script>
    new Vue({
      el: '#app',
      data: {weather: "rain"}
    })
  </script>
</html>

多重条件使用 template

<!DOCTYPE html>
<html lang='en'>
<head>
  <meta charset='UTF-8'>
  <meta name='viewport' content='width=device-width, initial-scale=1.0'>
  <meta http-equiv='X-UA-Compatible' content='ie=edge'>
  <script src='../lib/vue.js'></script>
  <title>IF</title>
</head>
<body>
  <div id='app'>
    <template v-if="age < 18">
      <p>AAA</p>
    </template>
    <template v-else-if="age >=18 && age <= 20">
      <p>BBB</p>
    </template>

    <template v-else>
      <p>CCC</p>
    </template>   
  </div>
</body>
  <script>
    new Vue({
      el: '#app',
      data: {age: 24}
    })
  </script>
</html>

method 小例子

<!DOCTYPE html>
<html lang='en'>
<head>
  <meta charset='UTF-8'>
  <script src='../lib/vue.js'></script>
  <title>V-if</title>
</head>
<body>
  <div id='app'>
    <template v-if="loginType=='username'">
      <label> 用户名 </label>
      <input type="text" name="username" placeholder="用户名">
    </template>

    <template v-else-if="loginType=='email'">
      <label> 邮箱 </label>
      <input type="text" name="email" placeholder="email">
    </template>
    <button @click="changeLoginType"> 更换登录类型 </button>
    
  </div>
</body>
  <script>
    new Vue({
      el: '#app',
      data: {loginType: "username"},
     methods: {changeLoginType() {
         // 三目运算符
         this.loginType = this.loginType =='username'?"email":"username"
       }
     }
    })
  </script>
</html>

小结:

  1. v-if,v-else-if,v-else
  2. 如果想要某个调间下渲染多个元素,那么就要使用 template 标签
  3. Vue 默认会重用相同的标签来提高性能,如果不要重用的话,那就在对应的元素上加一个 key 属性即可

v-show 和 v -if 的区别

v-show: 是通过简单的切换 display 来渲染信息,会一次性加载所有的元素,在频繁切换的状态下推荐使用,不能在 template 标签上使用
v-if: 真正的条件渲染,如果条件更改了,会重新加载

<!DOCTYPE html>
<html lang='en'>
<head>
  <meta charset='UTF-8'>
  <meta name='viewport' content='width=device-width, initial-scale=1.0'>
  <meta http-equiv='X-UA-Compatible' content='ie=edge'>
  <script src='../lib/vue.js'></script>
  <title></title>
</head>
<body>
  <div id='app'>
    <div v-show="loginType=='username'">
      <label> 用户名 </label>
      <input type="text" name="username" placeholder="username" key="username">
    </div>

    <div v-show="loginType=='email'">
      <label> 邮箱 </label>
      <input type="text" name="email" placeholder="email" key="email">
    </div>

    <button @click='changeLoginType'> 切换登录方式 </button>

  </div>
</body>
  <script>
    new Vue({
      el: '#app',
      data: {loginType: "username"},
     methods: {changeLoginType() {this.loginType = this.loginType=='username'?'email':'username'}
     }
    })
  </script>
</html>

循环语法

  • 循环数组
<!DOCTYPE html>
<html lang='en'>
<head>
  <meta charset='UTF-8'>
  <meta name='viewport' content='width=device-width, initial-scale=1.0'>
  <meta http-equiv='X-UA-Compatible' content='ie=edge'>
  <script src='../lib/vue.js'></script>
  <title>loop</title>
</head>
<body>
  <div id='app'>
     <table>
       <thead>
         <tr>
           <th>Index</th>
            <th>bookName</th>
            <th>Author</th>
         </tr>
       </thead>
       <tbody>
         <tr v-for="book,index in books">
           <td>{{index+1}}</td>
           <td>{{book.title}}</td>
           <td>{{book.author}}</td>
         </tr>
       </tbody>
     </table>
  </div>
</body>
  <script>
    new Vue({
      el: '#app',
      data: {
        books: [
          {
          'title':'Book1',
          'author':'1'
          },
          {
            'title': 'book2',
            'author': '2'
          },
          {
            'title':'book3',
            'author':'3'
          },
          {
            'title': 'book4',
            'author': '4'
          }
        ]
       
     }
    })
  </script>
</html>
  • 循环对象
<!DOCTYPE html>
<html lang='en'>
<head>
  <meta charset='UTF-8'>
  <meta name='viewport' content='width=device-width, initial-scale=1.0'>
  <meta http-equiv='X-UA-Compatible' content='ie=edge'>
  <script src='../lib/vue.js'></script>
  <title>vue for</title>
</head>
<body>
  <div id='app'>
    <div v-for="(value,key) in person">
      {{key}} : {{value}}
    </div>
  </div>
</body>
  <script>
    new Vue({
      el: '#app',
      data: {
        person: {
          username: "alex",
          age: 18,
          homepage: "http://www.baidu.com"
        }       
     }
    })
  </script>
</html>
  • 状态保持
<!DOCTYPE html>
<html lang='en'>
<head>
  <meta charset='UTF-8'>
  <meta name='viewport' content='width=device-width, initial-scale=1.0'>
  <meta http-equiv='X-UA-Compatible' content='ie=edge'>
  <script src='../lib/vue.js'></script>
  <title>vue-for</title>
</head>
<body>
  <div id='app'>
    <div v-for="book in books" :key="book.title">
      <label> 标题:</label>
      <input type="text" :placeholder="book.title">
    </div>
    <button @click="changeBookSort"> 更改图书顺序 </button>
  </div>
</body>
  <script>
    new Vue({
      el: '#app',
      data: {
        books: [
          {
          'title':'Book1',
          'author':'1'
          },
          {
            'title': 'book2',
            'author': '2'
          },
          {
            'title':'book3',
            'author':'3'
          },
          {
            'title': 'book4',
            'author': '4'
          }
        ]       
     },
     methods: {changeBookSort() {this.books.sort(function (a,b) {return Math.random(0,1) - 0.5
         })
       }
     }
    })
  </script>
</html>

小结:

  • 默认情况下,如果数组中的顺序发生变化,或者个数比发生变化导致重新渲染,那么 vue 就会重新利用之前的元素,而不会重新排序,这样需要添加 key 属性,key只能支持 number 和 string 类型
  • 在 vue2.2+,key 是必须的

视图更新

针对数组中使用函数进行更新,有一下的方法直接触发更新
push/pop/sort/splice/concat/reverse/shift/unshift

<!DOCTYPE html>
<html lang='en'>
<head>
  <meta charset='UTF-8'>
  <meta name='viewport' content='width=device-width, initial-scale=1.0'>
  <meta http-equiv='X-UA-Compatible' content='ie=edge'>
  <script src='../lib/vue.js'></script>
  <title>View Update</title>
</head>
<body>
  <div id='app'>
    <ul>
      <li v-for="role in roles" :key="role">
        {{role}}
      </li>
    </ul>
    <button @click="update"> 更新 </button>
    <button @click="update2"> 更新 2 </button>
    <button @click="popRole"> 删除最后一个元素 </button>
    <button @click='shiftRole'> 删除第一个元素 </button>
    <button @click='unshiftRole'> 在第一个位置添加元素 </button>
    <button @click='spliceTwo'> 删除前两个元素 </button>
    <button @click="spliceChange"> 替换前三个元素中的 aaa 为 XXXX</button>
    <button @click="spliceAdd"> 在第一个之前添加元素 </button>
    <button @click=concatRole> 合并数组 </button>
  </div>
</body>
  <script>
    new Vue({
      el: '#app',
      data: {roles: ['aaa','bbb','ccc']       
     },
     methods: {
       // 直接赋值更新
       // 通过函数更新
       update() {this.roles = ['ddd']
       },
       update2() {this.roles.push("eee")
       },
       popRole() {this.roles.pop()
       },
       shiftRole() {this.roles.shift()
       },
       unshiftRole() {this.roles.unshift("AAA")
       },
       spliceTwo() {this.roles.splice(0,2)
       },
       spliceChange() {this.roles.splice(0,4,'aaa','XXXX')
       },
       spliceAdd() {this.roles.splice(0,0,"dsadsadsa")
       },
       concatRole() {this.roles = this.roles.concat(['ssss','assfa'])
       }
     }
    })
  </script>
</html>

视图更新
如果想要通过下标来更新数组中的某个值,这样是不会触发视图更新的,需要通过 Vue.set 来实现

<!DOCTYPE html>
<html lang='en'>
<head>
  <meta charset='UTF-8'>
  <meta name='viewport' content='width=device-width, initial-scale=1.0'>
  <meta http-equiv='X-UA-Compatible' content='ie=edge'>
  <script src='../lib/vue.js'></script>
  <title>updateArray</title>
</head>
<body>
  <div id='app'>
    <ul>
        <li v-for="role in roles" :key="role">
            {{role}}
         </li>
    </ul>
    <div v-for="(value,key) in users">
      {{key}}:{{value}}
    </div>
    <button @click='updateArray'> 更新 Array</button>
    <button @click='updateObj'> 更新对象 </button>
  </div>
</body>
  <script>
    new Vue({
      el: '#app',
      data: {roles:["aa","bb","cc"],
       users: {"username":"BBB"}
     },
     methods: {updateArray() {// this.roles[0] = "dsadsadsd" 不能更新
        Vue.set(this.roles,0,'dadsffdafa')
       },
       updateObj() {
         this.users.username = "asdsfasfof",
         Vue.set(this.users,'age',19)
       }
     }
    })
  </script>
</html>
退出移动版