vue快速入门

421 阅读8分钟

vue基本概念

vue是什么?

  • 是一套用于构建用户界面的 渐进式框架

什么是渐进式?

  • 逐渐进步,想用什么就用什么,不必全部使用

什么是库和框架

  • :封装的属性或方法
  • 框架:拥有自己的规则和元素,比库更强大

什么是MVVM?

MVVM通过数据双向绑定让数据自动地双向同步 不再需要操作DOM

  • M: 模型(Model):对应 data 中的数据 -(data里定义)
  • V: 视图(View):模板 - (HTML页面)
  • VM: 视图模型(ViewModel):Vue实例对象 -(vue.js源码)

图解

1.png

  • V(修改视图) -> M(数据自动同步)
  • M(修改数据) -> V(视图自动同步)

@vue/cli 脚手架

  • 全局安装@vue/cli包
 npm i @vue/cli -g
  • @vue/cli是vue官方提供的一个全局模块包,用于快速创建脚手架项目

@vue/cli 创建项目启动服务

1.创建项目

//vue create是命令, vuecli-demo是文件夹名
vue create vuecli-demo
  • 项目不能带 大写字母,中文和特殊符号

2.选择模板

  • 可以上下箭头选择, 弄错了ctrl+c停止创建重来

8.png

  • 根据自己的需求选择对应的版本,按住电脑上下键选择,敲回车

  • 如下界面就成功了 9.png

  • 进入脚手架项目下, 启动内置更新本地服务器

cd vuecil-demo

npm run serve
//或
yarn serve
  • 你会看到如下界面

10.png

@vue/cli 目录和代码分析

vuecil-demo           //项目目录
    ├── node_modules  // 项目依赖的第三方包
    ├── public        // 静态文件目录
      ├── favicon.ico // 浏览器小图标
      └── index.html  // 单页面的html文件(网页浏览的是它)
    ├── src           // 业务文件夹
      ├── assets      // 静态资源
        └── logo.png  // vue的logo图片
      ├── components  // 组件目录
        └── HelloWorld.vue // 欢迎页面vue代码文件 
      ├── App.vue     // 整个应用的根组件
      └── main.js     // 入口js文件
    ├── .gitignore    //git提交忽略配置
    ├── babel.config.js  // babel配置
    ├── package.json // 依赖包列表
    ├── README.md   // 项目说明
	└── yarn.lock    // 项目包版本锁定和缓存地址
  • 主要文件及含义
node_modules         //都是下载的第三方包
public/index.html//浏览器运行的网页
src/main.js//webpack打包的入口文件
src/App.vue//vue项目入口页面
package.json//依赖包列表文件

@vue/cli 自定义配置

  • @vue/cli用的vue.config.js, 在src下配置
/* 覆盖webpack的配置 */
module.exports = {
  devServer: { // 自定义服务配置
    open: true, // 自动打开浏览器
    port: 3000
  },
  lintOnSave:false  //关闭eslint检查
}
  • eslint: 代码的检查工具,一种规范,例如:多个空格,或者声明的变量未使用都会报错,自己写一些小的demo或者初学者建议关闭它,不然你会怀疑人生

Vue中有2种数据绑定的方式

  • 单向绑定(v-bind):数据只能从data流向页面。
  • 双向绑定(v-model):数据不仅能从data流向页面,还可以从页面流向data 注意

1.双向绑定一般都应用在表单类元素上(如:input、select等)

2.v-model:value 可以简写为 v-model,因为v-model默认收集的就是value值。

Vue指令

插值表达式

  • 语法 {{ 表达式 }}

  • 在 DOM 标签中,直接插入内容

<template>
  <div>
    <h1>{{ msg }}</h1>
    <h2>{{ obj.name }}</h2>
    <h3>{{ obj.age > 18 ? '成年' : '未成年' }}</h3>
  </div>
</template>

<script>
export default {
  // data 里面专门用来声明变量
  data() { // 格式固定, 定义vue数据之处
    return {  // key相当于变量名
      msg: "hello, vue",
      obj: {
        name: "小vue",
        age: 5
      }
    }
  }
}
</script>

  • DOM 中插值表达式赋值, vue的变量必须在data里声明

v-bind: ----单项数据绑定

单向绑定(v-bind):数据只能从data流向页面

  • 给 DOM 标签属性设置 vue 变量的值

  • 语法:

    v-bind:属性名="vue变量"

  • 简写:

    :属性名="vue变量"

<!-- vue指令-v-bind属性动态赋值 -->
<a v-bind:href="url">我是a标签</a>
<img :src="imgSrc">

v-model:----双向数据绑定

  • 把value属性和vue数据变量, 双向绑定到一起

  • 语法: v-model="vue数据变量"

  • 双向数据绑定

    • 数据变化 -> 视图自动同步

    • 视图变化 -> 数据自动同步

重点:

  • 双向绑定一般都应用在表单类元素上(如:input、select等)

  • 遇到复选框, v-model的变量值

    • 非数组 - 关联的是复选框的checked属性

    • 数组 - 关联的是复选框的value属性

<div>
    <!-- 
    	v-model:是实现vuejs变量和表单标签value属性, 双向绑定的指令
    -->
    <div>
      <span>用户名:</span>
      <input type="text" v-model="username" />
    </div>
    <div>
      <span>密码:</span>
      <input type="password" v-model="pass" />
    </div>
    <div>
      <span>来自于: </span>
      <!-- 下拉菜单要绑定在select上 -->
      <select v-model="from">
        <option value="北京市">北京</option>
        <option value="南京市">南京</option>
        <option value="天津市">天津</option>
      </select>
    </div>

总结

  • 特别注意: v-model, 在input[checkbox]的多选框状态
  • 变量为非数组, 则绑定的是checked的属性(true/false) - 常用于: 单个绑定使用
  • 变量为数组, 则绑定的是他们的value属性里的值 - 常用于: 收集勾选了哪些值

v-model修饰符

语法:

  • v-model.修饰符="vue数据变量"

    • .number 以parseFloat转成数字类型

    • .trim 去除首尾空白字符

    • .lazy 在change时触发而非inupt时

<template>
  <div>
    <div>
      <span>年龄:</span>
      <input type="text" v-model.number="age">
    </div>
    <div>
      <span>人生格言:</span>
      <input type="text" v-model.trim="motto">
    </div>
    <div>
      <span>自我介绍:</span>
      <textarea v-model.lazy="intro"></textarea>
    </div>
  </div>
</template>

v-text和v-html

  • 更新DOM对象的innerText/innerHTML

语法:

  • v-text="vue数据变量"
  • v-html="vue数据变量"
<template>
  <div>
    <p v-text="str"></p>
    <p v-html="str"></p>
  </div>
</template>

<script>
export default {
  data() {
    return {
      str: "<span>我是一个span标签</span>"
    }
  }
}
</script>

区别

  • v-text把值当成普通字符串显示
  • v-html把值当成标签进行解析显示

v-show和v-if

  • 控制标签的隐藏或出现

  • 语法:

    • v-show="vue变量"
    • v-if="vue变量"
  • 原理

    • v-show 用的display:none隐藏 (频繁切换使用)
    • v-if 直接从DOM树上移除
  • 高级

    • v-else使用
<template>
  <div>
    <h1 v-show="isOk">v-show的盒子</h1>
    <h1 v-if="isOk">v-if的盒子</h1>

    <div>
      <p v-if="age > 18">我成年了</p>
      <p v-else>还得多吃饭</p>
    </div>
  </div>
</template>

<script>
export default {
  data() {
    return {
      isOk: true,
      age: 15
    }
  }
}
</script>

v-for

  • 列表渲染, 所在标签结构, 按照数据数量, 循环生成

  • 语法

    • v-for="(值, 索引) in 目标结构"
    • v-for="值 in 目标结构"
  • 目标结构:

    • 可以遍历数组 / 对象 / 数字 / 字符串 (可遍历结构)
  • 注意:

    v-for的临时变量名不能用到v-for范围外

<template>
  <div id="app">
    <div id="app">
      <!-- v-for 把一组数据, 渲染成一组DOM -->
      <!-- 口诀: 让谁循环生成, v-for就写谁身上 -->
      <p>学生姓名</p>
      <ul>
        <li v-for="(item, index) in arr" :key="item">
          {{ index }} - {{ item }}
        </li>
      </ul>

      <p>学生详细信息</p>
      <ul>
        <li v-for="obj in stuArr" :key="obj.id">
          <span>{{ obj.name }}</span>
          <span>{{ obj.sex }}</span>
          <span>{{ obj.hobby }}</span>
        </li>
      </ul>
     </div> 
 </template>     

v-on:----事件处理

-给标签绑定事件

  • 语法

    • v-on:事件名="要执行的==少量代码=="
    • v-on:事件名="methods中的函数"
    • v-on:事件名="methods中的函数(实参)"
  • 简写: @事件名="methods中的函数"

<!-- vue指令:   v-on事件绑定-->
<p>你要买商品的数量: {{count}}</p>
<button v-on:click="count = count + 1">增加1</button>
<button v-on:click="addFn">增加1个</button>
<button v-on:click="addCountFn(5)">一次加5件</button>

<button @click="subFn">减少</button>

<script>
    export default {
        // ...其他省略
        methods: {
            addFn(){ // this代表export default后面的组件对象(下属有data里return出来的属性)
                this.count++
            },
            addCountFn(num){
                this.count += num
            },
            subFn(){
                this.count--
            }
        }
    }
</script>

v-on修饰符

语法:

  • @事件名.修饰符="methods里函数"

    • .stop - 阻止事件冒泡
    • .prevent - 阻止默认行为
    • .once - 程序运行期间, 只触发一次事件处理函数
<template>
  <div @click="fatherFn">
    <!-- vue对事件进行了修饰符设置, 在事件后面.修饰符名即可使用更多的功能 -->
    <button @click.stop="btn">.stop阻止事件冒泡</button>
    <a href="http://www.baidu.com" @click.prevent="btn">.prevent阻止默认行为</a>
    <button @click.once="btn">.once程序运行期间, 只触发一次事件处理函数</button>
  </div>
</template>

<script>
export default {
  methods: {
    fatherFn(){
      console.log("father被触发");
    },
    btn(){
      console.log(1);
    }
  }
}
</script>

v-on按键修饰符

语法:

  • @keyup.enter - 监测回车按键
  • @keyup.esc - 监测返回按键

2.png

动态class

  • 用v-bind给标签class设置动态的值

语法:

  • :class="{类名: 布尔值}"
<template>
  <div>
    <!-- 语法:
      :class="{类名: 布尔值}"
      使用场景: vue变量控制标签是否应该有类名
     -->
    <p :class="{red_str: bool}">动态class</p>
  </div>
</template>

<script>
export default {
  data(){
    return {
      bool: true
    }
  }
}
</script>

<style scoped>
  .red_str{
    color: red;
  }
</style>

总结: 就是把类名保存在vue变量中赋予给标签

动态style

  • 给标签动态设置style的值 语法

  • :style="{css属性: 值}"

<template>
  <div>
    <!-- 动态style语法
      :style="{css属性名: 值}"
     -->
    <p :style="{backgroundColor: colorStr}">动态style</p>
  </div>
</template>

<script>
export default {
  data(){
    return {
      colorStr: 'red'
    }
  }
}
</script>

总结: 动态style的key都是css属性名

filters----过滤器

  • 过滤器就是一个 函数,只能用在, 插值表达式和v-bind表达式

注意点

  • 要定义到 filters 节点下,本质是一个函数

  • 在过滤器函数中, 一定要有 return 值

  • 在过滤器的形参中,可以获取到 “管道符” 前面待处理的那个值

  • 如果 全局过滤器和局部过滤器名字一致,此时按照 就近原则,调用的是局部过滤器

  • 语法示例:

1.全局

  • 每个 .vue 组件都可以使用

    • Vue.filter("过滤器名称",function()

2.局部

  • 只能在自己的 .vue 组件中使用

    • filters:{      "过滤器名称"(){}

    }

<template>
  <div>
    <p>原来的样子: {{ msg }}</p>
    <!-- 
      语法: {{ 值 | 过滤器名字 }}
     -->
    <p>使用翻转过滤器: {{ msg | reverse }}</p>
    <p :title="msg | toUp">鼠标长停</p>
  </div>
</template>
<script>
export default {
  data(){
    return {
      msg: 'Hello, Vue'
    }
  },
  
  filters: {
    toUp (val) {
      return val.toUpperCase()
    }
  }
}
</script>


全局注册最好在main.js中注册, 一处注册到处使用

watch : 侦听器

  • 可以侦听data/computed属性值改变
侦听器格式
  1. 方法格式的侦听器

    • 缺点1:无法在刚进入页面的时候,自动触发
    • 缺点2:如果侦听的是一个对象,对象的属性发生了变化,不会触发侦听器
  2. 对象格式的侦听器

    • 好处1:可以通过 immediate : true,让侦听器自动触发
    • 好处2:可以通过 deep :true,开启深度监听对象每个属性的变化

-语法:

watch: {
    "被侦听的属性名" (newVal, oldVal){
        
    }
}
  • 代码示例
<template>
  <div>
    <input type="text" v-model="name">
  </div>
</template>

<script>
export default {
  data(){
    return {
      name: ""
    }
  },
  // 目标: 侦听到name值的改变
  /*
  语法:
    watch: {
      变量名 (newVal, oldVal){
        // 变量名对应值改变这里自动触发
      }
    }
  */
  watch: {
    // newVal: 当前最新值
    // oldVal: 上一刻值
    name(newVal, oldVal){
      console.log(newVal, oldVal);
    }
  }
}
</script>

侦听器-深度侦听和立即执行

  • 侦听复杂类型, 或者立即执行侦听函数
  • 语法:
watch: {
    "要侦听的属性名": {
        immediate: true, // 立即执行
        deep: true, // 深度侦听复杂类型内变化
        handler (newVal, oldVal) {
            
        }
    }
}

-代码示例

<template>
  <div>
    <input type="text" v-model="user.name">
    <input type="text" v-model="user.age">
  </div>
</template>

<script>
export default {
  data(){
    return {
      user: {
        name: "",
        age: 0
      }
    }
  },
  // 目标: 侦听对象
  /*
  语法:
    watch: {
      变量名 (newVal, oldVal){
        // 变量名对应值改变这里自动触发
      },
      变量名: {
        handler(newVal, oldVal){

        },
        deep: true, // 深度侦听(对象里面层的值改变)
        immediate: true // 立即侦听(网页打开handler执行一次)
      }
    }
  */
  watch: {
    user: {
      handler(newVal, oldVal){
        // user里的对象
        console.log(newVal, oldVal);
      },
      deep: true,
      immediate: true
    }
  }
}
</script>

总结: immediate立即侦听, deep深度侦听, handler固定方法触发

computed:计算属性

  • 一个数据, 依赖另外一些数据计算而来的结果

  • 特点:

    • 定义的时候,要定义为 方法
    • 在使用计算属性时候,当普通的属性使用即可
  • 好处:

    • 实现了代码的复用
    • 只要计算属性中依赖的数据源变化了,计算属性会自动重新求值
  • 原理:

底层借助了Objcet.defineproperty方法提供的getter和setter

  • 语法示例:

    //简写
    computed:{
        "计算属性"(){
            
        }
    }
    // 完整写法
    computed:{
        // 自定义函数名称
        "计算属性名":{
          set(val){
            //
          },
          get(){
           //
          }
        }
    
  • 注意点:

    • 计算属性的值有缓存

    • 计算属性 一定要写return

    • 如果计算属性要被修改,那必须写set函数去响应修改,且set中要引起计算时依赖的数据发生改变

还在更新中