zoukankan      html  css  js  c++  java
  • Vue

    Vue

    在我们的大型项目开发的时候我们往往都会采用前后端分离的方案,而我们的前端一般都是采用Vue框架来实现前后端分离。那这样我们就不能不讲一下Vue开发的优点了:

    • 先进的前端设计模式:MVVM
    • 可以完全脱离服务器端,以 前端代码复用的方式渲染整个页面:组件化开发
    特点
    • 单页面Web应用
    • 数据驱动
    • 数据的双先绑定
    • 虚拟DOM

    平时开发可以直接使用js文件导入的形式使用Vue开发

    开发版本

    生产版本

    <div id="app">
        {{ }}
    </div>
    <script src="js/vue.min.js"></script>
    <script>
        new Vue({
            el: '#app'
        })
    </script>
    

    实例成员

    • el

      • 实例与页面挂载点一一对应

      • 一个页面中可以出现多个实例对应多个挂载点

      • 实例只操作挂载点内部内容

    • data

      • data为插值表达式中的变量提供数据

      • data中的数据可以通过Vue实例直接或间接访问

    • methods

      • methods为事件提供实现体
    • computed

      • 一个变量依赖于多个变量
      • 当依赖的变量发生变化,便会触发
    • watch:监听

      • 用于监听某个变量的变化
    • delimiters:分隔符

      • 当我们的{{}}与其他组件发生冲突时可以使用这个来替换新的标识符

    指令

    • 文本指令(数据需要在Vue中定义)

      • 插值表达式

        <p>{{ msg }}</p>

      • v-text(替换原文本)

        <p v-text='msg'>原文本</p>

      • v-html(替换原文本,并且解析html标签)

      • v-once(只渲染一次)

    • 斗篷指令

      <div id="app">
          <p>{{ msg }}</p>
          <p>{{ msg }}</p>
          <p>{{ msg }}</p>
          <p>{{ msg }}</p>
      </div>
      <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
      <script type="text/javascript">
          new Vue({
              el: "#app",
              data: {
                  msg: "message"
              }
          })
      </script>
      

      在这种情况下回发生一个问题就是页面是先加载后渲染数据的,所以你可以看到先是一堆的{{ msg }}然后才是渲染的数据。解决这个办法有两个方法

      • 将导入Vue.js的语句放在head里

        <html>
            <head>
                <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
            </head>
            <body>
                <div id="app">
                    <p>{{ msg }}</p>
                    <p>{{ msg }}</p>
                    <p>{{ msg }}</p>
                    <p>{{ msg }}</p>
                </div>
            </body>
            <script type="text/javascript">
                new Vue({
                    el: "#app",
                    data: {
                        msg: "message"
                    }
                })
            </script>
        </html>
        
      • 通过斗篷指令

        <html>
            <head>
                <style type="text/css">
                	[v-cloak] { 
                        display: none;
                    }
                </style>
            </head>
            <body>
                <div id="app" v-cloak>
                    <p>{{ msg }}</p>
                    <p>{{ msg }}</p>
                    <p>{{ msg }}</p>
                    <p>{{ msg }}</p>
                </div>
            </body>
            <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
            <script type="text/javascript">
                new Vue({
                    el: "#app",
                    data: {
                        msg: "message"
                    }
                })
            </script>
        </html>
        
    • 属性指令(属性绑定变量)

      • 绑定属性

        <p v-bind:abc="abc"></p>

      • 绑定类

        • 单类名绑定

          <p v-bind:class="c1"></p>

        • 多类名绑定

          <p v-bind:class="[c2, c3]"></p>

          控制每个类样式 {c4: true|false|var}

      • 绑定样式

        • <div :style="div_style"></div>
        • <div :style="{ '100px', height: '100px', backgroundColor: 'blue'}"></div>
    • 事件指令(绑定事件)

      v-on: 指令 简写 @
      不传参事件绑定,但事件回调方法可以获取事件对象
      <p @click="fn"></p>
      参数可以通过传入具体实参
      <p @click="fn()"></p>
      方法函数需要参数并没有传入的情况下,事件对象默认传入(事件对象:$event)
      <p @click="fn()"></p>
      
    • 表单指令

      <div id="app">
          <!-- v-model针对于表单元素 -->
          <form action="" method="get">
              <!-- 1、双向绑定:服务于文本输入框 -->
              <!-- v-model存储的值为输入框的value值 -->
              <div>
                  <input type="text" name="usr" v-model="in_val">
                  <input type="password" name="ps" v-model="in_val" >
                  <textarea name="info" v-model="in_val"></textarea>
              </div>
      
              <!-- 2、单选框 -->
              <div>
                  <!-- 单选框是以name进行分组,同组中只能发生单选 -->
                  <!-- v-model存储的值为单选框的value值 -->
                  男:<input type="radio" name="sex" value="男" v-model="ra_val">
                  女:<input type="radio" name="sex" value="女" v-model="ra_val">
                  {{ ra_val }}
              </div>
      
              <!-- 3、单一复选框 -->
              <!-- v-model存储的值为true|false -->
              <!-- 或者为自定义替换的值 -->
              <div>
                  <input type="checkbox" v-model='sin_val' true-value="选中" false-value="未选中" />
                  {{ sin_val }}
              </div>
      
              <!-- 4、多复选框 -->
              <!-- v-model存储的值为存储值多复选框value的数组 -->
              <div>
                  <input type="checkbox" value="喜好男的" name="cless" v-model='more_val' />
                  <input type="checkbox" value="喜好女的" name="cless" v-model='more_val' />
                  <input type="checkbox" value="不挑" name="cless" v-model='more_val' />
                  {{ more_val }}
              </div>
          </form>
      </div>
      
      <script type="text/javascript">
          new Vue({
              el: '#app',
              data: {
                  in_val: '',
                  // 默认值可以决定单选框默认选项
                  ra_val: '男',
                  // 默认值为true,单一复选框为选中,反之false为不选中
                  sin_val: '',
                  // 数组中存在的值对应的复选框默认为选中状态
                  more_val: ['喜好女的','不挑']
              }
          })
      </script>
      
    • 条件指令

      <div id="app">
          <button @click="toggle">显隐切换</button>
          <!-- v-if -->
          <div class="box r" v-if="isShow"></div>
          <!-- v-show -->
          <div class="box o" v-show="isShow"></div>
          <!-- 1.条件渲染的值为true|false -->
          <!-- 2.true代表标签显示方式渲染 -->
          <!-- 3.false v-if不渲染到页面,v-show以display:none渲染到页面,但也不会显示 -->
      
          <!-- v-if v-else-if v-else 案例 -->
          <ul>
              <li @mouseover="changeWrap(0)">red</li>
              <li @mouseover="changeWrap(1)">green</li>
              <li @mouseover="changeWrap(2)">blue</li>
          </ul>
          <!-- red页面逻辑结构 -->
          <div class="wrap red" v-if="tag == 0" key="0">...</div>
          <!-- green页面逻辑结构 -->
          <div class="wrap green" v-else-if="tag == 1" key="1">...</div>
          <!-- blue页面逻辑结构 -->
          <div class="wrap blue" v-else key="2">...</div>
          <!-- v-if相关分支操作,在未显示情况下,是不会被渲染到页面中 -->
          <!-- 通过key全局属性操作后,渲染过的分支会建立key对应的缓存,提高下一次渲染速度 -->
      
          <!-- v-show 案例 -->
          <ul>
              <li @mouseover="changeMain(0)">red</li>
              <li @mouseover="changeMain(1)">green</li>
              <li @mouseover="changeMain(2)">blue</li>
          </ul>
          <!-- red页面逻辑结构 -->
          <div class="main red" v-show="whoShow(0)">...</div>
          <!-- green页面逻辑结构 -->
          <div class="main green" v-show="whoShow(1)">...</div>
          <!-- blue页面逻辑结构 -->
          <div class="main blue" v-show="whoShow(2)">...</div>
      </div>
      <script type="text/javascript">
          new Vue({
              el: "#app",
              data: {
                  isShow: false,
                  tag: 0,
                  flag: 0
              },
              methods: {
                  toggle () {
                      this.isShow = !this.isShow;
                  },
                  changeWrap (num) {
                      this.tag = num;
                  },
                  changeMain (num) {
                      // this.flag num
                      this.flag = num;
                  },
                  whoShow (num) {
                      // this.flag num
                      return this.flag == num;
                  }
              }
          })
      </script>
      
    • 循环指令

      <div id="app">
          <h1>{{ msg }}</h1>
          <!-- v-for="item in items" -->
          <!-- 遍历的对象: 数组[] 对象(字典){} -->
          <ul>
              <li>{{ list[0] }}</li>
              <li>{{ list[1] }}</li>
              <li>{{ list[2] }}</li>
              <li>{{ list[3] }}</li>
              <li>{{ list[4] }}</li>
          </ul>
      
          <!-- n为遍历的元素值 -->
          <ul>
              <li v-for="n in list">{{ n }}</li>
          </ul>
      
          <!-- 一般列表渲染需要建立缓存 -->
          <!-- 列表渲染是循环,需要赋值变量给key,使用key需要v-bind:处理 -->
          <!-- v-for变量数组[]时,接收两个值时,第一个为元素值,第二个为元素索引 -->
          <ul>
              <li v-for="(n, i) in list" :key="i">value:{{ n }} | index: {{ i }}</li>
          </ul>
      
          <ul>
              <li>{{ dic['name'] }}</li>
              <li>{{ dic.age }}</li>
              <li>{{ dic.gender }}</li>
          </ul>
      
          <!-- v-for变量对象{}时,接收三个值时,第一个为元素值,第二个为元素键,第三个为元素索引 -->
          <ul>
              <li v-for="(v, k, i) in dic" :key="k">value:{{ v }} | key:{{ k }} | index: {{ i }}</li>
          </ul>
      
      
          <!-- 遍历的嵌套 -->
          <div v-for="(person, index) in persons" :key="index" style="height: 21px;">
              <div v-for="(v, k) in person" :key="k" style="float: left;">{{ k }} : {{ v }}&nbsp;&nbsp;&nbsp;</div>
          </div>
      </div>
      <script type="text/javascript">
          new Vue({
              el: "#app",
              data: {
                  msg: "列表渲染",
                  list: [1, 2, 3, 4, 5],
                  dic: {
                      name: 'zero',
                      age: 88888,
                      gender: 'god'
                  },
                  persons: [
                      {name: "zero", age: 8},
                      {name: "egon", age: 78},
                      {name: "liuXX", age: 77},
                      {name: "yXX", age: 38}
                  ]
              }
          })
      </script>
      

    组件

    • 每一个组件都是一个vue实例
    • 每个组件均具有自身的模板template,根组件的模板就是挂载点
    • 每个组件模板只能拥有一个根标签
    • 子组件的数据具有作用域,以达到组件的复用
    根组件
    <div id="app">
        <h1>{{ msg }}</h1>
    </div>
    <script type="text/javascript">
        // 通过new Vue创建的实例就是根组件(实例与组件一一对应,一个实例就是一个组件)
        // 每个组件组件均拥有模板,template
        var app = new Vue({
            // 根组件的模板就是挂载点
            el: "#app",
            data : {
                msg: "根组件"
            },
            // 模板: 由""包裹的html代码块,出现在组件的内部,赋值给组件的$template变量
            // 显式书写模块,就会替换挂载点,但根组件必须拥有挂载点
            template: "<div>显式模板</div>"
        })
        // app.$template
    </script>
    
    局部组件
    <div id="app">
        <local-tag></local-tag>
        <local-tag></local-tag>
    </div>
    <script>
        var localTag = {
            data () {
                return {
                    count: 0
                }
            },
            template: '<button @click="btnAction">局部{{ count }}</button>',
            methods: {
                btnAction () {
                    this.count ++
                }
            }
        }
        new Vue({
            el: "#app",
            components: {
                'local-tag': localTag
            }
        })
    </script>
    
    全局组件
    <div id="app">
        <global-tag></global-tag>
        <global-tag></global-tag>
    </div>
    <script>
        Vue.component('global-tag', {
            data () {
                return {
                    count: 0
                }
            },
            template: '<button @click="btnAction">全局{{ count }}</button>',
            methods: {
                btnAction () {
                    this.count ++
                }
            }
        })
        new Vue({
            el: "#app"
        })
    </script>
    
    父组件传递数据给子组件
    • 通过绑定属性的方式进行数据传递
    <div id="app">
        <global-tag :sup_data1='sup_data1' :supData2='sup_data2'></global-tag>
    </div>
    <script type="text/javascript">
        Vue.component('global-tag', {
            props:['sup_data1', 'supdata2'],
            template: '<div>{{ sup_data1 }} {{ supdata2 }}</div>'
        })
        new Vue({
            el: '#app',
            data: {
                sup_data1: '数据1',
                sup_data2: '数据2'
            }
        })
    </script>
    
    子组件传递数据给父组件
    • 通过发送事件请求的方式进行数据传递
    <div id="app">
        <global-tag @send_action='receiveAction'></global-tag>
    </div>
    <script type="text/javascript">
        Vue.component('global-tag', {
            data () {
                return {
                    sub_data1: "数据1",
                    sub_data2: '数据2'
                }
            },
            template: '<div @click="clickAction">发生</div>',
            methods: {
                clickAction () {
                    this.$emit('send_action', this.sub_data1, this.sub_data2)
                }
            }
        })
        new Vue({
            el: '#app',
            methods: {
                receiveAction (v1, v2) {
                    console.log(v1, v2)
                }
            }
        })
    </script>
    

    生命周期钩子

    • 表示一个Vue实例从创建到销毁的这个过程,将这个过程的一些时间节点赋予了对应的钩子函数
    • 钩子函数: 满足特点条件被回调的方法
    new Vue({
        el: "#app",
        data: {
            msg: "message"
        },
        beforeCreate () {
            console.log("实例刚刚创建");
            console.log(this.msg
                        
        },
        created () {
            console.log("实例创建成功, data, methods已拥有");
            console.log(this.msg);
        },
        mounted () {
            console.log("页面已被vue实例渲染, data, methods已更新");
        }
        // 拿到需求 => 确定钩子函数 => 解决需求的逻辑代码块
    })
    

    Vue-CLI 项目搭建

    1、环境搭建
    • 安装node
    官网下载安装包,傻瓜式安装:https://nodejs.org/zh-cn/
    
    • 安装cnpm
    npm install -g cnpm --registry=https://registry.npm.taobao.org
    
    • 安装脚手架
    cnpm install -g @vue/cli
    
    • 清空缓存处理(如果上面的步骤出现错误可以使用这个方法来清空后重新安装)
    npm cache clean --force
    
    2、Vue项目常用命令
    • 创建项目
    vue create 项目名
    
    • 启动/停止项目
    npm run serve / ctrl+c
    
    • 打包项目
    npm run build
    
    3、Vue项目
    • 项目目录
    dist: 打包的项目目录(打包后会生成)
    node_modules: 项目依赖
    public: 共用资源
    src: 项目目标,书写代码的地方
        -- assets:资源
        -- components:组件
        -- views:视图组件
        -- App.vue:根组件
        -- main.js: 入口js
        -- router.js: 路由文件
        -- store.js: 状态库文件
    vue.config.js: 项目配置文件(没有可以自己新建)
    
    • main.js
    new Vue({
        el: "#app",
        router: router,
        store: store,
        render: function (h) {
            return h(App)
        }
    })
    
    • .Vue文件
    <template>
        <!-- 模板区域 -->
    </template>
    <script>
        // 逻辑代码区域
        // 该语法和script绑定出现
        export default {
            
        }
    </script>
    <style scoped>
        /* 样式区域 */
        /* scoped表示这里的样式只适用于组件内部, scoped与style绑定出现 */
    </style>
    

    项目功能插件

    vue-router
    {
        path: '/',
        name: 'home',
        // 路由的重定向
        redirect: '/home'
    }
    
    {
        // 一级路由, 在根组件中被渲染, 替换根组件的<router-view/>标签
        path: '/one-view',
        name: 'one',
        component: () => import('./views/OneView.vue')
    }
    
    {
        // 多级路由, 在根组件中被渲染, 替换根组件的<router-view/>标签
        path: '/one-view/one-detail',
        component: () => import('./views/OneDetail.vue'),
        // 子路由, 在所属路由指向的组件中被渲染, 替换该组件(OneDetail)的<router-view/>标签
        children: [{
            path: 'show',
            component: () => import('./components/OneShow.vue')
        }]
    }
    <!-- router-link渲染为a标签 -->
    <router-link to="/">Home</router-link> |
    <router-link to="/about">About</router-link> |
    <router-link :to="{name: 'one'}">One</router-link> |
    
    <!-- 为路由渲染的组件占位 -->
    <router-view />
    a.router-link-exact-active {
        color: #42b983;
    }
    // router的逻辑转跳
    this.$router.push('/one-view')
    
    // router采用history方式访问上一级
    this.$router.go(-1)
    
    vuex
    // 在任何一个组件中,均可以通过this.$store.state.msg访问msg的数据
    // state永远只能拥有一种状态值
    state: {
        msg: "状态管理器"
    },
    // 让state拥有多个状态值
    mutations: {
        // 在一个一个组件中,均可以通过this.$store.commit('setMsg', new_msg)来修改state中的msg
        setMsg(state, new_msg) {
            state.msg = new_msg
        }
    },
    // 让mutations拥有多个状态值
    actions: {
    
    }
    
    vue-cookies
    // 安装cookie的命令
    // npm install vue-cookies --save
    // 为项目配置全局vue-cookie
    import VueCookies from 'vue-cookies'
    // 将插件设置给Vue原型,作为全局的属性,在任何地方都可以通过this.$cookie进行访问
    Vue.prototype.$cookies = VueCookies
    // 持久化存储val的值到cookie中
    this.$cookies.set('val', this.val, 300)
    // 获取cookie中val字段值
    this.$cookies.get('val')
    // 删除cookie键值对
    this.$cookies.remove('val')
    
    axios
    // 安装 axios(ajax)的命令
    // npm install axios--save
    // 为项目配置全局axios
    import Axios from 'axios'
    Vue.prototype.$ajax = Axios
    let _this = this
    this.$ajax({
        method: 'post',
        url: 'http://127.0.0.1:5000/loginAction',
        params: {
            usr: this.usr,
            ps: this.ps
        }
    }).then(function(res) {
        // this代表的是回调then这个方法的调用者(axios插件),也就是发生了this的重指向
        // 要更新页面的title变量,title属于vue实例
        // res为回调的对象,该对象的data属性就是后台返回的数据
        _this.title = res.data
    }).catch(function(err) {
        window.console.log(err)
    })
    # 用pycharm启动该文件模拟后台
    from flask import Flask, request, render_template
    from flask_cors import CORS
    app = Flask(__name__)
    CORS(app, supports_credentials=True)
    
    @app.route('/')
    def index():
        return "<h1>主页</h1>"
    
    @app.route('/loginAction', methods=['GET', 'POST'])
    def test_action():
        # print(request.args)
        # print(request.form)
        # print(request.values)
        usr = request.args['usr']
        ps = request.args['ps']
        if usr != 'abc' or ps != '123':
            return 'login failed'
        return 'login success'
    
    
    if __name__ == '__main__':
        app.run()
    
  • 相关阅读:
    Zabbix实战-简易教程(7)--监控第一台host
    Zabbix实战-简易教程(6)--Server端高可用
    Zabbix实战-简易教程(5)--Proxy和Agent端(源码和yum方式)
    HDFS“慢节点”监控分析功能
    遇见InterruptedException异常,怎么办?
    遇见InterruptedException异常,怎么办?
    Hadoop Erasure Coding结构分析
    Hadoop Erasure Coding结构分析
    聊聊错误注入技巧
    聊聊错误注入技巧
  • 原文地址:https://www.cnblogs.com/Gredae/p/11885416.html
Copyright © 2011-2022 走看看