基础原理
使用vue开发,对于新手需要了解的两个关键点是
MVVM
MVC模式变化而来,相对于MVC强调控制-模型-视图的责任分离之外,最大的特点就是引入ViewModel,支持双向绑定
 
 比如你改变一个输入框 Input 标签的值,会自动同步更新到页面上其他绑定该输入框的组件的值
组件化
页面上小到一个按钮/文本输入框/图片等等元素都可以是一个单独的文件.vue,这些小组件直接可以像乐高积木一样通过互相引用而组装起来,参考如下。
 
这样的好处在于,页面上的元素都是独立可替换的,可以实现最大的复用性和独立性。这样的好处在于,页面上的元素都是独立可替换的,可以实现最大的复用性和独立性。
安装和初始化项目
当前使用环境
node --version
v14.19.1
npm -v
6.14.16
vue2和vue3
目前大多数老项目还是vue2
 vue3相对vue2基本完全重构,解决了很多历史问题,这里不详述
 vue2和vue3实现上有很大差别,但在基础概念上没什么大的差别,对新手上手难度相差不大
 考虑到目前的应用广泛度,本教程暂时以vue2作为演示版本,后续看需求再补上vue3教程
vue-cli2 vue-cli3 vue-cli4
vue cli顾名思义,是vue提供的一套辅助命令行脚手架
 可以自动生成工程目录和框架,辅助调试和开发
 目前有多个版本,最新版本vue-cli4
- Vue CLI 2更多是依赖webpack的配置,Vue CLI 3开始设计原则是“0配置",同时提供了界面配置(vue ui),减少上手难度
- Vue CLI 4.5以下,对应的是Vue2
- Vue CLI 4.5及以上,对应的是Vue3,当然,创建项目的时候可以选择Vue2
目前推荐使用最新的cli,为了新手简单理解vue的机制,这里会先使用vue-cli2简单演示(如果不想深入了解或没有老项目,可以直接跳过),实际代码编写推荐最新vue-cli4
vue-cli2
如下安装vue
cnpm install -g vue-cli@2.9.6
查看当前版本
npm list -g vue vue-cli
/Users/wenzhou/.nvm/versions/node/v14.19.1/lib
└── vue-cli@2.9.6
简单项目
如下,使用webpack-simple模板,默认全部回车,这里简单演示选择不使用sass
 
 可以看到生成的目录结构如下,其中
- package.json和webpack.config.js分别是npm/webpack配置文件
- 核心代码在src中,index.html是入口网页,main.js是入口代码,当前main.js加载一个组件App.vue

 打开package.json如下,dependencies表明包依赖就是vue,devDependencies主要是开发打包用到webpack和对应插件的依赖;webpack.config.js是标准webpack打包文件,打开后可以看到主要是配置了各种依赖和引入vue
{
  "name": "vue-2-simple",
  "description": "A Vue.js project",
  "version": "1.0.0",
  "author": "xxx",
  "license": "MIT",
  "private": true,
  "scripts": {
    "dev": "cross-env NODE_ENV=development webpack-dev-server --open --hot",
    "build": "cross-env NODE_ENV=production webpack --progress --hide-modules"
  },
  "dependencies": {
    "vue": "^2.5.11"
  },
  "browserslist": [
    "> 1%",
    "last 2 versions",
    "not ie <= 8"
  ],
  "devDependencies": {
    "babel-core": "^6.26.0",
    "babel-loader": "^7.1.2",
    "babel-preset-env": "^1.6.0",
    "babel-preset-stage-3": "^6.24.1",
    "cross-env": "^5.0.5",
    "css-loader": "^0.28.7",
    "file-loader": "^1.1.4",
    "vue-loader": "^13.0.5",
    "vue-template-compiler": "^2.4.4",
    "webpack": "^3.6.0",
    "webpack-dev-server": "^2.9.1"
  }
}
按照如上提示,进入目录操作
- 运行npm/cnpm install安装所有依赖(dependencies中),依赖都装在同目录node_modules中
- 运行npm/cnpm run dev运行调试服务器(devDependencies中依赖安装并运行web server)

复杂项目
如下执行vue init webpack vue-2-webpack
 相对webpack-simple引入了更多生产和校验相关选项,对实际生产环境有帮助,这里简化全部默认值和No
 
 如下,默认会自动按照依赖,生成的项目功能一致,只是引入了更多实际生产代码和更多可配置项,更适合实际企业项目开发,其它不再赘述,可查看文档
 
vue-cli4
卸载老版本并安装版本
 cnpm uninstall vue vue-cli -g
 cnpm install -g @vue/cli
如下,最大的差别是Vue CLI 3开始设计原则是“0配置",隐藏了大量webpack的配置,现在webpack相关配置,通过vue.config.js来配置,参考
 相比vue-cli2 这里App中以组件化方式引用具体内容
 运行npm/cnpm run serve运行调试服务器
 
工程简单解释
如下图,打开页面http://localhost:8080/ 显示如下,到此一个基本可运行的vue项目初始化完成
 
 为了便于理解,改写App.vue如下,这就是一个标准Vue组件的写法:
- template-html语法描述模板(模板语法参考https://v2.cn.vuejs.org/v2/guide/syntax.html,和服务端渲染的模板语法功能都差不多)
- style-css描述样式
- script-js描述动作和填充模板
- data指返回的用于填充template的数据
可调试运行查看效果。
<template>
  <div id="app">
    <img src="./assets/logo.png">
    <h1>{{ msg }}</h1>
  </div>
</template>
<script>
export default {
  name: 'app',
  data () {
    return {
      msg: 'Hello Simple Vue'
    }
  }
}
</script>
<style>
h1, h2 {
  font-weight: normal;
}
</style>
运行npm/cnpm run build编译产物在同目录dist文件夹中,实际部署中只需要dist目录+index.html部署在服务端,请求index.html即可看到如下效果
 
简单使用
双向绑定
文本和属性
包括完整写法和简写,如下
<template>
  <div class="border">
    <div>属性绑定</div>
    <p>Message: {{ msg }}</p> <!-- 输出消息文本绑定msg变量 -->
    <p><a v-bind:href="url" target="_blank">绑定href</a></p> <!-- 属性href绑定到url变量上 -->
    <p><a :href="url" target="_blank">绑定href-2</a></p> <!-- 属性href绑定到url变量上简写方式 -->
    <p><a :[myprop]="url" target="_blank">绑定href-3</a></p> <!-- []代表动态参数 动态参数的缩写 -->
    <p>字符串拼接 {{ msg + 'test string' }}</p>
    <p>数字计算 {{ num % 2 }}</p>
  </div>
</template>
<script>
export default {
  name: 'CompBindAttribute',
  data() {
    return {
      msg: "Hello World",
      url: "http://www.baidu.com",
      myprop: "href",
      num: 100
    }
  }
}
</script>
class和style
可以看做属性的特殊场景,包括class激活和多值指定等
<template>
  <div class="border">
    <div>Class/Style绑定</div>
    <ul>
      <li>list1</li>
      <li>list2</li>
      <li v-bind:class="{high: isActive}">list3</li> <!--对应值isActive控制class是否激活 可简写:class-->
      <li v-bind:class="[activeClass, redClass]">list4</li><!--支持数组形式指定class 每一个元素都是变量-->
    </ul>
    <div v-bind:style="{ color: activeColor, fontSize: fontSize + 'px' }">内联样式</div> <!--内联样式 可简写:style 也支持数组方式指定-->
  </div>
</template>
<script>
export default {
  name: "CompBindClassStyle",
  data() {
    return {
      isActive: true,
      activeClass: 'high',
      redClass: 'red',
      activeColor: 'red',
      fontSize: 30
    }
  }
}
</script>
计算属性
用作复杂的属性计算优化,通过提前计算+cache可以优化性能
<template>
  <div class="border">
    <div>计算属性</div>
    <div id="example">
      {{ message }}
    </div>
    <div id="example">
      {{ message.split('').reverse().join('') }}
    </div>
    <div id="example">
      {{ reversedMessage }}
    </div>
  </div>
</template>
<script>
export default {
  name: "CompComputedAttribute",
  data() {
    return {
      message: "Hello World!!!"
    }
  },
  computed: {
    // 计算属性的 getter
    reversedMessage: function () {
      // `this` 指向 vm 实例
      return this.message.split('').reverse().join('')
    }
  }
}
</script>
流程控制
类似于服务端模板功能,增加更多html的逻辑控制语义,主要是if/else语义和for循环语义
<template>
  <div class="border">
    <div>流程控制</div>
    <h2 v-if="awesome">Vue is awesome!</h2> <!-- 注意if/else控制相关元素需要相临 -->
    <h2 v-else>Oh no 😢</h2>
    <!-- v-for 数组列表渲染 指定key标识虚拟DOM-->
    <ul id="example-1">
      <li v-for="item in items" :key="item.message">
        {{ item.message }}
      </li>
    </ul>
    <ul id="example-2">
      <li v-for="(item, index) in items" :key="item.message">
        {{ index }} - {{ item.message }}
      </li>
    </ul>
    <!-- v-for 对象列表渲染-->
    <ul id="v-for-object" class="demo">
      <li v-for="(value, name) in object" :key="name">
          {{ name }}: {{ value }}
      </li>
    </ul>
  </div>
</template>
<script>
export default {
  name: "CompProcessControl",
  data() {
    return {
      awesome: true,
      items: [
        {message: 'Foo'},
        {message: 'Bar'}
      ],
      object: {
        title: 'How to do lists in Vue',
        author: 'Jane Doe',
        publishedAt: '2016-04-10'
      }
    }
  }
}
</script>
界面交互
点击响应
通过v-on或简写方式绑定,如下
<template>
  <div class="border">
    <div>事件处理</div>
    <!--直接调用js-->
    <div id="example-1">
      <button v-on:click="counter += 1">Add 1</button> <!-- v-on绑定事件 -->
      <p>The button above has been clicked {{ counter }} times.</p>
    </div>
    <div id="example-2">
      <!-- `greet` 是在下面定义的方法名 -->
      <button v-on:click="greet">Greet</button>
      <button @click="say('hello')">Say Hello</button> <!-- 可以简写为@ -->
    </div>
    <!-- 调用响应函数 -->
  </div>
</template>
<script>
export default {
  name: "CompEventHandle",
  data() {
    return {
      counter: 0
    }
  },
  // 在 `methods` 对象中定义方法
  methods: {
    greet: function (event) {
      // `this` 在方法里指向当前 Vue 实例
      alert('Hello ' + this.name + '!')
      // `event` 是原生 DOM 事件
      if (event) {
        alert(event.target.tagName)
      }
    },
    say: function (message) {
      alert(message)
    }
  }
}
</script>
表单绑定
通过监听用户的输入事件以更新数据,并对一些极端场景进行一些特殊处理。如下,对应的表单值会和变量绑定。
<template>
  <div class="border">
    <div>表单绑定</div>
    <!--  v-model 在内部为不同的输入元素使用不同的 property 并抛出不同的事件:-->
    <!--  text 和 textarea 元素使用 value property 和 input 事件;-->
    <!--  checkbox 和 radio 使用 checked property 和 change 事件;-->
    <!--  select 字段将 value 作为 prop 并将 change 作为事件。-->
    <input v-model="message" placeholder="edit me">
    <p>Message is: {{ message }}</p>
    <input type="checkbox" id="jack" value="Jack" v-model="checkedNames">
    <label for="jack">Jack</label>
    <input type="checkbox" id="john" value="John" v-model="checkedNames">
    <label for="john">John</label>
    <input type="checkbox" id="mike" value="Mike" v-model="checkedNames">
    <label for="mike">Mike</label>
    <br>
    <span>Checked names: {{ checkedNames }}</span>
    <div id="example-4">
      <input type="radio" id="one" value="One" v-model="picked">
      <label for="one">One</label>
      <br>
      <input type="radio" id="two" value="Two" v-model="picked">
      <label for="two">Two</label>
      <br>
      <span>Picked: {{ picked }}</span>
    </div>
    <div id="example-5">
      <select v-model="selected">
        <option disabled value="">请选择</option>
        <option>A</option>
        <option>B</option>
        <option>C</option>
      </select>
      <span>Selected: {{ selected }}</span>
    </div>
  </div>
</template>
<script>
export default {
  name: "CompBindForm",
  data() {
    return {
      message: '',
      checkedNames: [],
      picked: '',
      selected: ''
    }
  }
}
</script>
参考文档
vue2
https://www.runoob.com/w3cnote/vue2-start-coding.html
 https://www.runoob.com/vue2/vue-tutorial.html
 https://v2.cn.vuejs.org/v2/guide/index.html
vue3
https://www.runoob.com/vue3/vue3-tutorial.html
 https://cn.vuejs.org/guide/introduction.html
vue cli
https://cli.vuejs.org/zh/guide/



















