美文网首页
vue - 学习笔记

vue - 学习笔记

作者: 自走炮 | 来源:发表于2020-10-08 00:33 被阅读0次
  • 环境变量与模式
  • 设置
  • 基础
  • 过滤器 观察属性 计算属性
  • 表单绑定 表单修饰符
  • 组件
  • 路由 vue-router
  • 事件多处理
  • 其他
    • 分割杠
    • 路径
    • 图像初始未载入

环境变量与模式

  • 环境变量 .env,使用变量 VUE_APP_ 前缀
    • .env.development 开发环境
    • .env.production 生产环境
    • .env.local git 忽略
  • 模式 NODE_ENV
    • NODE_ENV=development 开发模式,用于 serve
    • NODE_ENV=production 生产模式,用于 buildtest:e2e
    • NODE_ENV=test 测试模式,用于 test:unit

设置

  • package.json
{
  "dev-build": "vue-cli-service build --mode development", // 指定模式
  "browserslist": ["> 1%", "last 2 versions", "not ie <= 8"] // 浏览器兼容性
}
  • vue.config.js
module.exports = {
  outputDir: process.env.NODE_ENV === "production" ? "" : "dist",
  baseUrl: process.env.NODE_ENV === "production" ? "/" : "/",
  publicPath: process.env.NODE_ENV === "production" ? "/" : "/",
  configureWebpack: (config) => {},
  devServer: {
    host: "0.0.0.0",
    port: 8080,
    https: false,
    hotOnly: false,
    proxy: null,
    before: (app) => {},
  }, // webpack-dev-server
  parallel: require("os").cpus().length > 1, // 多核
  pwa: {},
  pluginOptions: {},
};

基础

  • v-if 显示条件
  • v-for 循环数组
  • v-bind 绑定数据
  • v-on 事件处理
  • v-model 双向绑定

过滤器 观察属性 计算属性

<div id="myApp">
  <p>{{ item | toupper }}价格:{{ price }}円,含税价格:{{ priceInTax }}円</p>
  <button @click="btnClick1(10800)">价格改为10800円</button>
  <button @click="btnClick2(10800)">含税价格改为10800円</button>
</div>
<script>
  var myApp = new Vue({
    el: "#myApp",
    data: { item: "Switch", price: 29980 }, // 观察属性需在初始声明,计算属性不需在初始声明
    watch: {
      // 观察 price,btnClick1() 改变 price
      price: function (newVal, oldVal) {
        console.log(newVal, oldVal);
        this.priceInTax = Math.round(this.price * 1.08);
      },
    },
    computed: {
      // 计算 priceInTax
      priceInTax: {
        // 计算属性 .get(),相当于 priceInTax: function () { return this.price*1.08; },
        get: function () {
          return this.price * 1.08;
        },
        // 计算属性 .set(),btnClick2() 改变 priceInTax
        set: function (value) {
          this.price = value / 1.08;
        },
      },
    },
    filters: {
      toupper: function (value) {
        return value.toUpperCase();
      },
    },
    methods: {
      btnClick1: function (newPrice) {
        this.price = newPrice;
      },
      btnClick2: function (newPrice) {
        this.priceInTax = newPrice;
      },
    },
  });
</script>

表单绑定 表单修饰符

<div id="myApp">
  <!-- 表单复选 input[type="checkbox"] -->
  <input
    type="checkbox"
    id="生化危机7"
    value="生化危机7"
    v-model="checkedGames"
  />
  <label for="生化危机7">生化危机7</label>
  <input
    type="checkbox"
    id="模拟飞行"
    value="模拟飞行"
    v-model="checkedGames"
  />
  <label for="模拟飞行">模拟飞行</label><br />
  <p>您选择的游戏是: {{ checkedGames }}</p>
  <!-- 表单单选 input[type="radio"] -->
  <input type="radio" id="male" value="男" v-model="pickedSex" />
  <label for="male">男</label><br />
  <input type="radio" id="female" value="女" v-model="pickedSex" />
  <label for="female">女</label><br />
  <p>性别: {{ pickedSex }}</p>
  <!-- 表单下拉框单选/复选 select multiple为多选 -->
  <select v-model="likedNBAStar" multiple style="width:200px;height:200px;">
    <option>科比</option>
    <option>詹姆斯</option>
  </select>
  <p>我喜欢: {{ likedNBAStar }}</p>
  <!--表单修饰符 input[type="text"] textarea .lazy .number .trim -->
  <label for="username">用户:</label>
  <input
    type="text"
    id="username"
    v-model.lazy="username"
    @change="checkUsername($event)"
  />
  <span v-if="checkUsernameOK">可注册</span>
  <label for="age">年龄:</label>
  <input type="number" id="age" v-model.number="age" />
  <label for="content">个人简介:</label><br />
  <textarea id="content" v-model.trim="content" cols="55" rows="8"></textarea>
  <p>用户名:{{ username }}</p>
  <p>年龄:{{ age }}</p>
  <p>个人简介:{{ description }}</p>
</div>
<script>
  var myApp = new Vue({
    el: "#myApp",
    data: {
      checkedGames: [],
      pickedSex: "",
      likedNBAStar: null,
      username: "",
      checkUsernameOK: false,
      age: "",
      description: "",
    },
    methods: {
      checkUsername: function (event) {
        if (this.username.length > 0) this.checkUsernameOK = true;
        else this.checkUsernameOK = false;
        this.debugLog(event); // 事件信息
        console.log(
          event.srcElement.tagName,
          event.srcElement.id,
          event.srcElement.innerHTML,
          event.key ? event.key : ""
        );
      },
    },
  });
</script>

组件

<div id="myApp">
  <table border="1">
    <tr>
      <td>编号</td>
      <td>游戏名称</td>
    </tr>
    <!-- 表行组件 is -->
    <tr is="my-row1"></tr>
    <tr is="my-row2"></tr>
  </table>
  <div>请输入名字:<input v-model="myname" /></div>
  <custom
    :score="50"
    :pname="myname"
    :age="25"
    :detail="{ address:'earth', language:'世界语' }"
    :a="6"
    :b="12"
    v-on:add_event="getAddResult"
  ></custom>
  <p>{{ result }}</p>
  <nba-all-stars c="奥尼尔"
    >全明星阵容是:<span slot="pf">加内特</span></nba-all-stars
  >
</div>
<script>
  // 表行组件
  Vue.component("my-row1", {
    template: "<tr><td>(1)</td><td>塞尔达传说:荒野之息(3/3)</td></tr>",
  });
  Vue.component("my-row2", {
    template: "<tr><td>(2)</td><td>新马里奥赛车(4/28)</td></tr>",
  });
  Vue.component("custom", {
    template:
      "<div>今天的天气是{{ todayWeather }}</div>" +
      "<div>你好,{{ pname }},考试成绩{{ score }}分,{{ testResult }}</div>" +
      "<div>年龄:{{ this.age }}岁<br/>地址:{{ this.detail.address }}<br/>语言:{{ this.detail.language }}</div>" +
      '<div><button v-on:click="add">加</button></div>',
    // 组件数据
    data: function () {
      return { todayWeather: "雨加雪" };
    },
    // 组件参数
    props: ["score", "pname", "a", "b"],
    // 组件参数验证
    props: {
      age: {
        type: Number,
        required: true,
        validator: function (value) {
          return value >= 0 && value <= 130;
        },
      },
      detail: {
        type: Object,
        default: function () {
          return { address: "US", language: "English" };
        },
      },
    },
    computed: {
      testResult: function () {
        var strResult = "";
        if (this.score < 60) strResult = "不及格";
        else if (this.score <= 100) strResult = "优秀";
        return strResult;
      },
    },
    methods: {
      add: function () {
        var value = 0;
        value = this.a + this.b;
        this.$emit("add_event", { result: value }); // 组件事件传递,在子组件中 $emit 触发事件
      },
    },
  });
  Vue.component("nba-all-stars", {
    props: ["c"],
    template:
      '<div><slot></slot><br/>中锋:{{ c }}<br/>大前:<slot name="pf"></slot></div>', // 组件插槽
  });
  var WeatherComponent = { template: "<div>今天下雨</div>" }; // 组件局部注册,其他为全局注册
  var myApp = new Vue({
    el: "#myApp",
    data: { myname: "Koma", result: 0 },
    components: { "my-weather": WeatherComponent },
    methods: {
      // 组件事件传递,在父组件中 v-on 侦听事件
      getAddResult: function (pval) {
        this.result = pval.result;
      },
    },
  });
</script>

路由 vue-router

// src/router/index.js 文件
import Vue from "vue";
import Router from "vue-router"; // 导入 router
import HelloWorld from "@/components/HelloWorld";
Vue.use(Router); // 注册 router
// 导出 router 对象
export default new Router({
  routes: [
    {
      path: "/player/:uid/:nationality", // 动态路由
      props: true, // 多参数路由需开 props
      name: "Player",
      component: Player,
      components: { myPart1: Part1, myPart2: Part2 }, // 多路由,在 router-view 标签中调用 name="myPart1"
      // 嵌套路由
      children: [
        { path: "profile", component: PlayerProfile },
        { path: "stats", component: PlayerStats },
      ],
      alias: "/aboutme", // 别名,地址栏显示
      redirect: "/player/1", // 重定向,地址栏隐藏原地址
    },
  ],
});

// src/main.js 文件
import router from "./router"; // 导入 router 对象
new Vue({
  el: "#app",
  router, // 注册 router 对象
  components: { App },
  template: "<App/>",
});
<template>
  <div id="app">
    <button @click="btnClick(1)">User1</button>
    <router-link :to="{ name: 'Player', params: { uid: 2 }}">User2</router-link>
    <router-link :to="{ path: '/player/3/stats' }">User3</router-link>
    <router-link to="/player/4/usa">User4</router-link>
    <router-view />
    <!-- 路由出口,多路由调用 name="myPart1" -->
  </div>
</template>
<script>
  export default {
    methods: {
      btnClick(uid) {
        this.$router.push({ path: "/player/${uid}/stats" });
        this.$router.push({ name: "Player", params: { uid: uid } });
        this.$router.push({ path: "/player", query: { uid: uid } }); // url-get 写法
        this.$router.go(-1); // url 历史控制
      },
    },
  };

  // Player.vue 文件
  export default {
    name: "Player",
    props: ["uid", "nationality"], // 调用 {{uid}} 和 {{nationality}} 接收数据,或调用 {{$route.params.uid}} 和 {{$route.params.nationality}} 接收数据
    mounted() {}, // 子路由初次渲染
    // 子路由再次渲染
    beforeRouteUpdate(to, from, next) {
      next();
    },
  };
</script>

事件多处理

<div id="hello-vue">
  <h2>点击次数:{{ count }}</h2>
  <button @click="btnClick1(), btnClick2($event)">点它加1</button>
</div>
<script>
  const app = Vue.createApp({
    data() {
      return { count: 0 };
    },
    methods: {
      btnClick1() {
        this.count++;
      },
      btnClick2(event) {
        console.log(event);
        console.log(event.target);
        console.log(event.target.attributes.class);
        console.log(event.target.innerText);
      },
    },
  });
  app.mount("#hello-vue");
</script>
  • 事件修饰符
    • .prevent: event.preventDefault()
    • .stop: event.stopPropagation()
    • .capture
    • .self
    • .once
    • .passive
  • 按键修饰符
    • .enter
    • .tab
    • .delete: 同时捕获删除和退格
    • .esc
    • .space
    • .up
    • .down
    • .left
    • .right
    • .ctrl
    • .alt
    • .shift
    • .meta: mac command

其他

分割杠

<template v-for="(tag, index) in job.tags">
  <i v-if="index > 0"></i>{{ tag }}
</template>

路径

<template v-for="(item, index) in path">
  <a :href="item.url">{{ item.title }}</a>
  <i v-if="index < path.length - 1"></i>
</template>

图像初始未载入

<div v-if="user">
  <img :src="user.avatar" />
</div>

相关文章

网友评论

      本文标题:vue - 学习笔记

      本文链接:https://www.haomeiwen.com/subject/gcdgrktx.html