个人向-Vue快速入门

个人向-Vue快速入门

  • 一、介绍
  • 二、初入(基本使用语法)
    • 1.初入
    • 2.v-bind
    • 3.判断循环
    • 4.事件绑定
    • 5.数据双向绑定
    • 6.vue组件
    • 7.axios异步通信
    • 8.计算属性
    • 9.插槽slot
    • 10.自定义事件 内容分发
  • 三、Vue-cli(vue脚手架)
    • 1.初始化
    • 2.idea 安装 Vue 插件没有Vue component选项
  • 四、vue-router
  • 五、Vue-ElementUI
    • 1.前期准备:
    • 2.简单项目代码
      • (1).在根目录(/hello-vue)下新建/static/mock/data.json
      • (2).修改src/main.js文件:
      • (3).组件
      • (3-2).组件
      • (4)index.js(配置路由)
    • 3.代码细节
      • (1).参数传递
      • (2)传参数props解耦
      • (3)重定向
      • (4)连接登录页面
      • (5)路由
      • (6)404
      • (7)路由钩子

一、介绍

  • Vue (读音 /vjuː/,类似于 view) 是一套用于构建用户界面的渐进式框架。与其它大型框架不同的是,Vue 被设计为可以自底向上逐层应用。Vue 的核心库只关注视图层(HTML+CSS+JS),不仅易于上手,还便于与第三方库或既有项目整合。另一方面,当与现代化的工具链以及各种支持类库结合使用时,Vue 也完全能够为复杂的单页应用提供驱动。(官方介绍)

  • Vue是中国人尤雨溪开发的

  • 前端除了视图层还有网络通信(一般用axios),还有页面跳转(vue-router),状态管理(vuex)

  • Vue官网

相关原则:

  • Soc:(Separation of concerns)Soc原则:关注点分离原则 是计算前端用到的一条最基本的原则。Vue当然也遵守
  • MVVM :Vue.js 是一个提供了 MVVM 风格的双向数据绑定的 Javascript 库,专注于View 层。它的核心是 MVVM 中的 VM,也就是 ViewModel。 ViewModel负责连接 View 和 Model,保证视图和数据的一致性,这种轻量级的架构让前端开发更加高效、便捷。

MVVM:
Model-View-ViewModel —— 事件驱动编程方式(主要目的是分离视图和模型)
ViewModel双向绑定层 :ViewModel所封装出来的数据模型包括视图的状态和行为两部分,model层数据模型只包含状态。

二、初入(基本使用语法)

一般直接在html中引入Vue就可以直接使用了

<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/vue.js"></script><!--或者下面的也行-->
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/vue.min.js"></script>

1.初入

使用基本html格式,代码只有部分

<body>

<!--view层 模板-->
<div id="app">
    {{message}}//从data中取数据
</div>

<!--1.导入vue.js-->
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/vue.min.js"></script>
<script>
    var vm=new  Vue({
        el:"#app",
        //Model:数据
        data:{
            message:"hello,vue!"
        }
    });
</script>

2.v-bind

<!--view层 模板-->
<div id="app">
    <span v-bind:title="message">
        鼠标悬停查看动态绑定的信息
    </span>
</div>

<!--1.导入vue.js-->
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/vue.min.js"></script>
<script>
    var vm=new  Vue({
        el:"#app",
        //Model:数据
        data:{
            message:"hello,vue!"
        }
    });
</script>

3.判断循环

判断:

<!--view层 模板-->
<div id="app">
    <h1 v-if="ok">True</h1>
    <h1 v-else>No</h1>
</div>

<!--1.导入vue.js-->
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/vue.min.js"></script>
<script>
    var vm=new  Vue({
        el:"#app",
        //Model:数据
        data:{
            ok:true
        }
    });
</script>

循环:

<!--view层 模板-->
<div id="app">
    <h1 v-if="type==='A'">A</h1>
    <h1 v-else-if="type==='B'">B</h1>
    <h1 v-else-if="type==='C'">C</h1>
    <h1 v-else>D</h1>
</div>

<!--1.导入vue.js-->
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/vue.min.js"></script>
<script>
    var vm=new  Vue({
        el:"#app",
        //Model:数据
        data:{
            type:'A'
        }
    });
</script>

4.事件绑定


<!--view层 模板-->
<div id="app">
    <button v-on:click="sayHi">click here</button>
</div>

<!--1.导入vue.js-->
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/vue.min.js"></script>
<script>
    var vm=new  Vue({
        el:"#app",
        //Model:数据
        data: {
            message:"大海"
        },
        methods:{//
            //方法必须定义在Vue的Method对象种
            sayHi:function (){
                alert(this.message)
            }
        }
    });
</script>

5.数据双向绑定

这里给两个例子

<!--view层 模板-->
<div id="app">
    性别:
    <input type="radio" name="sex" value="男" v-model="person" /><input type="radio" name="sex" value="女" v-model="person" /><p>
        选中了:{{person}}
    </p>
    <br />
    输入的文本:<textarea v-model="message" ></textarea>{{message}}
</div>

<!--1.导入vue.js-->
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/vue.min.js"></script>
<script>
    var vm=new  Vue({
        el:"#app",
        //Model:数据
        data:{
            message:"",
            person:''
        }
    });
</script>

下拉框的双向绑定:

<!--view层 模板-->
<div id="app">
    下拉框:
    <select name="" id="" v-model="selected">
        <option value="" disabled>---请选择---</option>
        <option>A</option>
        <option>B</option>
        <option>C</option>
        <option>D</option>
    </select>

    <span>value:{{selected}}</span>
</div>

<!--1.导入vue.js-->
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/vue.min.js"></script>
<script>
    var vm=new  Vue({
        el:"#app",
        //Model:数据
        data:{
            selected:''
        }
    });
</script>

6.vue组件

组件是可复用的Vue实例,(可重复使用的模板)

<!--
“绑定item的值”也是一个变量,命名为item_bind什么的也行,这里只是方便区别
-->

<!--view层 模板-->
<div id="app">

    <!--组件:传递给组件中的值:props-->
    <person v-for="item in items" v-bind:绑定item的值="item"></person>
</div>

<!--1.导入vue.js-->
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/vue.min.js"></script>
<script>

    //定义一个Vue组件component
    Vue.component("person",{
        props:["绑定item的值"],
        template:'
  • {{绑定item的值}}
  • '
    }); var vm=new Vue({ el:"#app", //Model:数据 data:{ items:["java","linux","mac"] } }); </script>

    7.axios异步通信

    Axios 是一个开源的可以用在浏览器端和 NodeJS 的异步通信框架,她的主要作用就是实现 AJAX 异步通信。
    需要引入script:

    <script src="https://unpkg.com/axios/dist/axios.min.js"></script>
    

    新建data.json文件

    {
      "name": "java",
      "url": "https://www.baidu.com/",
      "page": 1,
      "isNonProfit": true,
      "address": {
        "street": "含光门",
        "city": "陕西西安",
        "country": "中国"
      },
      "links": [
        {
          "name": "B站",
          "url": "https://www.bilibili.com/"
        },
        {
          "name": "csdn",
          "url": "https://www.csdn.net/"
        },
        {
          "name": "百度",
          "url": "https://www.baidu.com/"
        }
      ]
    }
    

    demo.html

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
        <style>
            [v-cloak]{
                display: none;
            }
        </style>
    </head>
    <body>
    <!--view层 模板-->
    <!--
        ps:这里打开网页会闪烁:   {{message.name}}------------》java   加载
        手动解决:
          <style>
            [v-cloak]{
                display: none;
            }
         </style>
         打开网页       白屏------------》java   加载
    -->
    <div id="vue" v-cloak>
    
        <div>{{message.name}}</div>
        <div>{{message.address.city}}</div>
    
        <a v-bind:href="message.url">百度</a>
    
    </div>
    
    <!--1.导入vue.js-->
    <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/vue.js"></script>
    <script src="https://unpkg.com/axios/dist/axios.min.js"></script>
    <script>
        var vm=new Vue({
            el:"#vue",
            data(){
                return{
                    message:{/*这里直接     message:''   不写也可以   */
                        name:null,
                        city:null,
                        address:{
                            street:null,
                            city:null,
                            country:null
                        }
                    }
                }
            },
            mounted(){//钩子函数 链式编程
                axios.get('./data.json').then(response=>(this.message=response.data));
            }
        });
    </script>
    </body>
    </html>
    

    8.计算属性

    <!--view层 模板-->
    <div id="app">
    
        <!--
            currentTime1():是方法,在网页中console.log中调用 vm.currentTime1()   会显示不同的值
            currentTime2:是属性    在网页中console.log中调用 vm.currentTime2()    会报错,因为它不是方法,重复调用vm.currentTime2值不会变化
          因为currentTime2是属性,计算出来后保存到了内存中   ,和缓存类似,如果 currentTime2内属性值变化 例如:在网页控制台中输入:vm.message="3",  currentTime2
          会重新计算
    
        -->
    
        <!--
            计算属性的主要特征就是为了将不经常变化的计算结果进行缓存,以节约我们的习题开销
        -->
        <P>currentTime1:{{currentTime1()}}</P>
        <P>currentTime2:{{currentTime2}}</P>
    
    </div>
    
    <!--1.导入vue.js-->
    <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/vue.min.js"></script>
    <script>
        var vm=new  Vue({
            el:"#app",
            data:{
                message:"hello,world"
            },
            methods:{
                currentTime1:function (){
                    return Date.now();  //返回当前一个时间戳
                }
            },
            computed:{//    计算属性:   methods. computed   方法不能重名      vm.currentTime2 is not a function   currentTime2是属性
                currentTime2:function (){
                    this.message;
                    return Date.now();  //返回当前一个时间戳
                }
            }
        });
    </script>
    

    9.插槽slot

    <!--view层 模板-->
    <div id="app">
    <!-- 
    网页输出:
    	<p>列表数据</p>
    	<ul>
    		<li>鲁迅</li>
    		<li>周树人</li>
    		<li>狂人</li>
    	</ul>
      -->
        <todo>
            <todo-title slot="todo-title" :title="title"></todo-title>
            <todo-items slot="todo-items" v-for="item in names" :item="item"></todo-items>
        </todo>
    
    </div>
    
    <!--1.导入vue.js-->
    <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/vue.min.js"></script>
    <script>
    
        //slot:插槽
        Vue.component("todo",{
            template:
            '
    ' + '' + '
      ' + '' + '
    '
    + '
    '
    }); Vue.component("todo-title",{ props:['title'], template: '
    {{title}}
    '
    }); Vue.component("todo-items",{ props:['item'], template: '
  • {{item}}
  • '
    }); var vm=new Vue({ //Vue有先后顺序,这个要放到最后,不然会报错 el:"#app", //Model:数据 data:{ title:"列表", names:['鲁迅','周树人','狂人'] } }); </script>

    10.自定义事件 内容分发

    
    <!--view层 模板-->
    <div id="app">
        <todo>
            <todo-title slot="todo-title" :title="title"></todo-title>
            <todo-items slot="todo-items" v-for="(item,index) in names" :item="item"
                        v-bind:绑定index的值="index" v-on:绑定remove方法="removeItems(index)"></todo-items>
        </todo>
    
    </div>
    
    <!--1.导入vue.js-->
    <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/vue.min.js"></script>
    <script>
    
        //slot:插槽
        Vue.component("todo",{
            template:
                '
    ' + '' + '
      ' + '' + '
    '
    + '
    '
    }); Vue.component("todo-title",{ props:['title'], template: '
    {{title}}
    '
    }); Vue.component("todo-items",{ props:['item','绑定index的值'], //只能绑定当前组件的方法 template: '
  • {{绑定index的值}}--{{item}}
  • '
    , methods:{ remove:function (绑定index的值){ //this.$emit() 自定义事件分发 this.$emit('绑定remove方法',绑定index的值) } } }); var vm=new Vue({ //据说Vue又先后顺序,这个要放到最后,不然会报错?? 未验证 el:"#app", //Model:数据 data:{ title:"列表", names:['鲁迅','周树人','狂人'] }, methods: { removeItems:function (index){ this.names.splice(index,1); //一次删除下标为index的一个元素 } } }); </script>

    三、Vue-cli(vue脚手架)

    Vue CLI 是一个基于 Vue.js 进行快速开发的完整系统
    全局安装vue-cli:

    npm install -g vue-cli

    不行用cnpm install -g vue-cli
    查看版本:vue -V

    1.初始化

    新建空文件夹,空文件夹位置打开cmd输入:

    vue init webpack myvue

    不行的需要用管理员打开cmd

    细节:
    vue init webpack myvue(文件名)
    加载后cmd会显示项目基本信息,选项依次可填:默认 默认 作者名 第一个选项(standalone) no no no no no,i

    然后就会生成一个myvue的项目,cmd切换到/myvue文件夹内
    终端输入:

    npm run dev

    网页打开 http://localhost:8080,空的vue-cli运行成功

    2.idea 安装 Vue 插件没有Vue component选项

    这里可以用idea开发Vue,直接下载Vue.js插件即可。
    如果下载后,新建中没有component选项的解决方案:

    1. 点击 file 打开设置 settings,展开 Editor 找到 file and code templates
    2. 找到 Vue single file component 并选中它,然后点击copy
    3. 复制后底部出现了一个新的文件
    4. 把 Name 改成 Vue Component,然后把代码里的 “COMPONENT_ ”删掉,最后点 ok 就完事了

    四、vue-router

    Vue Router 是Vue.js(opens new window)官方的路由管理器。

     这里简单说一下代码是什么实例:
    有很多网站大框架不变,按按钮时只是一块主显示区域刷新,我们用vue-router路由就是想达到相同的效果。

    在空的vue-cli项目中:
    下载vue-router路由:

    npm install vue-router --save-dev

    1.在空的vue-cli文件的src/main.js中配置路由

    import Vue from 'vue'
    import App from './App'
    import router from './router'   //自动扫描里面的路由配置
    
    Vue.config.productionTip = false	// 阻止启动生产消息,默认的
    
    new Vue({
      el: '#app',
      //配置路由
      router,
      components: { App },
      template: ''
    })
    	
    

    我们现在有三个页面和一个主页面,我们想在主页面中可以通过按钮切换显示其它三个页面
    2.三个页面(组件):
    Content.vue:

    <template>
      <h1>一些乱七八糟的内容</h1>
    </template>
    
    <script>
    export default {
      name: "Content"
    }
    </script>
    
    <style scoped>  /*  scoped  当前页面起效  */
    
    </style>
    

    Person.vue:

    <template>
        <h2>person</h2>
    </template>
    
    <script>
    export default {
      name: "person"
    }
    </script>
    
    <style scoped>
    
    </style>
    
    

    Main.vue:

    <template>
      <h1>首页</h1>
    </template>
    
    <script>
    export default {
      name: "Main"
    }
    </script>
    
    <style scoped>
    
    </style>
    

    3.配置导出路由
    在 src/  下新建文件router/index.js

    import Vue from "vue";
    import VueRouter from "vue-router";
    
    import Content from '../components/Content';
    import Main from '../components/Main';
    import Person from '../components/Person';
    
    //安装路由
    Vue.use(VueRouter);
    
    //配置导出路由
    export default new VueRouter({
      routes:[
        {
          //路由路径
          path:'/main',
          name:'content',
          //跳转的组件
          component:Main
        },
        {
          //路由路径
          path:'/content',
          name:'content',
          //跳转的组件
          component:Content
        },
        {
          //路由路径
          path:'/person',
          //name可以不用
          //跳转的组件
          component:Person
        }
      ]
    });
    
    

    4.主页:

    <template>
      <div id="app">
        <h1>Vue-Router</h1>
        <router-link to="/main">首页</router-link>
        <router-link to="/content">内容页</router-link>
        <router-link to="/person">个人页</router-link>
        <router-view></router-view>
      </div>
    </template>
    
    <script>
    
    export default {
      name: 'App'
    }
    </script>
    
    <style>
    #app {/*默认的主页css,删掉也行*/
      font-family: 'Avenir', Helvetica, Arial, sans-serif;
      -webkit-font-smoothing: antialiased;
      -moz-osx-font-smoothing: grayscale;
      text-align: center;
      color: #2c3e50;
      margin-top: 60px;
    }
    </style>
    
    

    然后直接在终端(要切到当前根目录)输入:
    npm run dev
    运行项目(默认: http://localhost:8080)
    8080端口被占会顺移端口

    五、Vue-ElementUI

    ElementUI:适合于Vue的UI框架
    官网组件

    1.前期准备:

    1. 初始化webpack项目
      vue init webpack hello-vue(文件名)
    2. cd hello-vue ——切换目录
    3. 安装vue-router
      cnpm install vue-router --save-dev
                 保存当前目录
    4. 安装element-ui
      cnpm i element-ui -s
    5. 安装依赖
      npm install
    6. 安装sass加载器
      cnpm install sass-loader node-sass --save-dev
    7. 启动测试
      npm run dev
    8. idea打开项目

    2.简单项目代码

    在src/下新建router,views文件夹
    在router/ 下新建index.js文件
    在views/ 下新建Main.vue,Login.vue文件

    这里先给出完整项目,在介绍相关代码

    提前安装一下axios,终端输入:cnpm install --save axios vue-axios

    (1).在根目录(/hello-vue)下新建/static/mock/data.json

    {
      "name":"person",
      "url": "https://www.baidu.com/",
      "page": 1,
      "isNonProfit":true,
      "address": {
        "street": "含光门",
        "city":"陕西西安",
        "country": "中国"
      },
      "links": [
        {
          "name": "B站",
          "url": "https://www.bilibili.com/"
        },
        {
          "name": "4399",
          "url": "https://www.4399.com/"
        },
        {
          "name": "百度",
          "url": "https://www.baidu.com/"
        }
      ]
    }
    
    

    (2).修改src/main.js文件:

    
    import Vue from 'vue'
    import App from './App'
    
    import router from './router'
    
    //导入element-ui和css文件
    import ElementUI from 'element-ui';
    import 'element-ui/lib/theme-chalk/index.css';
    
    import axios from 'axios'
    import VueAxios from 'vue-axios'
    
    Vue.use(VueAxios,axios);
    
    Vue.use(router);
    Vue.use(ElementUI);
    
    
    new Vue({
      el: '#app',
      router,
      render:h=>h(App)  //ElementUI
    })
    
    

    (3).组件

    Main.vue:

    <template>
      <div>
        <el-container>
          <el-aside width="200px">
            <el-menu :default-openeds="['1']">
    
              <el-submenu index="1">
                <template slot="title"><i class="el-icon-caret-right"></i>用户管理</template>
                <el-menu-item-group>
                  <el-menu-item index="1-1">
                    <!--插入的地方-->
                    <!--  <router-link to="/user/profile">个人信息</router-link>  -->
                    <!--  name-传组件名 params传递参数,需要对象:v-bind (:to)   -->
                    <router-link :to="{name: 'UserProfile',params: {id: 1}}">个人信息</router-link>
                  </el-menu-item>
                  <el-menu-item index="1-2">
                    <!--插入的地方-->
                    <router-link to="/user/list">用户列表</router-link>
                  </el-menu-item>
                  <el-menu-item index="1-3">
                    <router-link to="/goHome">回到首页</router-link>
                  </el-menu-item>
                </el-menu-item-group>
              </el-submenu>
    
              <el-submenu index="2">
                <template slot="title"><i class="el-icon-caret-right"></i>内容管理</template>
                <el-menu-item-group>
                  <el-menu-item index="2-1">分类管理</el-menu-item>
                  <el-menu-item index="2-2">内容列表</el-menu-item>
                </el-menu-item-group>
              </el-submenu>
    
              <el-submenu index="3">
                <template slot="title"><i class="el-icon-caret-right"></i>系统管理</template>
                <el-menu-item-group>
                  <el-menu-item index="3-1">用户设置</el-menu-item>
                </el-menu-item-group>
              </el-submenu>
    
            </el-menu>
          </el-aside>
    
          <el-container>
            <el-header style="text-align: right; font-size: 12px">
              <el-dropdown>
                <i class="el-icon-setting" style="margin-right: 15px"></i>
                <el-dropdown-menu slot="dropdown">
                  <el-dropdown-item>个人信息</el-dropdown-item>
                  <el-dropdown-item>退出登录</el-dropdown-item>
                </el-dropdown-menu>
              </el-dropdown>
    
    <!--          <span>{{name}}</span>-->
    
            </el-header>
    
            <el-main>
              <!--在这里展示视图-->
              <router-view />
            </el-main>
    
          </el-container>
        </el-container>
      </div>
    </template>
    
    <script>
    export default {
      // props:['name'],
      name: "Main"
    }
    </script>
    
    <style scoped > /*