zoukankan      html  css  js  c++  java
  • Vue项目

    Vue项目:

    vue全家桶

    vue-cli + vue核心 + axios/featch+ vue-router + vuex(vue全家桶)

    +webpack + es6 + scss的项目架构成为了越来越多大公司的第一选择。

    Vue2大核心思想:组件化和数据驱动

    组件化:把整个拆分为各个可以复用的个体

    数据驱动:通过数据的变化直接影响bom展示 ,避免dom操作。

    生成一个vue项目(可以选择formalprohect1111预设)

    上传到git上时要写一个忽略文件,先删除里面的所有代码,然后赋值

    .DS_Store
    /node_modules

    即可

    1.安装一个vue@cli的脚手架, cnpm install -g @vue/cli 电脑安装过一次就不用安装了

    2.创建项目 vue create myapp(名字不能包含大写)

    可以选择之前的预设,也可以自己重新设置(Manually select features)
    

    如果是复制vue脚手架模板需要cnpm i 安装依赖 (注意电脑卡的话最好别在vscode里面安装依赖,可以直接在文件夹中安装)

    3.更改package.json文件,加上一个dev : "npm run serve"

    4.将src目录下的App.vue中的部分代码删了

    5.书写

    • App.vue文件中写html结构

    • 找到lib文件,赋值到src目录下

    • 在App.vue文件中引入

    • 如果需要引入小图标的话可以引入图标的scss库,public>index

    • <link rel="stylesheet" href="//at.alicdn.com/t/font_1211795_gfmrt26v3ws.css">
      

    6.基本页面写好了,就开始抽离页面组件。

    • 在view文件夹下创建一个home文件夹,在文件夹内创建一个index.vue文件
    • 然后复制成4份,4个页面组件

    7.找到router.js文件,配置路由

    8.在app.vue页面中更改需要抽离的内容

    <router-view></router-view>//跳转到指定模块
    

    9.在common文件夹下创建一个common文件夹,新建一个Prolist.vue组件,

    10.在home文件下,写入请求数据,请求到数据后

    import Prolist from '@/components/common/Prolist'
    

    引入子组件,并在components里面注册,注册完后将data中写入请求到的数据,并在

    子组件中绑定数据,数据绑定成功后去子组件中接收数据,props:['prolist']接收数据

    编程式导航和声明式导航

    编程式跳转:用于在js中处理逻辑后需要页面进行跳转

    vue的路由我们可以看做是一个数组,每次添加一个页面可以看成是向数组中push一个地址,当点击返回时就是向数组中的上一个值查找。

    编程式跳转其实就是调用: this.$router.push( )

    li 标签中加入点击函数@click="goDetail(item.id)"

    <!-- 编程式跳转 -->
        <li class="proitem" v-for="(item, index) of prolist" @click="goDetail(item.id)" :key="index">
          <div class="itemimg">
            <img :src="item.images.small" :alt="item.alt" />
          </div>
          <div class="iteminfo">
            <h3>{{ item.title }} --- {{ item.rating.average }}</h3>
            <div class="directors">
              导演:<span v-for="(itm, idx) of item.directors" :key="idx">{{ itm.name }}/</span>
            </div>
            <div class="casts">
              演员: <span v-for="(itm, idx) of item.casts" :key="idx">{{ itm.name }}/</span>
            </div>
            <Rating :rating="(item.rating.average / 2).toFixed(1)"/>
          </div>
        </li>
    

    在export default中的methods中加入

    goDetail(id) {
        //this.$router.push( '/detail/' + id ) //string类型的参数
        //this.$router.push( { name: 'detail', params: { id } } ) //object类型参数
        this.$router.push( { path: '/detail/' + id } ) //object类型 
    
    声明式导航:用于直接渲染到页面中,

    声明式跳转中的to参数怎么写,编程式跳转中参数就怎么写

    <router-link tag="li" :to="{ name: 'detail', params: { id: item.id } }" class="proitem" v-for="(item, index) of prolist" :key="index">
    </router-link>
    

    Vue调用vant-ui库api

    vue引入vant ui库

    1.安装依赖

    cnpm / npm i vant -S

    2.按需加载(推荐)

    cnpm i babel-plugin-import -D

    3.在babel.config.js文件下配置

    4.在需要使用的文件内的script中引入

    <script>
    import Vue from 'vue'
    import { Button } from 'vant'
    Vue.use(Button)
    
    export default {
    }
    </script>
    

    5.编写样式即可

    例如按钮
    <van-button type="default">默认按钮</van-button>
    <van-button type="primary">主要按钮</van-button>
    

    1. 返回顶部按钮

    1. 先在components文件夹下创建一个Backtop.vue写一个返回顶部按钮组件

      <template>
        <div class="backTop" v-show="vShow" @click="backtop">
          <van-icon name="upgrade" size="40px"/>
        </div>
      </template>
      
      <script>
      import Vue from 'vue'
      import { Icon } from 'vant'
      Vue.use(Icon)
      
      export default {
        props: ['vShow'],
        methods: {
          backtop () {
            const content = document.getElementById('content')
            content.scrollTop = 0
          }
      }
      </script>
      
    2. 组件的使用

      • 组件的滚动区域的标签上添加属性 id="content"
      • 在script标签中引入import Backtop from '@/components/Backtop'
      • 在components中注册组件 Backtop
      • 在滚动区域标签底部加上<Backtop v-show="flag"/>
       * 哪一个页面需要使用返回顶部 
       * 组件的滚动区域的标签上添加属性  id="content"
       * v-show代表的是返回顶部按钮  显示还是隐藏
       * 在组件内部 mounted 的钩子函数内部,监听滚动条的变化
       * data () {
       *  return {
       *    flag: false
       *  }
       * }
       * mounted () {
       *  const content = document.querySelector('#content')
          // 开启监听滚动条的滚动事件
          content.addEventListener('scroll', this.scrollFn)
       * }
        实现滚动的函数
        methods: {
          scrollFn () {
            if (event.target.scrollTop > 150) {
              this.flag = true
            } else {
              this.flag = false
            }
          }
        }
       * 
       * <div class="content" id="content">
       *  <Backtop v-show="flag"/>
       * </div>
      
      

    路由守卫

    1.全局的路由守卫

    1.声明一个路由 const router = new Router{....},

    2.调用这个路由的全局导航守卫

    router.beforeEach((to, from, next) => {
    	//全局导航守卫,一般不推荐使用,但是后台管理系统中可以用
    })
    

    3.导出这个模块 export default router export default 只能导出一个默认模块,这条main.js就能import导入这个路由了

    例如:
    const router = new Router({
         ......
    })
    //  全局导航守卫 ------- 一般不推荐使用 -------后台管理系统会用
    router.beforeEach((to, from, next) => {
      if (to.name === 'login' || to.name === 'register') { // 如果没有这一句会造成死循环,登录页面也是路由,造成内存溢出
        next()
      } else {
        if (localStorage.getItem('isLogin') === 'ok') {
          next()
        } else {
          next('/login')
        }
      }
    })
    export default router //export default 只能导出一个默认模块,这个模块可以匿名
    
    2.路由独享的守卫

    在需要进行判断是否登录的页面的路由定义中定义

    {
          path: '/cart', // 浏览器地址输入/cart时
          name: 'cart', // 路由的名字
          // component: () => import('./views/cart/index.vue')
          components: {
            default: () => import('./views/cart/index.vue'),
            footer: Footer
          },
          //  路由独享守卫  ---本来就是一个路由的配置文件,写什么业务逻辑
          beforeEnter (to, from, next) {
            if (localStorage.getItem('isLogin') === 'ok') {
              next()
            } else {
              next('/login')  //注意这里不能加点,加点容易出bug,点表示当前目录下子文件跳转,比如user中也有一个login,我在user中点购物车,就进入了user/login,出现bug
            }
          }
        },
    
    3.组件级别的导航守卫

    在需要导航守卫的页面中加入导航守卫即可

    beforeRouteLeave (to, from, next) { // 在离开这个导航之前  ---导航守卫者
        const content = document.getElementById('content')
        content.removeEventListener('scroll', this.scrollFn)
        let position = content.scrollTop
        localStorage.setItem('position', position)
        next() // 继续执行后续的业务逻辑
      },
    

    进入列表详情,返回还在原来的位置

    1. 先在router.js文件中开启keepAlive这个属性

      meta: {
          keepAlive: true
      }
      
    2. 在App.vue中判断keepAlive是否为true

      <keep-alive>
        <router-view v-if="$route.meta.keepAlive"></router-view>
      </keep-alive>
      <router-view v-if="!$route.meta.keepAlive"></router-view>
      
    3. 在home.vue中监听滚动条的位置

      beforeRouteLeave (to, from, next) { // 在离开这个导航之前  ---导航守卫者
          const content = document.getElementById('content')
          let position = content.scrollTop
          localStorage.setItem('position', position)
          next() // 继续执行后续的业务逻辑
        },
        watch: {
          $route (newVal, oldVal) {
            if (newVal.name === 'home') {
              const content = document.getElementById('content')
              content.scrollTop = localStorage.getItem('position')
            }
          }
        }
      

    VueX状态管理器

    1.先在store.js文件中布置好状态管理器
    export default new Vuex.Store({
      state: { // 需要管理的组件的状态
        loginState: ''
      },
      mutations: { // 唯一改变状态的地方
        changeLoginState (state, data) { // state代表的是初始化的数据
          state.loginState = data
        }
      },
      actions: {
    
      }
    })
    
    2.获取状态管理器中的值 state
    1.用变量直接接收获取的值
    const { $store: { state: { loginState } } } = this
          if (loginState === 'ok') {
            console.log('加入购物车')
          }
    
    2.mapState辅助函数
    import { mapState } from 'vuex'  //引入模块
    computed: {   //计算属性
        ...mapState({
          //loginState: (state) => { return state.loginState }
            loginState: 'loginState'
        })
      },
    if (this.loginState === 'ok') {   // 直接使用
        console.log('立即购买')
      }
    
    3.mapGetters (mapGeters相当于mapState的计算属性,能理解就用,不理解也可以不用。既然我们可以通过mapState拿到属性值,我们也可以直接在compute里面写计算属性,就不用、mapGetters了。)
    第一种写法:
    	在store.js文件中
    	 state: { // 需要管理的组件的状态
    	    loginState: '',
    	    list: [1, 2, 3, 4, 5, 6]
    	  },
    	  getters: { // 可以看做是state的计算属性,类似组件中的 data 与 compute
    	    len (state) {
    	      return state.list.length
    	    }
    	  },
         在获取值页面直接获取
         {{ this.$store.getters.len }}
    第二种写法:
    	获取值
    	import { mapState, mapGetters } from 'vuex' //引入mapGetters模块
    	computed: {
        ...mapGetters({ // 获取值不能使用函数
          len: 'len'
       	 })
      	},
          {{ len }}  //直接使用
    第三种写法:即不用mapGetter
    	computed: {
        ...mapState({
          list: 'list' //通过mapState拿到属性值
        }),
        len () { // 计算属性
          return this.list.length
        }
    
    3.提交至状态管理器中的值 mutations 改变数据的方式(必须是同步的函数,只干同步的事,改值)

    **this.$store.commit() ** //提交数据方式

    1.直接提交
    this.$store.commit('changeLoginState', 'ok')
    this.$store.commit('changeLoginState', {
       result: 'ok'    //提交一个对象
    })
    2.使用 ES6 风格的计算属性命名功能来使用一个常量作为函数名  //没啥实际意义就是感觉逼格不一样了
    	创建一个mutation-types.js文件  
    	内容:export const CHANGE_LOGIN_STATE = 'changeLoginState' //定义一个函数名
        在store.js中用常量代替函数名
        [CHANGE_LOGIN_STATE] (state, data) {
          state.loginState = data.result
        }
    	在提交值页面引入
        import { CHANGE_LOGIN_STATE } from '@/mutation-types'
    	提交代码:
        this.$store.commit({
           type: CHANGE_LOGIN_STATE,//函数名改为常量定义的名字。
           result: 'ok'
        })
    注:如果自定义的常量函数名过多,我们可以换一种方法引入
    	import * as types from '@/mutation-types' 
    	提交代码:
        this.$store.commit({
           type: types.CHANGE_LOGIN_STATE,//函数名改为常量定义的名字。
           result: 'ok'
        })
        
    
    4. actions 异步操作
    第一种方法:
    1.在store.js页面中的actions添加回调函数
    actions: { // 异步操作
        getKindListData (context) { // 可以理解为this.$store,但不是this.$store
          fetch('https://www.daxunxun.com/douban').then(res => 		 res.json()).then(data => {
            context.commit(types.CHANGE_KIND_LIST, {
              result: data
            })
          })
        }
      }
    })
    2.在需要提交的页面中
       mounted () { //组件内部通过dispatch触发store中的action
           this.$store.dispatch('getKindListData')
       }
    
    第二种方法:利用mapActions辅助函数
    import { mapState, mapActions } from 'vuex' //引入组件
    methods: {  //利用mapActions将事件复制到一个变量
        ...mapActions({
          getKindListData: 'getKindListData' // 前者代表当前组件生成getKindListData自定义函数,后者代表状态管理器中的actions
        })
      },
     mounted () { //组件内部直接调用这个函数
        this.getKindListData()
      }
    
    

    混入mixin

    1.创建文件夹mixins,创建文件mymixins
    import Header from '@/components/common/Header'
    
    export default {
      components: {
        Header
      }
    }
    2.在需要引入的页面引入
    import mymixins from '@/mixins/mymixins'
    3.在export default 中声明,即可使用注册的模块
      mixins: [mymixins],
    
    

    自定义指令

    1.全局自定义指令,在main.js中自定义
     Vue.directive('focus', {
       inserted: function (e) {
         e.focus()
       }
     })
    在需要使用的标签中,直接输入 v-focus
    
    2.局部自定义指令,在需要使用的页面的export default中自定义
    export default {
      directives: {
        'focus': {
          inserted (e) {
            e.focus()
          }
        }
      },
      在需要使用的标签中,直接输入 v-focus
    
  • 相关阅读:
    数组和字符串长度length
    Eclipse最有用快捷键整理
    Eclipse编辑java文件报Unhandled event loop exception错误的解决办法
    Java 删除项目中的.svn信息
    oracle 删除外键约束 禁用约束 启用约束
    Java Sftp上传下载文件
    java 如何判断操作系统是Linux还是Windows
    Javascript-正则表达式-开发中的使用.
    Eclipse和PyDev搭建完美Python开发环境 Windows篇
    ExtJS4为form表单必填项添加红色*标识
  • 原文地址:https://www.cnblogs.com/jtjianfeng/p/11356700.html
Copyright © 2011-2022 走看看