夏以乔 發表於 2020-9-7 07:51:00

一个后端开发的 Vue 笔记【入门级】

<p><img src="//p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/c3f5fd2b292b4aba8da617bfaf147390~tplv-k3u1fbpfcp-zoom-1.image" alt="" loading="lazy"></p>
<h1 id="一-前言">一 前言</h1>
<p>最近找了些教程,顺带着趴在官网上,看了看 Vue 的一些内容,入门的一些概念,以及基础语法,还有一些常用的操作,瞄了一眼,通篇文字+贴了部分代码 9000 多字,入门语法什么的还是很好理解的,以前也有一定做小程序的基础,感觉还是很相似的,不过对于一些稍复杂的点,感觉还是总结的不够细致,例如插槽,和计算属性等,平时前端的东西看的也不是很多,学习过程中整理的笔记,和大家一起分享交流!欢迎各位大大交流意见~</p>
<h1 id="二-初始-vue">二 初始 Vue</h1>
<h2 id="一-vue-概念理解">(一) Vue 概念理解</h2>
<h3 id="1-vuejs-是什么">(1) Vue.js 是什么</h3>
<p>Vue (读音 /vjuː/,类似于 <strong>view</strong>) 是一套用于构建用户界面的<strong>渐进式框架</strong>。与其它大型框架不同的是,Vue 被设计为可以自底向上逐层应用。Vue 的核心库只关注视图层,不仅易于上手,还便于与第三方库或既有项目整合。</p>
<h3 id="2-渐进式框架是什么">(2) 渐进式框架是什么</h3>
<p>看了一些教程以及文章,简单理解的渐进式框架就三个字<strong>【不强求】</strong>,Vue并不强求你用它的所有内容(功能特性),用户完全可以根据自己情况进行选择,使用其部分即可。</p>
<p>这一块某乎上有一个比较好的答案,很容易度娘到,贴了部分</p>
<blockquote>
<p>vue即主张较少,也就是说可以在原有系统上面,引入vue直接就可以当jquery用,使用 vue,你可以在原有大系统的上面,把一两个组件改用它实现,当 jQuery 用;也可以整个用它全家桶开发</p>
</blockquote>
<h2 id="二-mvvm-架构">(二) MVVM 架构</h2>
<p>正式学习 Vue 前我们首先还需要了解一个基于前端的架构模式,也就是 MVVM ,它是 Model-View-ViewMode 的简写,其关系简单的描述为下图:</p>
<div align="center">
        <img src="//p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/ff58572d768a495d9d1e2fc081a37a8e~tplv-k3u1fbpfcp-zoom-1.image" style="zoom: 80%">
</div>
<ul>
<li>
<p>Model(模型层):表示 Javascript 数据对象</p>
</li>
<li>
<p>View(视图层):表示 DOM,也可以简单理解为前端展示的内容</p>
</li>
<li>
<p>ViewModel:连接视图和数据,即用于双向绑定数据与页面</p>
</li>
</ul>
<p>在 MVVM 架构中,视图和数据是没有办法直接进行沟通的,只能通过 ViewModel 来做一个中间关系,<strong>ViewModel 可以观察到数据的变化,然后更新视图内容,亦或者监听到视图的变化,并能通知数据发生改变</strong></p>
<p>后面我马上会写一个入门的小案例,可以一起来体会一下它的特点!</p>
<h2 id="三-vue-的优点">(三) Vue 的优点</h2>
<p><strong>1、体积小</strong></p>
<ul>
<li>压缩后33K</li>
</ul>
<p><strong>2、更高的运行效率</strong></p>
<ul>
<li>基于虚拟dom一种可以预先通过 javascript 进行各种计算,把最终的 DOM操作计算出来并优化的技术,由于这个DOM操作属于预处理操作,并没有真实的操作DOM,所以 叫做虚拟DOM。</li>
</ul>
<p><strong>3、双向数据绑定</strong></p>
<ul>
<li>让开发者不用再去操作 dom 对象,把更多的精力投入到业务逻辑上</li>
</ul>
<p><strong>4、生态丰富、学习成本低</strong></p>
<ul>
<li>市场上拥有大量成熟、稳定的基于 vue.js 的 ui 框架、常用组件!</li>
<li>拿来即用实现快速开发</li>
<li>对初学者友好、入门容易、学习资料多</li>
</ul>
<h2 id="四-入门案例">(四) 入门案例</h2>
<p>编写 Vue 你可以选择使用 Vscode 、 HBuilder 、sublime、Webstrom、甚至 IDEA 都是可以的,自行选择就好了</p>
<p>首先我们需要引入 Vue,你可以去官网直接 down 下文件,进行一个本地的引入,类似引入 jQuery,或者使用一个网络的引用,例如下文中,在官网中就可以找到这种引入或下载的地址</p>
<p>可以看到,引入后,我们通过 new 的这种形式创建了一个 Vue 的实例,其中通过 el 找到 id 值为 hello 的 div 进行绑定,在 data 中进行一个赋值,而在div 中 通过两组大括号来对数据进行回显</p>
<p>如果你有一些微信小程序的基础的话,其实可以发现,这两者结构看起来似乎有一些相似的</p>
<pre><code class="language-html">&lt;!DOCTYPE html&gt;
&lt;html lang="en"&gt;
&lt;head&gt;
&lt;meta charset="UTF-8"&gt;
&lt;title&gt;Title&lt;/title&gt;
&lt;/head&gt;
&lt;body&gt;

&lt;div id="hello"&gt;
&lt;h2&gt;{{content}}&lt;/h2&gt;
&lt;/div&gt;

&lt;script src="https://cdn.jsdelivr.net/npm/vue@2.6.11"&gt;&lt;/script&gt;
&lt;script&gt;
var vm = new Vue({
      el: "#hello",
      data:{
      content: "Hello Vue!"
      }
})
&lt;/script&gt;

&lt;/body&gt;
&lt;/html&gt;
</code></pre>
<p>回显数据肯定是没问题的,我们试着在控制台修改 content 的值,可以看到随之页面也就发生改变了</p>
<div align="center">
        <img src="//p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/ed46d479b696471d84958846f0ceaf19~tplv-k3u1fbpfcp-zoom-1.image" style="zoom: 80%">
</div>
<blockquote>
<p>我们已经成功创建了第一个 Vue 应用!看起来这跟渲染一个字符串模板非常类似,但是 Vue 在背后做了大量工作。现在数据和 DOM 已经被建立了关联,所有东西都是<strong>响应式的</strong>。我们要怎么确认呢?打开你的浏览器的 JavaScript 控制台 (就在这个页面打开),并修改 <code>app.message</code> 的值,你将看到上例相应地更新。</p>
<p>注意我们不再和 HTML 直接交互了。一个 Vue 应用会将其挂载到一个 DOM 元素上 (对于这个例子是 <code>#app</code>) 然后对其进行完全控制。那个 HTML 是我们的入口,但其余都会发生在新创建的 Vue 实例内部。—— Vue 官网</p>
</blockquote>
<h1 id="三-vue-基本语法">三 Vue 基本语法</h1>
<h2 id="一-声明式渲染">(一) 声明式渲染</h2>
<p>如果有接触过 Thymeleaf 这样的模板,你可以看出来,上面的 Vue 案例就是采用了一个简洁模板语法,即两组大括号包裹值,来声明式声明式地将数据渲染进 DOM 的系统,这其实和 Thymeleaf 中的 $ 加一组大括号 是相似的</p>
<p>我们还有一种绑定元素的方式:即使用指令</p>
<pre><code class="language-html">&lt;div id="hello-2"&gt;
&lt;span v-bind:title="content"&gt;
    鼠标悬停几秒钟查看此处动态绑定的提示信息!
&lt;/span&gt;
&lt;/div&gt;

&lt;script src="https://cdn.jsdelivr.net/npm/vue@2.6.11"&gt;&lt;/script&gt;
&lt;script&gt;
var vm = new Vue({
      el: "#hello-2",
      data:{
      content: '页面加载于 ' + new Date().toLocaleString()
      }
})
&lt;/script&gt;
</code></pre>
<p>观察结果,我们将鼠标悬停在文字上方,被绑定的数据就会出现</p>
<div align="center">
        <img src="//p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/7e60ad44161044869e1374e750c2ec28~tplv-k3u1fbpfcp-zoom-1.image" style="zoom: 80%">
</div>
<p>你看到的 <code>v-bind</code> attribute 被称为<strong>指令</strong>。指令带有前缀 <code>v-</code>,以表示它们是 Vue 提供的特殊 attribute,代码的意思就是将这个元素节点的 <code>title</code> attribute 和 Vue 实例的 <code>content</code> property 保持一致”</p>
<p>如果你在控制台进行修改 vm.content 的值,绑定的数据依旧会发生变化</p>
<p>注:使用 v-bind 需要头部引入一个约束</p>
<pre><code class="language-html">&lt;html lang="en" xmlns:v-bind="http://www.w3.org/1999/xhtml"&gt;
</code></pre>
<p>如果使用 IDEA 安装 Vue.js 插件 会有提示补全</p>
<h2 id="二-条件判断">(二) 条件判断</h2>
<p>条件判断使用的指令就是 <code>v-if</code> 、<code>v-else-if</code>、<code>v-else</code></p>
<p>来看两个例子,首先是对于 true 或者 false 的判断</p>
<pre><code class="language-html">&lt;div id="hello-3"&gt;
&lt;h2 v-if="isBoy"&gt;是男孩&lt;/h2&gt;
&lt;h2 v-else&gt;是女孩&lt;/h2&gt;

&lt;/div&gt;

&lt;script src="https://cdn.jsdelivr.net/npm/vue@2.6.11"&gt;&lt;/script&gt;
&lt;script&gt;
var vm = new Vue({
      el: "#hello-3",
      data:{
      isBoy: true
      }
})
&lt;/script&gt;
</code></pre>
<p>默认显示是男孩,我们接着在控制台修改为false</p>
<div align="center">
        <img src="//p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/afc597d918db4c8196776149b933d70e~tplv-k3u1fbpfcp-zoom-1.image" style="zoom: 80%">
</div>
<p>接着是对于值的判断,我们拿一个比较成绩的小例子,不过对数值的约束还是不够严谨的,仅仅为了讲解 if 这个例子,明白意思就行</p>
<pre><code class="language-html">&lt;div id="hello-3"&gt;
&lt;h2 v-if="score &lt; '60'"&gt;成绩不及格&lt;/h2&gt;
&lt;h2 v-else-if="score &gt;= '60' &amp;&amp; score &lt; '80'"&gt;成绩及格&lt;/h2&gt;
&lt;h2 v-else&gt;成绩优秀&lt;/h2&gt;

&lt;/div&gt;

&lt;script src="https://cdn.jsdelivr.net/npm/vue@2.6.11"&gt;&lt;/script&gt;
&lt;script&gt;
var vm = new Vue({
      el: "#hello-3",
      data:{
          score: 66
      }
})
&lt;/script&gt;
</code></pre>
<p>在结果中继续修改看看</p>
<div align="center">
        <img src="//p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/f9cf6dbb39864e72aa5d0fa6f80b7abd~tplv-k3u1fbpfcp-zoom-1.image" style="zoom: 80%">
</div>
<h2 id="三-循环">(三) 循环</h2>
<p>通过 <code>v-for</code> 就可以进行循环遍历,真例如 java 中的 增强for只不过是把 冒号 换成了 in,students 对应 data 中的数组名,student 代表其中的每一项,通过 XXX.xx 的形式取出具体的属性值</p>
<pre><code class="language-html">&lt;div id="hello-4"&gt;
&lt;li v-for="student in students"&gt;
    {{student.name}}
&lt;/li&gt;
&lt;/div&gt;

&lt;script src="https://cdn.jsdelivr.net/npm/vue@2.6.11"&gt;&lt;/script&gt;
&lt;script&gt;
    var vm = new Vue({
      el: "#hello-4",
      data: {
            students: [{name: '张三'}, {name: '李四'}, {name: '王五'}]
      }
    })
&lt;/script&gt;
</code></pre>
<p>试着在控制台 push 一个新的,同样会更新出来</p>
<div align="center">
        <img src="//p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/2d71e93f1bd341ab99bb38e0ecf209a3~tplv-k3u1fbpfcp-zoom-1.image" style="zoom: 80%">
</div>
<p>说明:这里演示的只是最基本的一种情况,很多时候,若遍历的数组中为对象,且对象有多个值,例如含有 id 这样的值,一般会将这种唯一的 id 值作为 key 值,例如:</p>
<pre><code class="language-html">&lt;div v-for="item in items" v-bind:key="item.id"&gt;
&lt;!-- 内容 --&gt;
&lt;/div&gt;
</code></pre>
<blockquote>
<p>为了给 Vue 一个提示,以便它能跟踪每个节点的身份,从而重用和重新排序现有元素,你需要为每项提供一个唯一 <code>key</code> attribute:</p>
<p>建议尽可能在使用 <code>v-for</code> 时提供 <code>key</code> attribute,除非遍历输出的 DOM 内容非常简单,或者是刻意依赖默认行为以获取性能上的提升。</p>
</blockquote>
<h2 id="四-事件绑定">(四) 事件绑定</h2>
<p>经常我们需要通过点击一些按钮或者标签组件等,使得用户可以与应用进行交互,也就是进行事件绑定,在 Vue 中我们可以通过 <code>v-on</code> 指令添加一个事件监听器来进行</p>
<p>注:使用 v-on 引入约束</p>
<pre><code class="language-html">&lt;html lang="en" xmlns:v-on="http://www.w3.org/1999/xhtml"&gt;
</code></pre>
<p>示例代码</p>
<pre><code class="language-html">&lt;div id="hello-5"&gt;
&lt;button v-on:click="helloWorld"&gt;你好世界&lt;/button&gt;
&lt;/div&gt;

&lt;script src="https://cdn.jsdelivr.net/npm/vue@2.6.11"&gt;&lt;/script&gt;
&lt;script&gt;
    var vm = new Vue({
      el: "#hello-5",
      data: {
            content: "Hello World !"
      },
      methods: {
            helloWorld: function () {
                alert(this.content);
            }
      }
    })
&lt;/script&gt;
</code></pre>
<p>可以看到,通过 <code>v-on:click</code> 就将 helloWorld 这个事件绑定了,而事件的具体逻辑需要定义在 Vue 对象的 methods 中</p>
<h2 id="五-双向绑定">(五) 双向绑定</h2>
<p>早在开篇介绍 MVVM 架构模式的时候,图中就提到了 View 和 ViewModel 之间的双向绑定,通俗的说就是<strong>:当数据发生变化时,视图也变化,而当视图发生变化的时候,数据也跟着变化</strong></p>
<p>其实在前面的基本语法中,我们已经能很明显的体会到了前半句,即修改 data 中的数据,从而引起视图中的变化,我们这里就重点提一下后半句</p>
<p>首先,Vue 提供了 <code>v-model</code> 指令,它能轻松实现表单输入和应用状态之间的双向绑定</p>
<p>从常见的表单中的几种形式来讲,我们可以使用 <code>v-model</code> 指令在表单的 <code>input</code> 、<code>textarea&gt;</code>、<code>select</code>等上进行数据的双向绑定,它可以根据控件类型选取正确的方法来更新元素</p>
<p>不过使用 <code>v-model</code> 指令后会忽略表单原先的 value、checked、selected 等的初始值,而总将 Vue 实例中的数据最为数据源</p>
<p><strong>input 中 ,输入文本</strong></p>
<pre><code class="language-html">&lt;div id="hello-6"&gt;
输入: &lt;input type="text" v-model="content" &gt; 输出: {{content}}
&lt;/div&gt;

&lt;script src="https://cdn.jsdelivr.net/npm/vue@2.6.11"&gt;&lt;/script&gt;
&lt;script&gt;
    var vm = new Vue({
      el: "#hello-6",
      data: {
            content: "Hello World !"
      },
    })
&lt;/script&gt;
</code></pre>
<p>在输出的位置使用两组大括号进行 content 这个值的回显我们之前就已经能做到了,而我们在 input 的属性中使用 v-model 进行对于 content 的绑定,这样就可以使得输入框中输入的值可以直接影响 data 中 content 的值,即随着你 input 中输入值的修改,随之输出位置的内容也会变化</p>
<div align="center">
        <img src="//p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/0f5526d095b6468484a4fc3a46442b04~tplv-k3u1fbpfcp-zoom-1.image" style="zoom: 80%">
</div>
<p><strong>input 中 ,单选框</strong></p>
<pre><code class="language-html">&lt;div id="hello-6"&gt;
性别:
&lt;input type="radio" name="gender" value="男" v-model="gender"&gt;男
&lt;input type="radio" name="gender" value="女" v-model="gender"&gt;女
输出: {{gender}}
&lt;/div&gt;

&lt;script src="https://cdn.jsdelivr.net/npm/vue@2.6.11"&gt;&lt;/script&gt;
&lt;script&gt;
    var vm = new Vue({
      el: "#hello-6",
      data: {
            gender: '男'
      },
    })
&lt;/script&gt;
</code></pre>
<p>效果显示</p>
<div align="center">
        <img src="//p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/e54201e1c89e402ea0adecd02d2f95c3~tplv-k3u1fbpfcp-zoom-1.image" style="zoom: 80%">
</div>
<p><strong>select 中</strong></p>
<pre><code class="language-html">&lt;div id="hello-6"&gt;
&lt;select v-model="choose"&gt;
    &lt;option value="" disabled&gt;---请选择---&lt;/option&gt;
    &lt;option&gt;A-苹果&lt;/option&gt;
    &lt;option&gt;B-樱桃&lt;/option&gt;
    &lt;option&gt;C-西瓜&lt;/option&gt;
&lt;/select&gt;
输出: {{choose}}
&lt;/div&gt;

&lt;script src="https://cdn.jsdelivr.net/npm/vue@2.6.11"&gt;&lt;/script&gt;
&lt;script&gt;
    var vm = new Vue({
      el: "#hello-6",
      data: {
            choose: ''
      },
    })
&lt;/script&gt;
</code></pre>
<div align="center">
        <img src="//p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/7c37ebcdc99f445eb3ab1f1ae0641d4e~tplv-k3u1fbpfcp-zoom-1.image" style="zoom: 80%">
</div>
<h2 id="六-vue组件">(六) Vue组件</h2>
<p>Vue 中组件也是一个很重要的概念,例如一个页面中,头部、底部、侧边栏、主内容区 都可以看做一个一个组件,不过有一些组件是固定的,例如头部,还有一些是变换的例如内容区</p>
<p>Vue 中就允许我们使用小型、独立和通常可复用的组件构建大型应用</p>
<div align="center">
        <img src="//p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/27827193d49443a5b9bf48a613e0da7f~tplv-k3u1fbpfcp-zoom-1.image" style="zoom: 80%">
</div>
<p>注:实际都是创建 .vue 模板文件,并不会用直接在页面中书写的这种形式,仅为讲解方便</p>
<p>直接拿一个简单,不过还算相对完善的案例来进行讲解‘</p>
<p>先说一下最终我们想干嘛,例如 div 或者 input 等等 都是一个一个标签,我们现在向做的就是通过创建自定义组件模板,自定义出一个这样的标签,我们在需要的地方只需要引用这个标签,我们就可以达到显示出模板中想要的效果,达到抽取复用的效果</p>
<p>首先使用 Vue.component.......这样的格式创建组件,在其中 ideal-20 就是组件标签的名字, template 就代表模板中的内容,props 代表我们在引用处传入的参数名</p>
<p>接着在一个已经绑定好的 hello-7 的 div 中引入自定义组件标签 ideal-20,而我们想要遍历 data 中的 fruits 数组,在 ideal-20 属性中进行 for 遍历即可,同时我们需要将每一项通过 <code>v-bind:ideal="item"</code> 绑定参数到组件模板中,因为数组不是一个普通的数组,所以赋 id 为 key值</p>
<pre><code class="language-html">&lt;div id="hello-7"&gt;
&lt;ideal-20 v-for="item in fruits" v-bind:ideal="item" v-bind:key="item.id"&gt;&lt;/ideal-20&gt;
&lt;/div&gt;

&lt;script src="https://cdn.jsdelivr.net/npm/vue@2.6.11"&gt;&lt;/script&gt;

&lt;script&gt;
    // 定义名为 todo-item 的新组件
    Vue.component('ideal-20', {
      props: ['ideal'],
      template: '&lt;li&gt;{{ideal.name}}&lt;/li&gt;'
    })
    var vm = new Vue({
      el: "#hello-7",
      data: {
            fruits: [
                {id: 0, name: '苹果'},
                {id: 1, name: '樱桃'},
                {id: 2, name: '山竹'}
            ]
      }
    })
&lt;/script&gt;
</code></pre>
<p>效果展示</p>
<div align="center">
        <img src="//p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/6e74a0c8a6b74289b33c3b59e1fe725a~tplv-k3u1fbpfcp-zoom-1.image" style="zoom: 80%">
</div>
<h2 id="七-axios-入门">(七) Axios 入门</h2>
<p>首先我们需要提一下,为什么要用这个东西呢?</p>
<p>我们在以前传统的开发中,我们一般会使用 Ajax 进行通信,而 Vue,js 作为一个视图层框架,并不支持 Ajax 的通信功能,所以可以使用 Axios 来实现 Ajax 的异步通信</p>
<p>首先看一下它的特点:</p>
<ul>
<li>从浏览器中创建 XMLHttpRequests</li>
<li>从 node.js 创建 http 请求</li>
<li>支持 Promise API</li>
<li>拦截请求和响应</li>
<li>转换请求数据和响应数据</li>
<li>取消请求</li>
<li>自动转换 JSON 数据</li>
<li>客户端支持防御 XSRF</li>
</ul>
<p>首先我们拿一段 json 来模拟数据</p>
<pre><code class="language-json">{
"name": "BWH_Steven",
"blog": "www.ideal-20.cn",
"about": {
    "country": "中国",
    "phone": "13888888888"
},
"students": [
    {
      "id": 0,
      "name": "张三"
    },
    {
      "id": 1,
      "name": "李四"
    },
    {
      "id": 2,
      "name": "王五"
    }
]
}
</code></pre>
<p>通过下图我们就可以知道 我们可以将代码写到 mounted()中去</p>
<div align="center">
        <img src="//p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/ce2cdb426afc43d1b203f1f7b15e5645~tplv-k3u1fbpfcp-zoom-1.image" style="zoom: 80%">
</div>
<p>接着就是使用的代码了</p>
<p>首先除了引入 Vue 还需要引入 Axios 的 CDN,在 mounted() 方法中,去拿到这个json文件,同时将 response.data 也就是拿到的值,赋值给我们在 data() 中定义的 info 中</p>
<p>注意:data 和 data() 是不一样的</p>
<p>接着在绑定好的 hello-8 div 中就可以调用回显了</p>
<p>说明:为什么给 v-clock 添加了一个样式呢,这是因为,显示数据的过程是先显示出<code>{{info.name}}</code> 这样的字样,拿到值后,再去渲染,如果网速慢的情况下可以看到 info.name 的,体验不是很好</p>
<pre><code class="language-html">&lt;!DOCTYPE html&gt;
&lt;html lang="en" xmlns:v-on="http://www.w3.org/1999/xhtml"&gt;
&lt;head&gt;
&lt;meta charset="UTF-8"&gt;
&lt;title&gt;Title&lt;/title&gt;
&lt;style&gt;
    {
      display: none;
    }
&lt;/style&gt;
&lt;/head&gt;
&lt;body&gt;
&lt;div id="hello-8" v-clock&gt;
&lt;div&gt;{{info.name}}&lt;/div&gt;
&lt;div&gt;{{info.blog}}&lt;/div&gt;
&lt;div&gt;{{info.about.country}}&lt;/div&gt;
&lt;div&gt;{{info.about.phone}}&lt;/div&gt;
&lt;div&gt;{{info.students.name}}&lt;/div&gt;
&lt;/div&gt;

&lt;script src="https://cdn.jsdelivr.net/npm/vue@2.6.11"&gt;&lt;/script&gt;
&lt;script src="https://unpkg.com/axios/dist/axios.min.js"&gt;&lt;/script&gt;

&lt;script&gt;

    var vm = new Vue({
      el: "#hello-8",
      data() {
            return {
                info: {}
            }
      },
      mounted() {
            axios.get("../json/data.json").then(response =&gt; (this.info = response.data));
      }
    })
&lt;/script&gt;

&lt;/body&gt;
&lt;/html&gt;
</code></pre>
<h2 id="八-计算属性">(八) 计算属性</h2>
<p>这一段,我认为官方文档说的还是比较清楚的</p>
<p>模板内的表达式非常便利,但是设计它们的初衷是用于简单运算的。在模板中放入太多的逻辑会让模板过重且难以维护。例如:</p>
<pre><code class="language-html">&lt;div id="example"&gt;
{{ message.split('').reverse().join('') }}
&lt;/div&gt;
</code></pre>
<p>在这个地方,模板不再是简单的声明式逻辑。你必须看一段时间才能意识到,这里是想要显示变量 <code>message</code> 的翻转字符串。当你想要在模板中多包含此处的翻转字符串时,就会更加难以处理。</p>
<p>所以,对于任何复杂逻辑,你都应当使用<strong>计算属性</strong>。</p>
<pre><code class="language-html">&lt;div id="hello-9"&gt;
&lt;p&gt;原始数据: "{{ message }}"&lt;/p&gt;
&lt;p&gt;翻转数据: "{{ reversedMessage }}"&lt;/p&gt;
&lt;/div&gt;


&lt;script src="https://cdn.jsdelivr.net/npm/vue@2.6.11"&gt;&lt;/script&gt;

&lt;script&gt;
    var vm = new Vue({
      el: '#hello-9',
      data: {
            message: 'Hello'
      },
      computed: {
            // 计算属性的 getter
            reversedMessage: function () {
                // `this` 指向 vm 实例
                return this.message.split('').reverse().join('')
            }
      }
    })
&lt;/script&gt;
</code></pre>
<p>结果:</p>
<p>原始数据: "Hello"</p>
<p>翻转数据: "olleH"</p>
<p>这里我们声明了一个计算属性 <code>reversedMessage</code>。我们提供的函数将用作 property <code>vm.reversedMessage</code> 的 getter 函数:</p>
<pre><code class="language-js">console.log(vm.reversedMessage) // =&gt; 'olleH'
vm.message = 'Goodbye'
console.log(vm.reversedMessage) // =&gt; 'eybdooG'
</code></pre>
<p>你可以打开浏览器的控制台,自行修改例子中的 vm。<code>vm.reversedMessage</code> 的值始终取决于 <code>vm.message</code> 的值。</p>
<p>你可以像绑定普通 property 一样在模板中绑定计算属性。Vue 知道 <code>vm.reversedMessage</code> 依赖于 <code>vm.message</code>,因此当 <code>vm.message</code> 发生改变时,所有依赖 <code>vm.reversedMessage</code> 的绑定也会更新。而且最妙的是我们已经以声明的方式创建了这种依赖关系:计算属性的 getter 函数是没有副作用 (side effect) 的,这使它更易于测试和理解。</p>
<p><strong>计算属性和方法的区别 ?</strong></p>
<p>看到这里,你会不会觉得,貌似我用方法也可以实现这种效果啊,将具体的业务逻辑放在定义的方法中,但是他们最大的区别是<strong>计算属性是基于它们的响应式依赖进行缓存的</strong>,也就是说,我们上文中所依赖的 message 不发生改变,reversedMessage 会马上获取之前的结果,就不用再次执行函数了,计算属性可以帮我们节省大量的性能开销,不过如果我们并不希望出现缓存内容,就可以使用方法来代替它</p>
<h2 id="九-插槽-slot">(九) 插槽 Slot</h2>
<blockquote>
<p>在 2.6.0 中,我们为具名插槽和作用域插槽引入了一个新的统一的语法 (即 v-slot 指令)。它取代了 slot 和 slot-scope 这两个目前已被废弃但未被移除且仍在文档中的 attribute。新语法的由来可查阅这份 RFC。</p>
</blockquote>
<p>这块写的太浅了,不看也罢</p>
<p>插槽就是子组件给父组件一个占位符即 <code>&lt;slot&gt;&lt;/slot&gt;</code> 父组件就能在这个占位符,填一些模板或者 HTML 代码</p>
<p>简单点理解就是组件套组件</p>
<p>就像下面我定义了三个组件,ideal是父组件,在其中用 slot 进行占位,同时用 name 属性指向到了这两个子组件 ideal-title 和 ideal-content,而为了子组件中显示的数据来自服务器(模拟)所以需要动态地显示,即通过传参(前面讲解组件模板有说过),配合遍历等读出 data 中的数据即可</p>
<pre><code class="language-html">&lt;div id="hello-10"&gt;
&lt;ideal&gt;
    &lt;ideal-title slot="ideal-title" v-bind:title="title"&gt;&lt;/ideal-title&gt;
    &lt;ideal-content slot="ideal-content" v-for="contentItem in contents" v-bind:content="contentItem"&gt;&lt;/ideal-content&gt;
&lt;/ideal&gt;
&lt;/div&gt;


&lt;script src="https://cdn.jsdelivr.net/npm/vue@2.6.11"&gt;&lt;/script&gt;

&lt;script&gt;
    Vue.component("ideal", {
      template: '&lt;div&gt;\
                  &lt;slot name="ideal-title"&gt;&lt;/slot&gt;\
                      &lt;ul&gt;\
                        &lt;slot name="ideal-content"&gt;&lt;/slot&gt;\
                      &lt;/ul&gt;\
                   &lt;/div&gt;'
    })
   
    Vue.component("ideal-title", {
      props: ['title'],
      template: '&lt;div&gt;{{title}}&lt;/div&gt;'
    })
   
    Vue.component("ideal-content", {
      props: ['content'],
      template: '&lt;li&gt;{{content}}&lt;/li&gt;'
    })

    var vm = new Vue({
      el: '#hello-10',
      data: {
            title: "理想二旬不止",
            contents: ["Java", "Linux", "数据库"]
      }
    })
&lt;/script&gt;
</code></pre>
<p>结果如下:</p>
<div align="center">
        <img src="//p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/87f2bc1b73a64a97b12bdb73d9c0d33c~tplv-k3u1fbpfcp-zoom-1.image" style="zoom: 80%">
</div>
<h1 id="四-vue-入门">四 Vue 入门</h1>
<h2 id="一-创建-vue-cli-项目">(一) 创建 Vue-cli 项目</h2>
<p>Vue-cli 是官方提供的一个用于快速创建 Vue 项目的脚手架,可以简单的理解为 Maven ,即创建时选择一个骨架那种感觉,能让开发更加便捷</p>
<h3 id="1-准备">(1) 准备</h3>
<h4 id="a安装-nodejs">A:安装 Node.js</h4>
<ul>
<li>Node.js 去官网或者中文网进行下载</li>
</ul>
<p>cmd 下输入 <code>node -v</code> ,出现版本号即正常,输入 <code>npm -v</code> 同样出现版本号即正常</p>
<ul>
<li>将 Node.js 的镜像调整为淘宝镜像加速(cnpm)</li>
</ul>
<pre><code class="language-shell"># -g 代表全局安全 推荐此方法
npm install cnpm -g

# 还有一种办法就是每次使用 npm 都在后面加一串字符串,不推荐
npm install --registry=https://registry.npm.tabao.org
</code></pre>
<p>安装后打开此路径(abc是我这台机器的用户名,根据自己的来):</p>
<p><code>C:\Users\abc\AppData\Roaming\npm\node_modules</code></p>
<p>正常情况下里面会有安装好的 cnpm,接着我们就开始安装 vue-cli</p>
<h4 id="b安装-vue-cli">B:安装 vue-cli</h4>
<pre><code class="language-shell">cnpm install vue-cli -g
</code></pre>
<p>安装后在 npm 文件夹下打开 cmd 输入 <code>vue-list</code> ,若出现下图这种星状内容,则完毕</p>
<div align="center">
        <img src="//p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/ceee985fd03a42aeaf2ab8550fd60025~tplv-k3u1fbpfcp-zoom-1.image" style="zoom: 80%">
</div>
<h3 id="c创建-vue-cli-程序">C:创建 vue-cli 程序</h3>
<p>自己在想要的位置创建一个目录,选择基于 webpack 的 vue 应用程序</p>
<p>此文件夹下的 cmd 中输入命令</p>
<pre><code class="language-shell">vue init webpack vue_02_myvue
</code></pre>
<p>输入一些基本信息,例如 项目名 作者名</p>
<p>下面的内容如果有选项的回车配合 n(也就是no)进行</p>
<div align="center">
        <img src="//p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/c1cc15331f5440ab9978757c455df02d~tplv-k3u1fbpfcp-zoom-1.image" style="zoom: 80%">
</div>
<p>这时,它会询问你是否自动执行 npm install(如下),是的话则会自动安装一些依赖,点击否,需要自行再输入命令安装,所以选择是就行了</p>
<pre><code class="language-shell">Should we run npm install for you after the project has been created? (recommended) npm
</code></pre>
<p>完成之后,项目中的 node_modules 就会多出很多很多依赖</p>
<p>再接着,它又会提醒初始化好了,你如果想启动就可以执行这两条,第一句是从外面的文件夹进入到我自定义的那个项目文件夹中,第二句则是启动</p>
<div align="center">
        <img src="//p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/b0e9e5acda774e54bfe16e2664a22d87~tplv-k3u1fbpfcp-zoom-1.image" style="zoom: 80%">
</div>
<p>出现如果所示内容则启动成功,通过后面的地址和端口就可以访问</p>
<div align="center">
        <img src="//p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/90d3a36581de4a80b45cd8ff98dc4abe~tplv-k3u1fbpfcp-zoom-1.image" style="zoom: 80%">
</div>
<p>找个编辑器看一下,我用 IDEA Open进这个文件夹来,就可以进行修改了,具体的代码文件还是在 src 目录下,同时还可以配置 IDEA 的 Terminal 为有管理员权限的 cmd 或者终端,能更便捷一些</p>
<p><strong>如何快速创建项目</strong></p>
<ul>
<li>
<p>可以通过 HBuilder 进行相对快速的创建项目,其新建中直接就可以创建vue 项目 以及终端运行</p>
</li>
<li>
<p>在想创建项目的目录下终端输入 vue ui 进入图形界面(此方法需要 vue-cli 版本为 3.x ,通过 vue --version 查询到 vue-cli 的版本 例如为 2.9.6 是不能使用的,可用的命令可以通过 vue -h 查看 )</p>
</li>
</ul>
<h2 id="二-简单认识-webpack">(二) 简单认识 Webpack</h2>
<h3 id="1-认识安装">(1) 认识安装</h3>
<p>盖菜我们创建 vue 项目的时候,选择的是 webpack进行打包,但是都是自动化的过程,我们手动的操作一下,能更好的理解</p>
<blockquote>
<p>webpack是一个现代 Javascript应用程序的静态模块打包器( module bundler)。当webpack处理应用程序时,它会递归地构建一个依赖关系 Dependency graph),其中包含应用程序需要的毎个模块,然后将所有这些模块打包成一个或多个 bundle<br>
webρack是当下最热门的前端资源模块化管理和打包工具,它可以将许多松散耦合的模块按照<br>
依赖和规则打包成符合生产环境部署的前端资源。还可以将按需加载的模块进行代码分离,等到实际<br>
需要时再异步加载。通过 loader转换,任何形式的资源都可以当做模块,比如 Commonis、AMD、ES6、CSS、JSON、 Coffee Script、LESS等;</p>
</blockquote>
<p>安装 webpack、webpack-cli,如果 npm 不太慢先考虑使用 npm 再考虑使用 cnpm</p>
<pre><code class="language-shell">cnpm install webpack -g

cnpm install webpack-cli -g
</code></pre>
<p>通过 <code>webpack -v</code> 、<code>webpack-cli -v</code> 查看是否出现版本号确定安装是否成功</p>
<h3 id="2-使用-webpack">(2) 使用 webpack</h3>
<ul>
<li>
<p>创建项目(IDEA 的话,直接创建一个普通文件夹 Open进入就行了)</p>
</li>
<li>
<p>新建一个 modules 目录,放置 JS 模块等内容</p>
</li>
<li>
<p>在 modules 下创建模块文件,例如 demo.js 用于编写 Js 模块相关代码,例如</p>
</li>
</ul>
<pre><code class="language-js">exports.test = function () {
    document.write("&lt;h2&gt;理想二旬不止&lt;/h2&gt;")
}
</code></pre>
<ul>
<li>在 moduels 下创建 main.js ,这是一个入口文件,用于打包时设置 entry 属性对应</li>
</ul>
<pre><code class="language-js">var demo = require("./demo")
demo.test();
</code></pre>
<ul>
<li>在项目根目录下创建 webpack.config.js 文件,用于配置</li>
</ul>
<pre><code class="language-js">module.exports = {
    entry: "./modules/main.js",
    output: {
      filename: "./js/bundle.js"
    }
};
</code></pre>
<ul>
<li>在 terminal 中输入 webpack 命令进行打包(进入项目目录后 输入 webpack 就行了,这是运行结果)</li>
</ul>
<pre><code class="language-shell">abc@LAPTOP-5T03DV1G MINGW64 /f/develop/IdeaProjects/framework-code/vue/webpack_01_first
$ webpack
Hash: 7f61ef9440a6bab63058
Version: webpack 4.44.1
Time: 334ms
Built at: 2020-09-05 4:18:40 PM
         Asset      SizeChunks             Chunk Names
./js/bundle.js1020 bytes       0main
Entrypoint main = ./js/bundle.js
./modules/main.js 42 bytes {0}
./modules/demo.js 82 bytes {0}

WARNING in configuration
The 'mode' option has not been set, webpack will fallback to 'production' for this value. Set 'mode' option to 'development' or 'production' to enable defaults for each e
nvironment.
You can also set it to 'none' to disable any default behavior. Learn more: https://webpack.js.org/configuration/mode/
</code></pre>
<ul>
<li>打包后项目目录多出 dist 文件夹 其中有一个 js 文件夹,放着打包的 js,创建index.html 引入此 js</li>
</ul>
<pre><code class="language-html">&lt;!DOCTYPE html&gt;
&lt;html lang="en"&gt;
&lt;head&gt;
&lt;meta charset="UTF-8"&gt;
&lt;title&gt;Title&lt;/title&gt;
&lt;/head&gt;
&lt;body&gt;
&lt;script src="dist/js/bundle.js"&gt;&lt;/script&gt;
&lt;/body&gt;
&lt;/html&gt;
</code></pre>
<ul>
<li>页面效果如下:</li>
</ul>
<div align="center">
        <img src="//p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/86f8b38017694211a5c59199d631c3fe~tplv-k3u1fbpfcp-zoom-1.image" style="zoom: 80%">
</div>
<p>补充:配置文件中可能会有哪些内容</p>
<ul>
<li>entry:入口文件,指定 Web Pack用哪个文件作为项目的入口</li>
<li>output:输出,指定 Web pack把处理完成的文件放置到指定路径</li>
<li>module:模块,用于处理各种类型的文件plugins:插件,如:热更新、代码重用等</li>
<li>resolve:设置路径指向</li>
<li>watch:监听,用于设置文件改动后直接打包</li>
</ul>
<h2 id="三-简单认识-vue-router-路由">(三) 简单认识 Vue Router 路由</h2>
<p>Vue Router是 Vue.js 的官方路由器。它与 Vue.js 核心深度集成,使使用 Vue.js 轻松构建单页应用程序变得轻而易举。功能包括:</p>
<p>简单的说,可以实现一些页面的跳转,例如我们头部的内容是不变的,内容部分需要根据链接改变</p>
<ul>
<li>嵌套路线/视图映射</li>
<li>模块化,基于组件的路由器配置</li>
<li>路由参数,查询,通配符</li>
<li>查看由Vue.js过渡系统提供动力的过渡效果</li>
<li>细粒度的导航控制</li>
<li>与自动活动CSS类的链接</li>
<li>HTML5历史记录模式或哈希模式,在IE9中具有自动回退</li>
<li>可自定义的滚动行为</li>
</ul>
<p><strong>安装步骤:</strong></p>
<p>由于 vue-router 是一个插件包,还是老办法,npm/cnpm</p>
<pre><code class="language-shell">npm install vue-router --save-dev
</code></pre>
<p>安装后如果有一些问题,根据提示,输入对应命令即可,就像我遇到了提示输入 <code>npm audit fix</code></p>
<p>创建好项目后,删掉默认的 HelloWorld那个组件,然后再 components 中新建两个自定义组件,例如我创建的 FirstDemo.vue 和 Main.vue 前者是一个子页面,后者代表主页面,随便自拟</p>
<p><strong>FirstDemo.vue</strong></p>
<pre><code class="language-vue">&lt;template&gt;
&lt;h1&gt;第一个Demo页面&lt;/h1&gt;
&lt;/template&gt;

&lt;script&gt;
export default {
    name: "FirstDemo.vue"
}
&lt;/script&gt;

&lt;style scoped&gt;

&lt;/style&gt;
</code></pre>
<p><strong>Main.vue</strong></p>
<pre><code class="language-vue">&lt;template&gt;
&lt;h1&gt;首页&lt;/h1&gt;
&lt;/template&gt;

&lt;script&gt;
export default {
    name: "Main.vue"
}
&lt;/script&gt;

&lt;style scoped&gt;
&lt;/style&gt;
</code></pre>
<p>接着创建 router 文件夹,以及其中的 index.js 主配置</p>
<p>注:如果在一个模块化工程中使用它,必须要通过 Vue.use() 明确地安装路由功能</p>
<pre><code class="language-js">import Vue from 'vue'
import VueRouter from 'vue-router'
import FirstDemo from '../components/FirstDemo'
import Main from '../components/Main'

Vue.use(VueRouter);

export default new VueRouter({
routes: [
    {
      // 路由路径
      path: "/firstDemo",
      name: 'firstDemo',
      // 跳转的组件
      component: FirstDemo
    },
    {
      // 路由路径
      path: "/main",
      name: 'main',
      // 跳转的组件
      component: Main
    }
]
})

</code></pre>
<p>修改 main.js 这个入口文件</p>
<pre><code class="language-js">// The Vue build version to load with the `import` command
// (runtime-only or standalone) has been set in webpack.base.conf with an alias.
import Vue from 'vue'
import App from './App'
import router from './router'

Vue.config.productionTip = false

Vue.use(router);

/* eslint-disable no-new */
new Vue({
el: '#app',
//配置路由
router,
components: {App},
template: '&lt;App/&gt;'
})

</code></pre>
<p>以及正式的书写页面,引入链接</p>
<pre><code class="language-vue">&lt;template&gt;
&lt;div id="app"&gt;
    &lt;h1&gt;理想二旬不止&lt;/h1&gt;
    &lt;router-link to="/main"&gt;首页&lt;/router-link&gt;
    &lt;router-link to="/firstDemo"&gt;第一个Demo页面&lt;/router-link&gt;
    &lt;router-view&gt;&lt;/router-view&gt;
&lt;/div&gt;
&lt;/template&gt;

&lt;script&gt;

export default {
    name: 'App',
}
&lt;/script&gt;

&lt;style&gt;
#app {
    font-family: 'Avenir', Helvetica, Arial, sans-serif;
    -webkit-font-smoothing: antialiased;
    -moz-osx-font-smoothing: grayscale;
    text-align: center;
    color: #2c3e50;
    margin-top: 60px;
}
&lt;/style&gt;
</code></pre>
<h2 id="四-vue--elementui-基本使用">(四) Vue + ElementUi 基本使用</h2>
<p>创建名字为 vue_03_vue_elementui 的项目,同时安装 vue-router、e1ement-ui、sass-loader 、node-sass 插件</p>
<pre><code class="language-shell"># 创建项目
vue init webpack vue_03_vue_elementui

# 进入工程目录
cd vue_03_vue_elementui
# 安装vue-router
npm install vue-router --save-dev
# 安装e1ement-ui
npm i element-ui -S
# 安装依赖
npm install
# 安装SASS加载器
cnpm install sass-loader node-sass --save-dev
# 启动测试
npm run dev
</code></pre>
<p>补充:Npm命令解释</p>
<ul>
<li>
<p><strong>npm install moduleName</strong>:安装模块到项目目录下</p>
</li>
<li>
<p><strong>npm install - g moduleNMame</strong>:-g 的意思是将模块安装到全局,具体安装到磁盘哪个位置,要看 npm config prefix的位置</p>
</li>
<li>
<p><strong>npm install - save moduleName</strong>:--save 的意思是将模块安装到项目目录下,并在package文件的 dependencies 节点写入依赖,-S为该命令的缩写</p>
</li>
<li>
<p><strong>npm install -save -dev moduleName</strong>:--save-dev 的意思是将模块安装到项目目录下,并在 package 文件的 devdependencies节点写入依赖, -D为该命令的缩写</p>
</li>
</ul>
<p>接着就可以在编辑器中打开了,看个人选择,我这里用 IDEA 打开,打开后注意看一下 modules 文件夹中是否已经把 router sass 等内容成功安装了</p>
<p>接着将默认的 HelloWorld 那个组件和默认 logo 删掉,开始编写代码,创建一个 views 文件夹用来放视图</p>
<p><strong>创建 Login.vue 和 Main.vue</strong></p>
<p><strong>Login.vue</strong></p>
<pre><code class="language-vue">&lt;template&gt;
&lt;h1&gt;主页面&lt;/h1&gt;
&lt;/template&gt;

&lt;script&gt;
export default {
    name: "Main.vue"
}
&lt;/script&gt;

&lt;style scoped&gt;
&lt;/style&gt;
</code></pre>
<p><strong>Main.vue</strong></p>
<pre><code class="language-vue">&lt;template&gt;
&lt;div&gt;
    &lt;el-form ref="loginForm" :model="form" :rules="rules" label-width="80px" class="login-box"&gt;
      &lt;h3 class="login-title"&gt;欢迎 登录&lt;/h3&gt;
      &lt;el-form-item label=" 账号" prop="username"&gt;
      &lt;el-input type="text" placeholder="请输入账号" v-model="form.username"/&gt;
      &lt;/el-form-item&gt;
      &lt;el-form-item label=" 密码" prop="password"&gt;
      &lt;el-input type="password" placeholder=" 请输入密码" v-model="form.password"/&gt;
      &lt;/el-form-item&gt;
      &lt;el-form-item&gt;
      &lt;el-button type="primary" v-on:click="onSubmit( 'loginForm' )"&gt;登录&lt;/el-button&gt;
      &lt;/el-form-item&gt;
    &lt;/el-form&gt;
    &lt;el-dialog
      title="温馨提示"
      :visible.sync="dialogVisible"
      width="30%"
      :before-close="handLeClose"&gt;
      &lt;span&gt;请输入账号和密码&lt;/span&gt;
      &lt;span slot="footer" class="dialog- footer"&gt;
      &lt;el-button type="primary" @click="dialogVisible = false"&gt;确定&lt;/el-button&gt;
      &lt;/span&gt;
    &lt;/el-dialog&gt;
&lt;/div&gt;

&lt;/template&gt;


&lt;script&gt;
export default {
    name: "Login",
    data() {
      return {
      form: {
          username: '',
          password: ''
      },
      //表单验证,需要在el-form-item 元素中增加prop 属性
      rules: {
          username: [
            {required: true, message: " 账号不可为空", trigger: 'blur'}
          ],
          password: [
            {required: true, message: " 密码不可为空 ", trigger: 'blur'}
          ]
      },
      //对话框显示和隐藏
      dialogVisible: false
      }
    },
    methods: {
      onSubmit(formName) {
      //为表单绑定验证功能
      this.$refs.validate((valid) =&gt; {
          if (valid) {
            //使用vue-router路由到指定页面,该方式称之为编程式导航
            this.$router.push("/main");
          } else {
            this.dialogVisible = true;
            return false;
          }
      });
      }
    }
}
&lt;/script&gt;


&lt;style lang="scss" scoped&gt;
.login-box {
    border: 1px solid #DCDFE6;
    width: 350px;
    margin: 40px auto;
    padding: 35px 35px 15px 35px;
    border-radius: 5px;
    -webkit-border-radius: 5px;
    -moz-border-radius: 5px;
    box-shadow: 0 0 25px #909399;
}

.login-title {
    text-align: center;
    margin: 0 auto 40px auto;
    color: #303133;
}
&lt;/style&gt;
</code></pre>
<p>创建 router 文件夹,以及其中的 index.js,配置好跳转内容</p>
<p><strong>index.js</strong></p>
<pre><code class="language-js">import Vue from 'vue'
import VueRouter from 'vue-router'
import Login from '../views/Login'
import Main from '../views/Main'

Vue.use(VueRouter);

export default new VueRouter({
routes: [
    {
      path: "/main",
      component: Main
    },
    {
      path: "/login",
      component: Login
    }
]
})
</code></pre>
<p>修改 main.js ,使用 router 和 elementui,关于 router 前面就说过,至于后者,照着官网起步文档就明白了</p>
<p><code>https://element.eleme.cn/#/zh-CN/component/quickstart</code></p>
<p><strong>main.js</strong></p>
<pre><code class="language-js">import Vue from 'vue'
import App from './App'

import router from './router'
import ElementUI from 'element-ui';
import 'element-ui/lib/theme-chalk/index.css';

Vue.config.productionTip = false;

Vue.use(router);
Vue.use(ElementUI);

/* eslint-disable no-new */
new Vue({
el: '#app',
router,
render: h =&gt; h(App)
});
</code></pre>
<p><strong>App.vue</strong></p>
<pre><code class="language-vue">&lt;template&gt;
&lt;div id="app"&gt;
    &lt;h1&gt;理想二旬不止&lt;/h1&gt;
    &lt;router-link to="/main"&gt;首页&lt;/router-link&gt;
    &lt;router-link to="/login"&gt;登录页面&lt;/router-link&gt;
    &lt;router-view&gt;&lt;/router-view&gt;
&lt;/div&gt;
&lt;/template&gt;

&lt;script&gt;
export default {
name: 'App',
}
&lt;/script&gt;

&lt;style&gt;
#app {
font-family: 'Avenir', Helvetica, Arial, sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
text-align: center;
color: #2c3e50;
margin-top: 60px;
}
&lt;/style&gt;
</code></pre>
<p>到这里就写好了,我们可以开始运行了,但是运行时,我分别出现了如下错误</p>
<pre><code>TypeError : The "path" argument must be of type string. Received type undefined

Module build failed: TypeError: this.getResolve is not a function
</code></pre>
<p>经查阅后,修改项目目录下 package.json 中的 sass-loder 的版本 从 10.0.2 到 8.0.2 到 7.3.1 才可以正常通过 npm run dev 运行</p>
<pre><code>"sass-loader": "^7.3.1",
</code></pre>
<p>注:修改配置后需要重新 npm install 或者 cnpm install</p>
<p>展示一下最终效果:</p>
<p>点击首页效果:</p>
<div align="center">
        <img src="//p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/4944cda0c2d245a39581b8a90a3afda6~tplv-k3u1fbpfcp-zoom-1.image" style="zoom: 80%">
</div>
<p>点击登录页面效果:</p>
<div align="center">
        <img src="//p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/ce9f09cd81ac45b289a924fde4794f42~tplv-k3u1fbpfcp-zoom-1.image" style="zoom: 80%">
</div>
<h1 id="五-vue和java数据交互简单案例">五 Vue和Java数据交互简单案例</h1>
<p>最后,在某马上找了一个现成的页面案例,简单搭了下后台跑了一下,也算巩固一下最前面的基础语法,后台就基本的 SSM ,给了三个接口方法,作为一个后端,这应该算基本功了哇</p>
<p><code>/user/findAll</code> 、<code>/user/indById </code>、<code>/user/updateUser</code></p>
<p>就是简单的查询和一个更新操作,查询的主体是一个用户类,有这么几个基本字段</p>
<pre><code class="language-java">public class User implements Serializable {       
        private Integer id;
    private String username;
    private String password;
    private Integer age;
    private String sex;
    private String email;
    ......
}
</code></pre>
<p>页面中承接的数据的关键代码如下</p>
<p>首先是关于所有用户数据展示的,通过一个对于 userList 的遍历,然后通过大括号组和 X.x 的形式取出属性值</p>
<pre><code class="language-html">&lt;tr v-for="u in userList"&gt;
&lt;td&gt;&lt;input name="ids" type="checkbox"&gt;&lt;/td&gt;
&lt;td&gt;{{u.id}}&lt;/td&gt;
&lt;td&gt;{{u.username}}
&lt;/td&gt;
&lt;td&gt;{{u.password}}&lt;/td&gt;
&lt;td&gt;{{u.sex}}&lt;/td&gt;
&lt;td&gt;{{u.age}}&lt;/td&gt;
&lt;td class="text-center"&gt;{{u.email}}&lt;/td&gt;
&lt;td class="text-center"&gt;
    &lt;button type="button" class="btn bg-olive btn-xs"&gt;详情&lt;/button&gt;
    &lt;button type="button" class="btn bg-olive btn-xs" @click="findById(u.id)"&gt;编辑&lt;/button&gt;
&lt;/td&gt;
&lt;/tr&gt;
</code></pre>
<p>点击编辑后执行对于当前用户的查询方法,用于回显,下面通过 v-model 进行与 user 的绑定(js后面给出)</p>
<pre><code class="language-html">&lt;div class="box-body"&gt;
&lt;div class="form-horizontal"&gt;


    &lt;div class="form-group"&gt;
      &lt;label class="col-sm-2 control-label"&gt;用户名:&lt;/label&gt;
      &lt;div class="col-sm-5"&gt;
      &lt;input type="text" class="form-control" v-model="user.username"&gt;
      &lt;/div&gt;
    &lt;/div&gt;
    &lt;div class="form-group"&gt;
      &lt;label class="col-sm-2 control-label"&gt;密码:&lt;/label&gt;
      &lt;div class="col-sm-5"&gt;
      &lt;input type="text" class="form-control" v-model="user.password"&gt;
      &lt;/div&gt;
    &lt;/div&gt;
    &lt;div class="form-group"&gt;
      &lt;label class="col-sm-2 control-label"&gt;性别:&lt;/label&gt;
      &lt;div class="col-sm-5"&gt;
      &lt;input type="text" class="form-control" v-model="user.sex"&gt;
      &lt;/div&gt;
    &lt;/div&gt;
    &lt;div class="form-group"&gt;
      &lt;label class="col-sm-2 control-label"&gt;年龄:&lt;/label&gt;
      &lt;div class="col-sm-5"&gt;
      &lt;input type="text" class="form-control" v-model="user.age"&gt;
      &lt;/div&gt;
    &lt;/div&gt;
    &lt;div class="form-group"&gt;
      &lt;label class="col-sm-2 control-label"&gt;邮箱:&lt;/label&gt;
      &lt;div class="col-sm-5"&gt;
      &lt;input type="text" class="form-control" v-model="user.email"&gt;
      &lt;/div&gt;
    &lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
</code></pre>
<p>要实现数据交互,最重要的还是定义数据,与使用 axios 进行异步请求</p>
<pre><code class="language-js">var vue = new Vue({
    el: "#app",
    data: {
      user: {id: "", username: "", password: "", age: "", sex: "", email: ""},
      userList: []
    },
    methods: {
      findAll: function () {
            var _this = this;
            axios.get("user/findAll.do").then(function (response) {
                _this.userList = response.data;
                console.log(_this.userList);
            }).catch(function (err) {
                console.log(err);
            });
      },
      findById: function (userid) {
            var _this = this;
            axios.get("user/findById.do", {
                params: {
                  id: userid
                }
            }).then(function (response) {
                _this.user = response.data;
                $('#myModal').modal("show");
            }).catch(function (err) {
            });

      },
      update: function (user) {
            var _this = this;
            axios.post("user/updateUser.do", _this.user).then(function (response) {
                _this.findAll();
            }).catch(function (err) {
            });
      }
    },
    created() {
      this.findAll();
    }
});
</code></pre>
<p>上述代码其实很好理解,首先定义了 user 和 userList 两个数据,userList 就是前面展示所有用户数据的一个遍历内容,用来承载 findAll 后的数据,user 则是对于进行单个用户查询,即修改时回显当前用户旧信息的一个承载实体,因为查询所有的操作是一开始就进行,所以在 created() 中就执行 findAll 方法,在 methos 中创建查和改的方法,通过 axios 进行 get 或者 post 请求,同时将返回的结果进行处理</p>
<p>说明:<code>.then</code> 中的是请求成功后执行的内容,<code>.catch</code> 中是请求失败后执行的内容</p>
<p>注意:最关键的一个内容就是在 axios 前定义了 <code>var _this = this</code> 如果有接触过小程序可能会感到很熟悉,这里定义的原因是因为 例如在 axios 中有这样的语句 <code>_this.userList = response.data;</code> 如果 userList 中前直接使用 this,这就代表着查找 axios 中的此内容,但我们明显想指代的是 data 中的 userList,所以此定义 <code>_this</code> 步骤不可省略</p>
<p>效果如下:</p>
<p>查询所有</p>
<div align="center">
        <img src="//p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/538050de27c74f3c8653cd5f8d6b989f~tplv-k3u1fbpfcp-zoom-1.image" style="zoom: 80%">
</div>
查询当前用户以及修改
<div align="center">
        <img src="//p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/6470d31ae607489fa765ef72939506a7~tplv-k3u1fbpfcp-zoom-1.image" style="zoom: 80%">
</div>
<h1 id="六-结尾">六 结尾</h1>
<p>如果文章中有什么不足,欢迎大家留言交流,感谢朋友们的支持!</p>
<p>如果能帮到你的话,那就来关注我吧!如果您更喜欢微信文章的阅读方式,可以关注我的公众号</p>
<blockquote>
<p>在这里的我们素不相识,却都在为了自己的梦而努力 ❤</p>
<p>一个坚持推送原创开发技术文章的公众号:理想二旬不止</p>
</blockquote>
<p><img src="//p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/d5bb62feeb174d099c1baff16e52dc1f~tplv-k3u1fbpfcp-zoom-1.image" alt="" loading="lazy"></p><br><br>
来源:https://www.cnblogs.com/ideal-20/p/13624713.html
頁: [1]
查看完整版本: 一个后端开发的 Vue 笔记【入门级】