Vue编程笔记

25次阅读
没有评论

共计 7270 个字符,预计需要花费 19 分钟才能阅读完成。

环境搭建

引入 Vue

下载 js 文件:

<script> 标签引入,Vue 会被注册为一个全局变量。

用谷歌浏览器打开 html 文件,切换到控制台,会出现 2 个小提示。

Vue 开发者工具

第一个小提示,安装 Vue 开发者工具后,就不会出现提示了。

如果安装后还是不行的话,右键「Vue Devtools」->「管理扩展程序」,打开「允许访问文件网址」即可。

修改全局配置

第二个小提示,需要修改全局配置:

// 阻止 vue 在启动时生成生产提示
Vue.config.productionTip = false;

脚手架自定义创建项目

安装脚手架

全局安装:npm i -g @vue/cli,如果之前安装过低版本的脚手架,想更新至最新版本的话,可先卸载当前版本再安装最新版本:npm un -g vue-cli

查看版本:vue -V

自定义创建项目

创建项目:vue create test
? Please pick a preset: Manually select features(选择自定义)
? Check the features needed for your project: Babel, Router, Vuex, CSS Pre-processors, Linter(选择需要的特性)
? Choose a version of Vue.js that you want to start the project with 2.x(这里选择 Vue2)
? Use history mode for router? (Requires proper server setup for index fallback in production) No(这里不使用历史模式,即 URL 路径中带有 #号)
? Pick a CSS pre-processor (PostCSS, Autoprefixer and CSS Modules are supported by default): Less(选择 CSS 预处理器)
? Pick a linter / formatter config: Standard(ESLint 代码检查和格式化工具,选择标准化无分号规范)
? Pick additional lint features: Lint on save(选择保存时检验)
? Where do you prefer placing config for Babel, ESLint, etc.? In dedicated config files(将 ESLint 配置文件放在单独文件中)
? Save this as a preset for future projects? No(是否保存当前配置作为将来项目的预设,这里选择 No)
? Pick the package manager to use when installing dependencies: Yarn(选择安装依赖时使用的包管理器,这里选择 Yarn)

启动项目

cd test
yarn serve

ESLint 代码规范

使用 Prettier 代码格式化工具,格式化 Vue 代码时可能出现单引号变双引号等其他问题,这时需要自定义一些配置,可在项目根目录下添加配置文件.prettierrc:

{
  "singleQuote": true,
  "semi": false,
  "trailingComma": "none"
}

调整初始化目录

删除多余的文件

  • src\assets\logo.png
  • src\components\HelloWorld.vue
  • src\views\AboutView.vue 和 src\views\HomeView.vue

修改路由配置和 App.vue

src\router\index.js:删除 HomeView 导入,删除 routes,默认路由规则设置为空数组,即:

import Vue from "vue";
import VueRouter from "vue-router";

Vue.use(VueRouter);

const router = new VueRouter({routes: []
});

export default router;

src\App.vue 修改为:

<template>
  <div id="app">
    <router-view />
  </div>
</template>

<style lang="less"></style>

新增 api 和 utils 目录

在 src 目录下新增两个目录 api 和 utils:

  • api 接口模块:发送 ajax 请求的接口模块
  • utils 工具模块:自己装的一些工具方法模块

数据代理

Object.defineProperty()方法

这个方法接收三个参数:属性所在的对象、属性的名字、一个描述符对象。

<script>
  let number = 20
  let person = {
    name: " 张三 ",
    sex: " 女 ",
  }
  Object.defineProperty(person, "age", {
    value: 18,
    enumerable: true, // 控制属性是否可枚举,默认不可枚举
    writable: true, // 控制属性是否可修改,默认不可修改
    configurable: true, // 控制属性是否可删除,默认不可删除
  })
</script>

该方法的第三个参数除了可以是数据属性,也可以是访问器属性:

<script>
  let number = 20
  let person = {
    name: " 张三 ",
    sex: " 女 ",
  }
  Object.defineProperty(person, "age", {// 当读取 person 的 age 属性时,get 函数 (getter) 会被调用,且返回值是 age 的值
    get() {return number},

    // 当修改 person 的 age 属性时,set 函数 (setter) 会被调用,且会收到修改的具体值
    set(value) {number = value},
  })
</script>

事件处理

基本使用

<body>
  <div id="root">
    <button @click="showInfo($event,666)"> 点 {{name}} 提示信息 </button>
  </div>
  <script type="text/javascript">
    Vue.config.productionTip = false;
    const vm = new Vue({
      el: "#root",
      data: {name: " 李小龙 ",},
      methods: {showInfo(event, number) {console.log(event, number);
        },
      },
    });
  </script>
</body>

事件修饰符

  1. prevent:阻止默认事件
  2. stop:阻止事件冒泡
  3. once:事件只触发一次
  4. capture:使用事件的捕获模式
  5. self:只有 event.target 是当前操作的元素时才触发事件
  6. passive:事件的默认行为立即执行,无需等待事件回调执行完毕

修饰符可以连续写:

<body>
  <div id="root" @click="showInfo">
    <a href="https://www.baidu.com/" @click.stop.prevent="showInfo"> 点我提示信息 </a>
  </div>
  <script type="text/javascript">
    Vue.config.productionTip = false;
    const vm = new Vue({
      el: "#root",
      methods: {showInfo() {alert(" 你好呀 ");
        },
      },
    });
  </script>
</body>

键盘事件

  1. 回车 => enter
  2. 删除 => delete(“删除”和“退格”键)
  3. 退出 => esc
  4. 空格 => space
  5. 换行 => tab(配合 keydown 使用)
  6. 上 => up
  7. 下 => down
  8. 左 => left
  9. 右 => right

系统修饰键:ctrl、alt、shift、meta,配合 keydown 使用。想用 keyup,还可以这样用:

// ctrl + y
@keyup.ctrl.y="showInfo"

计算属性

<div id="root">
  姓:<input type="text" v-model="firstName" /><br /><br />
  名:<input type="text" v-model="lastName" /><br /><br />
  全名:<span>{{fullName}}</span>
</div>
<script type="text/javascript">
  Vue.config.productionTip = false;
  const vm = new Vue({
    el: "#root",
    data: {
      firstName: " 张 ",
      lastName: " 三 ",
    },
    computed: {fullName() {return this.firstName + "-" + this.lastName;},
    },
  });
</script>

计算属性完整写法

<!DOCTYPE html>
<html lang="zh-CN">
  <head> </head>
  <body>
    <!-- 第一步:准备容器 -->
    <div id="app">
      姓:<input type="text" v-model="firstName" /> + 名:<input type="text" v-model="lastName" /> = <span>{{fullName}}</span><br /><br />
      <button @click="changeName"> 改名 </button>
    </div>

    <!-- 第二步:引包 -->
    <script src="vue.js"></script>

    <script>
      // 第三步:创建实例,添加配置项
      const app = new Vue({
        el: '#app',
        data: {
          firstName: '张',
          lastName: '三',
        },
        methods: {changeName() {this.fullName = '张小三'},
        },
        computed: {
          fullName: {get() {return this.firstName + this.lastName},
            set(value) {this.firstName = value.slice(0, 1)
              this.lastName = value.slice(1)
            },
          },
        },
      })
    </script>
  </body>
</html>

监视属性

<body>
  <div id="app">
    <h2> 今天天气很{{info}}</h2>
    <button @click="changeWeather"> 切换天气 </button>
  </div>

  <script>
    const app = new Vue({
      el: "#app",
      data: {isHot: true,},
      computed: {info() {return this.isHot ? " 炎热 " : " 凉爽 "},
      },
      methods: {changeWeather() {this.isHot = !this.isHot},
      },
      watch: {
        isHot: {
          immediate: true, // 初始化时让 handler 调用一下
          // 当 isHot 发生改变时调用 handler
          handler(newValue, oldValue) {console.log("isHot 被修改了 ", newValue, oldValue)
          },
        },
      },
    })
  </script>
</body>

还可以这么写:

app.$watch("isHot", {
  immediate: true,
  handler(newValue, oldValue) {console.log("isHot 被修改了 ", newValue, oldValue)
  },
})

深度监视

<script>
  const app = new Vue({
    el: "#app",
    data: {
      numbers: {
        a: 10,
        b: 20,
      },
    },
    watch: {
      numbers: {
        deep: true, // 深度监视
        handler() {console.log("numbers 改变了 ")
        },
      },
    },
  })
</script>

监视简写

watch: {isHot(newValue, oldValue) {console.log("isHot 被修改了 ", newValue, oldValue)
  },
}

还可以简写:

app.$watch("isHot", function (newValue, oldValue) {console.log("isHot 被修改了 ", newValue, oldValue)
      })

实时翻译案例

<!DOCTYPE html>
<html lang="zh-CN">
  <head> </head>
  <body>
    <!-- 第一步:准备容器 -->
    <div id="app"><textarea v-model="obj.words"></textarea>{{result}}</div>

    <!-- 第二步:引包 -->
    <script src="vue.js"></script>
    <script src="https://unpkg.com/axios/dist/axios.min.js"></script>

    <script>
      // 第三步:创建实例,添加配置项
      const app = new Vue({
        el: '#app',
        data: {
          obj: {words: '',},
          result: '',
        },
        watch: {'obj.words'(newValue) {
            // 防抖优化(延时 300ms)clearInterval(this.timer)
            this.timer = setTimeout(async () => {
              const res = await axios({
                url: 'https://applet-base-api-t.itheima.net/api/translate',
                params: {words: newValue,},
              })
              this.result = res.data.data
            }, 300)
          },
        },
      })
    </script>
  </body>
</html>

列表过滤

用 watch 实现:

<div id="app">
  <h2> 人员列表 </h2>
  <input type="text" placeholder=" 请输入名字 " v-model="keyWord" />
  <ul>
    <li v-for="(p,index) of filPersons" :key="index">
      {{p.name}}--{{p.age}}
    </li>
  </ul>
</div>

<script>
  const app = new Vue({
    el: "#app",
    data: {
      keyWord: "",
      persons: [{ id: "001", name: " 李小龙 ", age: 18},
        {id: "002", name: " 李大龙 ", age: 19},
        {id: "003", name: " 李中龙 ", age: 20},
        {id: "004", name: " 周杰伦 ", age: 21},
      ],
      filPersons: [],},
    watch: {
      keyWord: {
        immediate: true,
        handler(val) {this.filPersons = this.persons.filter((p) => {return p.name.indexOf(val) !== -1
          })
        },
      },
    },
  })
</script>

用 computed 实现:

<script>
  const app = new Vue({
    el: "#app",
    data: {
      keyWord: "",
      persons: [{ id: "001", name: " 李小龙 ", age: 18},
        {id: "002", name: " 李大龙 ", age: 19},
        {id: "003", name: " 李中龙 ", age: 20},
        {id: "004", name: " 周杰伦 ", age: 21},
      ],
    },
    computed: {filPersons() {return this.persons.filter((p) => {return p.name.indexOf(this.keyWord) !== -1
        })
      },
    },
  })
</script>

列表排序

<div id="app">
  <h2> 人员列表 </h2>
  <input type="text" placeholder=" 请输入名字 " v-model="keyWord" />
  <button @click="sortType=1"> 年龄升序 </button>
  <button @click="sortType=2"> 年龄降序 </button>
  <button @click="sortType=0"> 原顺序 </button>
  <ul>
    <li v-for="(p,index) of filPersons" :key="index">
      {{p.name}}--{{p.age}}
    </li>
  </ul>
</div>

<script>
  const app = new Vue({
    el: "#app",
    data: {
      keyWord: "",
      sortType: 0, // 0 原顺序 1 升序 2 降序
      persons: [{ id: "001", name: " 李小龙 ", age: 28},
        {id: "002", name: " 李大龙 ", age: 19},
        {id: "003", name: " 李中龙 ", age: 20},
        {id: "004", name: " 周杰伦 ", age: 11},
      ],
    },
    computed: {filPersons() {const arr = this.persons.filter((p) => {return p.name.indexOf(this.keyWord) !== -1
        })
        // 判断是否需要排序
        if (this.sortType) {arr.sort((p1, p2) => {return this.sortType == 1 ? p1.age - p2.age : p2.age - p1.age})
        }
        return arr
      },
    },
  })
</script>

正文完
post-qrcode
 0
三毛
版权声明:本站原创文章,由 三毛 于2023-08-14发表,共计7270字。
转载说明:除特殊说明外本站文章皆由CC-4.0协议发布,转载请注明出处。
评论(没有评论)