01-入门

1. 环境介绍与搭建

  1. Angular
  2. React
  3. Vue:渐进式的javascript框架,可以嵌入到应用程序里,也可以单独来使用

特性:

  1. Approachable:亲切友善的;易理解的;可接近的
  2. Versatile:多才多艺的;通用的,万能的;多面手的
  3. Performant
  4. Maintainable:可维持的;可主张的;可维修的
  5. Testable
  6. Reactive:响应式的,数据的变更会影响视图的更新

1. 安装node

node -v
image-20220513204350816

2. 安装Vue_Cli

# 注:node版本必须大于等于8.9
# vue-cli3.x:
npm install -g @vue/cli
sudo cnpm install -g @vue/cli

# 旧版本桥接工具
# vue-cli2.x:
npm install -g @vue/cli-init
sudo cnpm install -g @vue/cli-init

# 版本
vue -V
vue --version
image-20220514084611141
image-20220514084851341

3. 创建项目

vue init webpack my-project

# 注:安装依赖的时候,选择最后一个,就是自己安装

cd my-project

cnpm install

# 启动项目
npm start | npm run dev
image-20220514090131581
image-20220514090249268

1. 启动项目

image-20220514090927029

4. 工程目录

  1. build:webpack相关的配置文件。Base基础的、dev开发的、prod生产的
  2. config:也是配置,开发模式,生产模式
    • 在webpack4中已经不需要这样的配置了,只需要在命令行中加入model即可
  3. src:原码文件(程序员关心)
    • assets:静态资源文件,图片、字体
    • components:组件
    • App.vue:主组件
    • main.js:入口文件
  4. static:静态文件,项目需求文档
  5. .babelrc:es6解析的依赖文件,vue解析的依赖文件
  6. .postcssrc.js:css的配置文件
  7. index.html:主入口
image-20220513204553531
image-20220513204607661

5. 拓展

1. Homebrew

# 安装结果查看
brew -v
node -v
vue -V
image-20220513205205134

2. 基础指令

main.js 入口文件

// 引入vue
import Vue from 'vue'
// 引入主组件
import App from './App'

// 生产模式的提示
Vue.config.productionTip = false

// 创建Vue实例
new Vue({
  // 加载元素 index.html <div id="app">
  el: '#app',
  // 加载组件
  components: { App },
  // 加载模板
  template: '<App/>'
})
<template>
  <div class="hello"> <!-- 标签下只能且必须有一个root标签 -->

  </div>
</template>

 



  1. Mustache: 只能存在单行语句
  2. v-once:只能渲染一次 const只能一次不能改变
  3. v-html:解析HTML结构
  4. v-bind:指令:解析属性中的对象
  5. v-bind:简写 :
  6. v-if:条件渲染
  7. v-show:条件渲染
  8. v-for:列表渲染

1. 条件渲染

v-if, v-show

  1. v-if 是“真正”的条件渲染,因为它会确保在切换过程中条件块内的事件监听器和子组件适当地被销毁和重建
  2. v-if 也是惰性的:如果在初始渲染时条件为假,则什么也不做——直到条件第一次变为真时,才会开始渲染条件块
  3. 相比之下,v-show 就简单得多——不管初始条件是什么,元素总是会被渲染,并且只是简单地基于 CSS 进行切换
  4. 一般来说,v-if 有更高的切换开销,而 v-show 有更高的初始渲染开销。因此,如果需要非常频繁地切换,则使用 v-show 较好;如果在运行时条件很少改变,则使用 v-if 较好

2. 列表渲染

<!-- 渲染数组。()中顺序不能变,推荐加key -->
<ul>
  <li v-for="(item,index) in names" :key="index">{{ index }}-{{ item.name }}-{{ item.age }}</li>
</ul>
<!-- 渲染单个对象 -->
<ul>
  <li v-for="(value,key,index) in obj" :key="index">{{ value }}-{{ key }}-{{ index }}</li>
</ul>

3. 事件处理

@click="clickHandler('哈哈',$event)"
helloArr.push(["hello4"])
helloArr.unshift(["hello4"])
  1. 事件改变data数据,data数据改变会引起视图的变化
  2. 事件传递参数。$event
  3. 数组更新检测。pushunshift

HelloWorld.vue

<template>
  <div class="hello">
    <!--模板语法,Mustache 只能存在单语句-->
    {{ "哈哈" }}

    {{ 20 + 1 }}

    {{ "ok" ? 'YES' : 'NO' }}

    {{ "hello".split('').reverse().join('') }}

    {{ msg }}

    <!--只能渲染一次-->
    <p v-once>{{ msg }}</p>

    <!--解析HTML结构-->
    <div v-html="hello"></div>

    <!-- v-bind指令(解析属性中的对象)简写(:) -->
    <a :href="url">{{ url_name }}</a>

    <!--动态样式,也可以组合-->
    <div :class="divClass">容器</div>
    <div :class="div2Class+'-1'">容器1</div>

    <!--条件渲染-->
    <div v-if="flag">孙悟空</div>
    <div v-else>通臂猿猴</div>

    <!--条件渲染,没有else概念-->
    <div v-show="flag">真·三国无双</div>

    <!--渲染数组。()中顺序不能变,推荐加key-->
    <ul>
      <li v-for="(item,index) in names" :key="index">{{ index }}-{{ item.name }}-{{ item.age }}</li>
    </ul>
    <!--渲染单个对象-->
    <ul>
      <li v-for="(value,key,index) in obj" :key="index">{{ value }}-{{ key }}-{{ index }}</li>
    </ul>

    <!-- v-on:click 事件$event的传递-->
    <button @click="clickHandler('哈哈',$event)" type="button" name="button">按钮</button>

    <!--数组更新检测,改变原数组,才可以引起视图更新-->
    <ul>
      <li v-for="item in helloArr">{{ item }}</li>
    </ul>
    <button @click="addHandler" type="button" name="button">添加</button>
  </div>
</template>

<script>
export default {
  name: 'HelloWorld',
  // state
  data() {
    return {
      msg: 'Welcome to Your Vue.js App',
      hello: "<h3>Hello H3</h3>",
      url_name: "百度",
      url: "http://baidu.com",
      divClass: 'isActive',
      div2Class: "list",
      flag: false,
      names: [
        {
          name: "iwen",
          age: 20
        },
        {
          name: "ime",
          age: 200
        },
        {
          name: "ice",
          age: 2000
        }
      ],
      obj: {
        name: "iwen",
        age: 20
      },
      helloArr: ["hello1", "hello2", "hello3"]
    }
  },
  methods: {
    clickHandler(data, event) {
      console.log(data);
      console.log(event);
      // 改变data中的数据
      this.flag = !this.flag;
    },
    addHandler() {
      // push()
      // pop()
      // shift()
      // unshift()
      // splice()
      // sort()
      // reverse()
      this.helloArr.push("hello")
      this.helloArr.unshift("helloz")
      console.log(this.helloArr.concat(["hello4", "hello5"]));
    }
  }
}
</script>

<style scoped>

</style>

3. 计算属性

  • 计算属性缓存 vs 方法
  • 可以将同一函数定义为一个方法而不是一个计算属性。两种方式的最终结果确实是完全相同的
  • 不同的是计算属性是基于它们的依赖进行缓存的。计算属性只有在它的相关依赖发生改变时才会重新求值。这就意味着只要 msg 还没有发生改变,多次访问 getMsg() 计算属性会立即返回之前的计算结果,而不必再次执行函数

4. 动态Class,Style

<!-- 数组中既有属性,也有对象 -->
<div class="old" :class="[ isActive ? active + '12': 'no_active', { helloC: cssAttr }]">
  应用中的样式
</div>

<!--内联样式
    不要提取到下面,内联就是在上面-->
<div :style="{ color: style_css, fontSize: '40px' }">
  style
</div>

5. 表单与侦听器

  • v-model指令在表单<input>, <textarea>, <select>元素上创建双向数据绑定
  • 表单输入绑定

修饰符:

  1. .lazy 回车才会有响应。回车的同时失去焦点。有效的避免网络请求的次数。
  2. .number 数字
  3. .trim 去空格

watch:监听事件

VueDamo.vue

<template lang="html">
  <div>
    <!--Mustache-->
    {{ msg }}
    <!--计算属性-->
    {{ getMsg }}
    <!--方法-->
    {{ mMsg() }}

    <!--动态class
        1. 不会覆盖原有class
        2. 对象{}的key不能为变量
        3. cssObj
        4. 数组-->
    <div class="old" :class="{ active: cssAttr, 'txt': cssAttr }">
      cssAttr
    </div>

    <div :class="cssObj">
      cssObj
    </div>
    <button @click="changeCss" type="button" name="button">改变css</button>

    <div :class="[ isActive ? activeClass : '', errorClass ]">
      cssArray
    </div>

    <!-- 数组中既有属性,也有对象 -->
    <div class="old" :class="[ isActive ? active + '12': 'no_active', { helloC: cssAttr }]">
      应用中的样式
    </div>

    <!--内联样式
        不要提取到下面,内联就是在上面-->
    <div :style="{ color: style_css, fontSize: '40px' }">
      style
    </div>


    <div class="myInput">
      <label>
        <!--
        .lazy 回车、失去焦点
        .number 数字
        .trim 清除空格-->
        <input v-model="inputMsg" type="text" name="" value="">
      </label>
      <p>{{ inputMsg }}</p>

      <input type="checkbox" id="checkbox" v-model="checked">
      <label for="checkbox">{{ checked }}</label>
    </div>

  </div>
</template>

<script>
export default {
  name: "vuedemo",
  data() {
    return {
      // 计算属性
      msg: "hello",
      // :class
      cssAttr: true,
      // cssObj
      cssObj: {
        'c1': true,
        'c2': true
      },
      // cssArray
      isActive: true,
      activeClass: 'activeClass',
      errorClass: 'errorClass',
      active: "active1",

      // 内联样式
      style_css: "green",

      // watch
      checked: true,
      inputMsg: "默认数据",
    }
  },
  // 实时监听数据变化
  watch: {
    // 和变量名一致
    inputMsg(data) {
      console.log(data)
      if (data === "100") {
        this.inputMsg = "符合条件"
      }
    }
  },
  // 计算属性
  computed: {
    getMsg() {
      // 如果数据没有被改变,则不会重新计算。结果会被缓存
      return this.msg.split('').reverse().join('')
    }
  },
  methods: {
    // 方法
    mMsg() {
      return this.msg.split('').reverse().join('')
    },
    changeCss() {
      this.cssObj.c1 = !this.cssObj.c1
      this.cssObj.c2 = !this.cssObj.c2
      this.cssAttr = !this.cssAttr
      this.isActive = !this.isActive
    },
  }
}
</script>

<style lang="css">
.active {
  color: red;
}

.txt {
  font-size: 30px;
}
</style>