vue 项目开发要点总结

发布时间:2019-08-13 发布网站:脚本宝典
脚本宝典收集整理的这篇文章主要介绍了vue 项目开发要点总结脚本宝典觉得挺不错的,现在分享给大家,也给大家做个参考。

vue-cli 脚手架工具的使用

vue-cli 的依赖
clipboard.png

vue-cli 的使用流程
clipboard.png

node 的安装
node 是通过js 操作系统接口的语言; npm 是node的包管理工具;所以,安装了node 就可以直接使用npm 下载我们需要的包;
node 可以直接去node官网下载对应系统的安装包,安装提示完成;
然后在 命令行中 通过 npm -v 查看npm 版本,如果有出来代表安装成功;

npm 代理 到cnpm
你直接通过添加 npm 参数 alias 一个新命令:

alias cnpm="npm --registry=https://registry.npm.taobao.org 
--cache=$HOME/.npm/.cache/cnpm 
--disturl=https://npm.taobao.org/dist 
--userconfig=$HOME/.cnpmrc"

然后运行

cnpm  install xx -g  //全局安装xx

使用 vue-cli

vue inIT webpack demoName //生成 webpack 为模板的vue项目

clipboard.png

运行热更新页面

npm run dev

生成项目可以直接通过 http://localhost:8080/?#/ 访问

如果你是拉别人的项目运行的,要先运行下面的命令,安装依赖包

npm install 
@H_526_126@//或者
npm i

生成一个 静态项目文件(直接打开的静态页面)

npm run build
大多数情况 ,生成的页面是不可以直接打开的;提示只能部署到 服务器上才能正常访问;
如果需要直接本地打开;到项目目录下的config文件夹里的index.js文件中,将build对象下的assetsPublicPath中的“/”,改为“./”即可

vue 项目开发要点总结


生成的文件都是经过压缩的,带md5的文件

es6 的引入与输出

export default{} , module.exports = {}, exports { }

在node 的模块中,exports 是 module.exports 的引用;但是在vue 中 不能写成

exports = {
    porps:['text']
}

// 提示 text 未定义;

exports default {} 定义的输出;可以通过 import xx 直接使用(标准ES6);写法是:

exports default {a:123}    

import a; 

module.exports = {} 与 exports default 是等价的

但是如果 同一个js 同时出现 module.exports ={} 和 import 就会报错


module.exports = {a:123} //定义和导出

import a;  //引入

//上面两个关键词 不能同时出现在同一个js 中

报错原因如下:

webpack可以使用require和export ,但是不能混合使用import 和module.exports ,不然会报错Cannot
assign to read only PRoPErty 'exports' of object '#<Object>'
ES6 统一的写法 是 import 和 exports default
如果你要import 组件 ;建议 统一使用 exports default {} 编写组件

vue 项目开发要点总结

vue 项目开发要点总结

vue-router 路由插件安装

安装

cnpm install vue-router 

引入为全局插件

vue 项目开发要点总结

配置路由表

vue 项目开发要点总结

可以通过router-link 组件 链接到 对应组件;它会解析成类似a 标签

<router-link :to="{path:'forms'}">forms</router-link>  //注意书写格式一定要正确
<router-link :to="{path:'father'}">father</router-link>

vue 项目开发要点总结

注意到 生成的url 中前面自动加了个 “#”;可以通过添加 mode:'history', 去掉

vue 项目开发要点总结

原理:https://router.vuejs.org/zh-c...

路由配置中,path 可以设置 url 带参;

带参path定义

vue 项目开发要点总结

表示 apple 后面跟的是参数,不是路径;

带参路径

vue 项目开发要点总结

获取参数

vue 项目开发要点总结

使用路由要注意的地方

@H_85_406@
  • 所有的路由都是定义在 routes 生成的页面中的;不能在子组件中重新定义;例子如下:
  • VAR router = new VueRouter()
    
    import browSEMode From './components/browse-mode.vue'
    import blogList from './components/bLOG-list.vue'
    import blogArticle from './components/blog-article.vue'
    import writePanel from './components/write-panel.vue'
    
    router.map({
        '/': {
          component: browseMode,
          subRoutes: {
            '/': {
              component: blogList
            },
            '/details/:artId': {
              component: blogArticle
            }
          }
        },
        '/edit/:mode': {
          component: writePanel
        },
        '/seArch/tag/:tag': {
          component: browseMode,
          subRoutes: {
            '/': {
              component: blogList
            }
          }
        },
        '/search/time/:time': {
          component: browseMode,
          subRoutes: {
            '/': {
              component: blogList
            }
          }
        },
        '/search/title/:title': {
          component: browseMode,
          subRoutes: {
            '/': {
              component: blogList
            }
          }
        },
    })
    router.start(App, 'app')
    • 路由不是最适合做tab切换的;最适合做tab的是 components 内置组件 ;通过is 控制切换;
    <component v-bind:is="currentView">
    
    var vm = new Vue({
      el: '#example',
      data: {
        currentView: 'home' //改变这个值就会切换内容;
      },
      components: {
        home: { /* ... */ },
        posts: { /* ... */ },
        archive: { /* ... */ }
      }
    })
    • 定义带参路由 的时候 注意格式是 path:'/box1/:text', 不是path:'/box1:text',(可以理解为/: 后面是参数 ,/后面是路径;)

    vue 项目开发要点总结

    • 定义好路由后, router-link 是可以放在任何地方的;它就是一个a标签;点击会切换第一个父级的router-view 中的页面;还要注意格式和传参
     <li class="tab1"><router-link :to="{path:'box1/666'}">box1</router-link></li>
    
     // to的 值是一个对象 ,key 固定是path ,value 是 一个字符串;
     // 后面的666 是参数;它的前面不是 “ ?或者 & ” 而是 “ / ”;
    • 获取参数的时候,直接去到参数的值是 this.$route.params.text (text是你定义路由时的 :text )

    vue 项目开发要点总结

    • 因为$route 是一个全局变量,你还可以直接在htML 中使用它的url参数
    <div>{{$route.params.text}}</div>

    定义一个多参数 路由的 url

    vue 项目开发要点总结

    使用时的url可能是这样:

    http://localhost:8080/#/apple/red/detail/fool
    //后面的detail 是固定的。

    获取的方法是一样的;

    var a = $route.params;
    
    //结果
    a={
        color:red,
        type:fool
    }

    子路由的定义

    {
      path:'/box1',
      component:box1,
      children:[
        {
          // 当 /box1/box1a匹配成功,
          // box1a会被渲染在 box1的 <router-view> 中
          path:'box1a', //这里不加 “ / ”
          component:box1a
        },
        {
          path:'box1b',
          component:box1b
        }
      ]
    },
    // 要注意,以 / 开头的嵌套路径会被当作根路径。 这让你充分的使用嵌套组件而无须设置嵌套的路径。
    
    
    
    //在box1 中定义一行 
    
    <router-view/>
    
    //子组件 box1a 会自动渲染 到页面中;
    
    //如果添加两个 router-link 组件 就可以做tab切换(不建议用路由做tab)
    //router-link 只会切换 第一个父级的 router-view 中的内容,所以不会刷新整个 box1 ;
    
    <ul>
      <li class="tab1"><router-link :to="{path:'/box1/box1a'}">box1a</router-link></li>
      <li class="tab2"><router-link :to="{path:'/box1/box1b'}">box1b</router-link></li>
    </ul>
    
    //path 写成 /box1/box1a  是用了根路径(绝对路径)的形式;
    //如果写成 {path:'box1a'} 则是相对路径;这样写点击 浏览器的url会写成 http://localhost:8080/box1a
    //因为顶级路由中是没有定义 box1a 组件的;所以页面空白;
    
    带参子路由
    //路由定义
    {
      path:'/box1/:text',
      component:box1,
      children:[
        {
          path:'box1a',
          component:box1a
        },
        {
          path:'box1b',
          component:box1b
        }
      ]
    },
    
    
    //跳转到 box1 的写法
     <li class="tab1"><router-link :to="{path:'box1/789'}">box1</router-link></li>
    
    //box1 中渲染 box1a/b 的写法
    <ul>
      <li class="tab1"><router-link :to="{path:url1}">box1a</router-link></li>
      <li class="tab2"><router-link :to="{path:url2}">box1b</router-link></li>
    </ul>
    
    //初始化的时候生成url
     mounted: function () {
                this.parms = this.$route.params.text;
                this.url1 = '/box1/'+this.parms+'/box1a'
                this.url2 = '/box1/'+this.parms+'/box1b'
              },
    • router-link 中的to 属性,如果只是简单的跳转可以直接写成 to=“box1”;
    • 如果加上:绑定属性;后面的属性可以是简短的 表达式,因此上面的例子可以简化为:
    //路由定义
    {
      path:'/box1/:text',
      component:box1,
      children:[
        {
          path:'box1a',
          component:box1a
        },
        {
          path:'box1b',
          component:box1b
        }
      ]
    },
    
    
    //跳转到 box1 的写法
     <li class="tab1"><router-link :to="{path:'box1/789'}">box1</router-link></li>
    
    //box1 中渲染 box1a/ b 的写法
    //to 属性会自动 运算出来;
    <ul>
      <li class="tab1"><router-link :to="/box1/'+parms+'/box1a'">box1a</router-link></li>
      <li class="tab2"><router-link :to="'/box1/'+parms+'/box1b'">box1b</router-link></li>
    </ul>
     
    
    
    //初始化的时候生成url
     mounted: function () {
                this.parms = this.$route.params.text;
              },
    具名路由

    router-link 还可以通过 name 指定跳转(具名路由);通过例如 tag="li" 指定包裹标签为a以为的tag;

     children:[
            {
              path:'box1a',
              name:"nameBox",
              component:box1a
            }
            ]
            
     <router-link :to="{name:'nameBox'}" tag="li">nameBox</router-link>       
            
    //结果:会生成li, 点击router-view 会渲染出 box1a ;注意,path是不可缺少的
            

    用具名路由布局(代替iframe的方式)

    export default new Router({
      mode:'history',
      routes: [
        {
          path:'/index',
          components:{   //注意这里是有 “ s ” 的
            default:vuexIndex,  //对应 <router-view/>
            left:vuexLeft,    // 对应<router-view name="left"></router-view>
            right:vuexRight  //对应<router-view name="right"></router-view>
          }
        }
      ]
    })
    
    
    <template>
      <div id="app">
        <router-view/>
        <div class="content">
          <router-view name="left"></router-view>
          <router-view name="right"></router-view>
        </div>
      </div>
    </template>
    
    //注意访问的路径 是在components 中定义的path ;
    

    在某个页面中定义具名路由

    {
      path:'/layout',
      name:'layout',
      component:layout,
      children: [
        {
          path: '/',
          components:{
            default:main,
            leftView:leftView,
            topBar:topBar
          },
        }
      ]
    }
    
    
    
    
    
    路由的重定向
     routes: [
        { path:'/', redirect:'/box' //路径不存在就跳转到box
        },
        { path: '/a', redirect: '/b' } //访问a的路径,都跳转到b
    ]

    vuex 状态管理插件安装

    当vue项目中 组件过多并设计到功能某些数据的时候,管理数据变得复杂,VUEX 就是通过自身的一套数据管理流程帮助你管理 项目数据(状态);

    vue 项目开发要点总结

    安装

    cnpm install vuex --save

    实例化

    //在main.js 中
    
    import Vuex from 'vuex'
    
    Vue.use(Vuex);
    let store = new Vuex.Store({  //Store 是vuex 方法
      state:{ //存放变量的地方
        total:0,
        appleTotal:0,
        bananaTotal:0,
      },
      mutations:{     //定义同步变量的方法
        aSetValue(state,value){
          state.appleTotal = value
          state.total = state.appleTotal + state.bananaTotal;
        },
        bSetValue(state,value){
          state.bananaTotal = value
          state.total = state.appleTotal + state.bananaTotal;
        }
      }
    })
    
    
    new Vue({
      el: '#app',
      store,   //在实例中 引入
      router,
      components: { App },
      template: '<App/>'
    })
    

    获取值

    vuex 的变量store 全局以后可以通过以下语句获取

    this.$Store.state.total 
    
    //组件中
     <h3>总价:<span>{{$store.state.total}}</span></h3>

    还可以通过设置getter函数 暴露对应的值

     getters:{
        getTotal(state){
          return state.total
        }
      },
    
    //组件中
    
    <h3>总价:<span>{{$store.getters.getTotal}}</span></h3>

    改变vuex变量的值

    通过在组件中调用以下特定语句改变

     methods:{
          add(){
            this.cnt += 1;
            //bSetValue 是在vuex实例的mutations中定义的方法
            //通过 bSetValue方法 去改变实例的值
            this.$store.COMmit('bSetValue',this.cnt*5) 
          },
          minus(){
            this.cnt-=1;
            this.$store.commit('bSetValue',this.cnt*5)
          }
        },
        
     // 在vuex 中只有 commit 方法可以改变数据;这里是不建议直接在组件中调用 cmmit 的
     // 因为cmmit中只能是同步操作;但是交互往往需要同步数据库
     // 更加好的方法是在 actions的方法 中触发 commit;actions 方法支持异步操作
     // 所有涉及 后端API 的接口都是放在actions 中进行   

    actions 属性

    
    mutations:{
            aSetValue(state,value){
              state.appleTotal = value
              state.total = state.appleTotal + state.bananaTotal;
            },
            bSetValue(state,value){
              state.bananaTotal = value
              state.total = state.appleTotal + state.bananaTotal;
            }
      },
    actions:{ 
             // 定义doAfn 方法,间接触发 aSetValue;
             // 在doAfn 方法是可以用ajax 的
            doAfn(context,price){
              context.commit('aSetValue',price)
            },
            doBfn(context,price){
              context.commit('bSetValue',price)
            }
      }
    

    组件中的触发方式 通过 dispatch 触发doAfn;

    this.$store.dispatch('doAfn',val*10)

    vuex 的 modules

    Vuex 允许我们将 store 分割成模块(module)。每个模块拥有自己的 state、mutation、action、getter、甚至是嵌套子模块——从上至下进行同样方式的分割:

    官方文档代码

    const moduleA = {
      state: { ... },
      mutations: { ... },
      actions: { ... },
      getters: { ... }
    }
    
    const moduleB = {
      state: { ... },
      mutations: { ... },
      actions: { ... }
    }
    
    const store = new Vuex.Store({
      modules: {
        a: moduleA,
        b: moduleB
      }
    })
    
    store.state.a // -> moduleA 的状态
    store.state.b // -> moduleB 的状态

    官方的文档组织建议:

    • 应用层级的状态应该集中到单个 store 对象中。
    • 提交 mutation 是更改状态的唯一方法,并且这个过程是同步的。
    • 异步逻辑都应该封装到 action 里面。

    对于大型应用,我们会希望把 Vuex 相关代码分割到模块中。下面是项目结构示例:

    ├── index.html
    ├── main.js
    ├── api
    │   └── ... # 抽取出API请求
    ├── components
    │   ├── App.vue
    │   └── ...
    └── store
        ├── index.js          # 我们组装模块并导出 store 的地方
        ├── actions.js        # 根级别的 action
        ├── mutations.js      # 根级别的 mutation
        └── modules
            ├── cart.js       # 购物车模块
            └── products.js   # 产品模块

    https://vuex.vuejs.org/zh-cn/...

    一个 vuex 小例子

    vue 项目开发要点总结

    父组件
    <template>
      <div class="left">
        <h1>我是left</h1>
        <div class="tips">(我是{{text?text:'路由的方式'}}来的)</div>
        <div class="left-content">
          <div class="item-box">
            <apple/>
            <banana/>
          </div>
          <div class="price">
            <h3>总价:<span>{{$store.getters.getTotal}}</span></h3>
          </div>
        </div>
      </div>
    </template>
    <script>
        import apple from '@/components/vuex/apple.vue'
        import banana from '@/components/vuex/banana.vue'
        export default {
            data: function () {
                return {
                }
            },
          components:{
            apple,
            banana
          },
          props:['text']
        }
    </script>
    <style scoped>
      h1{
        text-align: center;
      }
      .left-content{
        margin-top: 20px;
      }
      .item-box{
        width: 48%;
        display: inline-block;
      }
      .price{
        width: 50%;
        display: inline-block;
        vertical-align: bottom;
      }
      .item{
        font-size: 15px;
        margin-top: 20px;
        margin-left: 20px;
      }
    
    </style>
    
    apple 组件
    <template>
      <div class="item">
        <span>苹果</span>
        <button @click="add">add</button>
        <button @click="minus">minus</button>
        <input v-model.number.lazy="cnt">
        <span v-if="noEnough" class="red">库存不够</span>
      </div>
    </template>
    <script>
        module.exports = {
          data: function () {
              return {
                cnt:0,
                noEnough:false
              }
          },
          methods:{
              add(){
                this.cnt += 1;
              },
              minus(){
                this.cnt-=1;
              }
          },
          watch:{
              cnt(val){
                if(val>10){
                  this.noEnough = true;
                }
                if(val<0){
                  this.cnt=0
                }
                if(val<10){
                  this.noEnough = false;
                }
                this.$store.dispatch('doAfn',val*10)
              }
          }
        }
    </script>
    <style scoped>
      .item input{
        width: 40px;
        display: inline-block;
      }
      .red{
        color:red;
        font-size: 12px;
      }
    </style>
    
    banana 组件
    <template>
      <div class="item">
        <span>香蕉</span>
        <button @click="add">add</button>
        <button @click="minus">minus</button>
        <input v-model.number.lazy="cnt">
        <span v-if="noEnough" class="red">库存不够</span>
      </div>
    </template>
    <script>
      module.exports = {
        data: function () {
          return {
            cnt:0,
            noEnough:false
          }
        },
        methods:{
          add(){
            this.cnt += 1;
          },
          minus(){
            this.cnt-=1;
          }
        },
        watch:{
          cnt(val){
            if(val>10){
              this.noEnough = true;
            }
            if(val<10){
              this.noEnough = false;
            }
            if(val<0){
              this.cnt=0
            }
            this.$store.dispatch('doBfn',val*5)
          }
        }
      }
    </script>
    <style scoped>
      .item input{
        width: 40px;
        display: inline-block;
      }
      .red{
        color:red;
        font-size: 12px;
      }
    </style>
    
    main.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 Vuex from 'vuex'
    import App from './App'
    import router from './router'
    
    
    Vue.config.productionTip = false
    
    Vue.use(Vuex);
    let store = new Vuex.Store({
      state:{
        total:0,
        appleTotal:0,
        bananaTotal:0,
      },
      getters:{
        getTotal(state){
          return state.total
        }
      },
      mutations:{
        aSetValue(state,value){
          state.appleTotal = value
          state.total = state.appleTotal + state.bananaTotal;
        },
        bSetValue(state,value){
          state.bananaTotal = value
          state.total = state.appleTotal + state.bananaTotal;
        }
      },
      actions:{
        doAfn(context,price){
          context.commit('aSetValue',price)
        },
        doBfn(context,price){
          context.commit('bSetValue',price)
        }
      }
    })
    
    
    
    /* eslint-disable no-new */
    new Vue({
      el: '#app',
      store,
      router,
      components: { App },
      template: '<App/>'
    })
    

    脚本宝典总结

    以上是脚本宝典为你收集整理的vue 项目开发要点总结全部内容,希望文章能够帮你解决vue 项目开发要点总结所遇到的问题。

    如果觉得脚本宝典网站内容还不错,欢迎将脚本宝典推荐好友。

    本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
    如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。