zoukankan      html  css  js  c++  java
  • vue学习

    vue 官网 https://cn.vuejs.org/


    Vue项目开发


    环境搭建

    npm install -g cnpm --registry=https://registry.npm.taobao.org
    cnpm install -g @vue/cli@4.1.1
    

    创建项目

    C:Users13922>F:
    F:>cd VUE学习
    F:VUE学习>vue ui
    F:VUE学习>vue create vue_proj 
    

    cd vue_proj
    npm serve
    

    项目目录

    """
    node_modules:项目依赖
    
    public:公用文件
    	favicon.ico:页面标签图标
    	index.html:项目的唯一页面(单页面)
    	
    src:项目开发文件目录
    	assets:静态资源
    		css|js|img
    	components:小组件
    		*.vue
    	views:视图组件
    		*.vue
    	App.vue:根组件
    	main.js:主脚本文件
    	router.js:路由脚本文件 - vue-router
    	store.js:仓库脚本文件 - vuex
    	
    *.xml|json|js:一系列配置文件
    README.md:使用说明
    """
    

    <link rel="icon" href="<%= BASE_URL %>favicon.ico">

    <%= BASE_URL %> 表示项目根路径


    <div id="app"></div> 挂载点, 挂载vue的页面, 如果没有这个标签, vue页面什么都没有


    根组件 App.vue 文件

    <router-view/>


    image-20201127092737433


    主脚本文件

    原内容

    import { createApp } from 'vue'   
    import App from './App.vue'
    import router from './router'
    import store from './store'
    
    createApp(App).use(store).use(router).mount('#app')
    

    说明

    import Vue from 'vue'  // node_modules下的依赖直接写名字
    import App from './App.vue'  // ./代表相对路径的当前目录,文件后缀军可以省略
    import router from '@/router.js'  // @ 代表src的绝对路径
    import store from './store'
    // 在main中配置的信息就是给整个项目配置
    // 已配置 vue | 根组件App | 路由 | 仓库
    // 以后还可以配置 cookie | ajax(axios) | element-ui
    
    createApp(App).config.productionTip = false;;  // Tip小提示
    
    
    new Vue({
        el: '#app',
        router: router,
        store,
        // render: function (fn) {
        //     return fn(App)
        // }
        // 解释:function (h) {return 1} | (h) => {return 1} | h => 1
        render: readTemplateFn => readTemplateFn(App)
    });
    

    如果 import App from './App.vue' 改成 import App from './App.vuexxxxxxxxxxxxx'

    如果vue还没启动, 将无法启动, 报如下的错

     ERROR  Failed to compile with 1 errors                                                                                                                                 下午1:19:20
    
    This relative module was not found:
    
    * ./App.vuexxxxxxxxxxx in ./src/main.js
    

    如果启动了, 页面上将会报错, 因为vue是单页面实时刷新的


    自定义组件1


    第一步:在 components 下面新建vue文件

    <!--html代码:有且只有一个根标签--> 
    <template>
        <div>
            <h1 :class="{active: is_active}" @click="btnClick">我的组件</h1>
        </div>
    </template>
    
    <!--js代码:在export default {} 的括号内完成组件的各项成员:data|methods|... -->
    <script>
        export default {
            data () {
                return {
                    is_active: false
                }
            },
            methods: {
                btnClick() {
                    this.is_active = !this.is_active;
                }
            }
        }
    </script>
    
    <!--css代码:scoped样式组件化 - 样式只在该组件内部起作用 -->
    <style scoped>
    .active {
        color: red;
    }
    </style>
    

    第二步:在about.vue中引入该组件

    <template>
        <div class="about">
            <h1>This is an about page</h1>
            <h2>好</h2>
            <mycompon></mycompon>
        </div>
    </template>
    <script>
    import mycompon from '@/components/mycomponent'
        export default {
        components: {
            mycompon,
        }
        }
    </script>
    
    

    自定义组件2


    第一步:在 components 下面新建vue文件header.vue

    <template>
        <div class="header">
            <div class="header-slogan">xxxxxx集团 | 帮助有志向的年轻人通过努力学习获得体面的工作和生活!</div>
            <div class="header-nav">
                <h1 class="header-logo"><router-link to="/"><img src="@/assets/img/header-logo.svg" alt=""></router-link></h1>
                <ul class="header-menu">
                    <li>
                        <router-link to="/">主页</router-link>
                    </li>
                    <li>
                        <router-link to="/user">用户</router-link>
                    </li>
                </ul>
                <div class="header-owner">
                    <div v-if="is_logout">
                        <span>登陆</span> | <span>注册</span>
                    </div>
                    <div v-else>
                        <span>Owen</span> | <span>个人中心</span>
                    </div>
                </div>
            </div>
        </div>
    </template>
    
    <script>
        export default {
            name: "Header",
            data() {
                return {
                    is_logout: true,
                    page: 'normal'
                }
            },
            methods: {
                togglePage(page) {
                    this.page = page;
                }
            }
    
        }
    </script>
    
    <style scoped>
      .header {
             100%;
            background-color: #ccc;
            position: fixed;
        }
    
        .header-slogan {
             1200px;
            font: normal 14px/36px '微软雅黑';
            color: #333;
            margin: 0 auto;
        }
    
        .header-nav {
             1200px;
            margin: 0 auto;
            /*background-color: orange;*/
        }
    
        .header-nav:after {
            content: "";
            display: block;
            clear: both;
        }
    
        .header-logo, .header-menu {
            float: left;
        }
    
        .header-owner {
            float: right;
        }
    
        .header-logo {
            
             118px;
            height: 60px;
            padding-top: 20px;
            /*background: url("/src/assets/img/header-logo.svg") no-repeat;*/
            /* background: url("../assets/img/header-logo.svg") no-repeat 0; */
        }
    
        .header-menu {
            margin-left: 40px;
        }
    
        .header-menu li {
            float: left;
            margin-top: 26px;
            cursor: pointer;
            margin-right: 20px;
        }
    
        .header-menu li:hover {
            color: #444;
            padding-bottom: 5px;
            border-bottom: 2px solid #444;
        }
    
        .header-owner {
            padding-top: 26px;
        }
    
        .active {
            color: #444;
            padding-bottom: 5px;
        }
    </style>
    
    

    第二步:在home.vue中引入该组件

    <template>
        <div class="home">
            <Header></Header>
            <div class="wrapper">
                <h1>我是主页</h1>
            </div>
        </div>
    </template>
    
    <script>
        // @ is an alias to /src
        import Header from '@/components/Header.vue'
    
        export default {
            name: 'header2',
            components: {
                Header,
            }
        }
    </script>
    
    <style scoped>
        .wrapper {
            padding-top: 116px
        }
    </style>
    
    

    第三步: 创建User.vue并引入header.vue

    • 创建User.vue 模板文件
    <template>
      <div class="User">
        <Header></Header>
        <div class="wrapper">
          <h1>User页面</h1>
        </div>
        </div>
    </template>
    
    <script>
      // @ is an alias to /src
      import Header from '@/components/Header.vue'
    
      export default {
        components: {
          Header,
        }
      }
    </script>
    
    <style scoped>
      .wrapper {
        padding-top: 116px
      }
    </style>
    
    

    • /src/router/index.js 中添加路由
    import User from '../views/User.vue'
    
    const routes = [
        {
            path: '/',
            name: 'Home',
            component: Home
        },
        {
            path: '/user',
            name: 'User',
            component: User
        },
    ]
    
    

    第四步: 在App.vue中渲染组件

    <template>
      <div id="app">
        <router-view></router-view>
        </div>
    </template>
    
    <style>
    
    </style>
    
    


    第五步: 格式化样式, 并在main.js中引入

    • 创建 /src/assets/css/reset.css
    body, h1, h2, h3, h4, h5, h6, p, ul {
        margin: 0;
        padding: 0;
    }
    ul {
        list-style: none;
    }
    
    a {
        text-decoration: none;
        color: black;
    }
    
    

    • 在main.js中引入该文件
    // 配置reset.css
    import '@/assets/css/reset.css'
    
    

    相关报错


    1. 定义了组件没有应用组件


    2. 组件调用时候用了和定义组件时候一样的名字


    3. 组件调用时候用了和定义组件时候一样的名字, 但是大小写不同

    vue.runtime.esm.js?2b0e:619 [Vue warn]: Do not use built-in or reserved HTML elements as component id: header·


    路由:vue-router

    1)name使用

    用{}前面需要用:绑定, {}内写变量,

    路由配置

    import Main from './views/Main'
    routes: [
        {
            path: '/main',
            name: 'main',
            component: Main
        }
    ]
    
    

    视图使用

    <router-link :to="{name: 'main'}">主页</router-link>
    
    

    2)router-link与系统a标签的区别

    router-link:会被vue渲染成a标签,但是点击这样的a标签不能发生页面的转跳,只会出现组件的替换
    a:也可以完成同样的效果,但是会发生页面的转跳
    
    

    3)路由重定向

    routes: [
    	{
            path: '/',
            name: 'home',
            component: Home
        },
        {
            path: '/home',
            redirect: '/', // 重定向
        }
    ]
    
    

    4)路由传参-1

    路由:router/index.js

    import Course from '../views/Course.vue'
    import CourseDetail from '../views/CourseDetail.vue' 
    
    {
      path: '/course',
      name: 'Course',
      component: Course
      },
      {
      path: '/course/detail/:id',
      name: 'CourseDetail',
      component: CourseDetail
      },
    
    

    转跳页面:Course.vue

    <template>
        <div class="course">
            <h1>名著</h1>
            <hr>
            <ul>
                <li v-for="course in courses" :key="course.title">
                     <router-link :to="'/course/detail/' + course.id">{{ course.title }}</router-link>
                </li>
            </ul>
        </div>
    </template>
    
    <script>
        let course_list = [
            { id: 1, title: "西游记" },
            { id: 2, title: "三国演义" },
            { id: 3, "title": "水浒传" },
            { id: 4, "title": "红楼梦" },
        ];
        export default {
            name: "Course",
    
            data() {
                return {
                    courses: []
                }
            },
            created() {
                this.courses = course_list
            }
    
        }
    </script>
    
    <style scoped>
        li a {
            display: block;
        }
    
        li,
        li a {
            border: 1px solid pink;
            background-color: rgba(123, 21, 56, 0.3);
            margin-top: 10px;
            line-height: 80px;
            cursor: pointer;
        }
    </style>
    
    

    渲染页面:CourseDetail.vue

    <template>
        <div class="course-detail">
            <h1>四大名著详情</h1>
            <hr>
            <h2>{{ ctx }}</h2>
        </div>
    </template>
    
    <script>
        let course_detail_list = ["数据有误", "西游记", "三国演义", "水浒传", "红楼梦"]
    
        export default {
            name: "CourseDetail",
            data() {
                return {
                    ctx: ''
                }
            },
            created() {
                console.log('详情页面被渲染了')
                let index = this.$route.params.id
    
                if (index <= 0 || index > course_detail_list.length) index=0 
                this.ctx = course_detail_list[index]  
                
            },
    
        }
    </script>
    
    <style scoped>
    
    </style>
    
    

    4)路由传参-2
    路由:router/index.js
    {
        path: '/course/detail',
        name: 'course-detail',
        component: CourseDetail
    }
    
    
    转跳页面:Course.vue
    <router-link :to="'/course/detail?id=' + course.id">{{ course.title }}</router-link>
    
    
    渲染页面:CourseDetail.vue
    created () {
        let index = this.$route.query.id;
        if (index < 0 || index >= course_detail_list.length) index = 0;
        this.ctx = course_detail_list[index]
    }
    
    
    5)路由传参-3
    路由:router/index.js
    {
        path: '/course/detail',
        name: 'course-detail',
        component: CourseDetail
    }
    
    
    转跳页面:Course.vue
    <template>
        <div class="course">
            <h1>课程</h1>
            <hr>
    
            <ul>
                <li v-for="course in courses" :key="course.title" @click="toDetail(course.id)">
                    <!--<router-link :to="{name: 'course-detail'}">{{ course.title }}</router-link>-->
                    <!--<router-link :to="'/course/detail?id=' + course.id">{{ course.title }}</router-link>-->
                    {{ course.title }}
                </li>
            </ul>
    
        </div>
    </template>
    
    <script>
        let course_list = [
            {
                id: 1,
                title: '水浒传'
            },
            {
                id: 2,
                title: '西游记'
            },
        ];
        export default {
            name: "Course",
            data () {
                return {
                    courses: []
                }
            },
            // 组件创建成功去获取数据
            created () {
                this.courses = course_list
            },
            methods: {
                toDetail (id) {
                    // this.$router.push({path: 'course/detail?id=' + id});
                    this.$router.push({
                        name: 'course-detail',
                        // params: {
                        //     id: id
                        // },
                        query: {
                            id: id
                        }
                    });
    
                    // this.$router.go(-1)
    
                }
            }
    
        }
    </script>
    
    <style scoped>
        li a {
            display: block;
        }
        li, li a {
            border: 1px solid pink;
            background-color: rgba(123, 21, 56, 0.3);
            margin-top: 10px;
            line-height: 80px;
            cursor: pointer;
        }
    </style>
    
    
    渲染页面:CourseDetail.vue
    created () {
        let 参数的数据 = this.$route.query.参数的key 或者 this.$route.params.参数的key
    }
    
    

    6)go
    this.$router.go(-1)  //返回历史记录的前一页
    
    

    仓库:vuex

    1. 仓库配置:store.js

    import Vue from 'vue'
    import Vuex from 'vuex'
    
    Vue.use(Vuex);
    
    export default new Vuex.Store({
    // 全局可以访问的变量 - 获取值
        // 组件内:this.$store.state.title
      state: {
        title: '主页'
      },
       // 全局可以访问的方法 - 修改值
        // 组件内:this.$store.commit('UpdateTitle', '新值')
      mutations: {
        UpdateTitle (state, newvalue) {
          state.title = newvalue
        }
      },
      actions: {
      },
    })
    
    

    2. 组件调用 homesubsub.vue

    <template>
    <div class="homesubsub">
      <input type="text" v-model="val">
      <button @click="btnClick">修改</button>
    </div>
    </template>
    
    <script>
    export default {
    name: "HomeSubSub",
      data () {
      return {
        val: ""
      }
      },
      methods: {
      btnClick() {
       this.$store.commit('UpdateTitle', this.val)
        console.log(this.$store.state.title)
      }
      }
    }
    </script>
    
    <style scoped>
    
    </style>
    
    

    3. 属性计算 homesub.vue ( computed)

    computed: 调用仓库中的变量,使得页面展示的数据实时更新

    <template>
      <div class="homesub">
        <h1>{{ title }}</h1>
        <hr>
        <HomeSubSub></HomeSubSub>
      </div>
    </template>
    
    <script>
    import HomeSubSub from "@/components/HomeSubSub";
    export default {
      name: "HomeSub",
      components: {
        HomeSubSub
      },
      computed: {
        title () {
          return this.$store.state.title
        }
      }
    }
    </script>
    
    <style scoped>
    
    </style>
    
    

    4. 主页面展示

    <template>
      <div class="home">
       <Header></Header>
       <div class="wrapper">
         <HomeSub></HomeSub>
       </div>
      </div>
    </template>
    
    <script>
    // @ is an alias to /src
    import Header from '@/components/Header'
    import HomeSub from '@/components/HomeSub'
    
    export default {
      components: {
        Header,
        HomeSub
      },
      created () {
        console.log(this.$axios)
      }
    
    }
    </script>
    
    <style>
    .wrapper {
      padding-top:116px;
    }
    </style>
    
    

    前后台交互:axios

    1.安装

    >: cd 项目目录
    >: cnpm install axios --save
    
    

    2.配置:main.js

    import Axios from 'axios'
    Vue.prototype.$axios = Axios;
    
    

    3.跨域问题(同源策略):Access-Control-Allow-Origin => CORS

    前提:前台向后跳请求数据
    1)服务器不一致 - ip
    2)应用不一致 - 端口
    3)协议不一致 - http <-> https
    
    

    1. django解决跨域

    • 安装django-cors-headers模块
    pip install django-cors-headers
    
    

    • 在settings.py中配置

      注册app

    INSTALLED_APPS = [
    	...
    	'corsheaders'
    ]
    
    

    • 添加中间件
    MIDDLEWARE = [
    	...
    	'corsheaders.middleware.CorsMiddleware'
    ]
    
    

    • 允许跨域源
    CORS_ORIGIN_ALLOW_ALL = True
    
    

    4. axios请求方式

    get

    // this.$axios({
        //   url: 'http://127.0.0.1:8000/data/',
        //   method: 'get',
        // }).then( (response) => {
        //   console.log(response)
        // })
    
        this.$axios.get('http://127.0.0.1:8000/data/', {params: {usr: 'zero', pwd: '000'}}).then(response => {
          console.log(response)
        });
    
    

    post (不使用DRF只能从request.body中取得post请求的响应值)

    this.$axios.post('http://127.0.0.1:8000/data/', {username: 'zero', password: '0000', headers: {'Content-Type': 'urlencoded'}}).then(response => {
          console.log(response)
        })
    
    

    安装

    >: cd 项目目录
    >: cnpm install vue-cookie --save
    
    

    配置:main.js

    import cookie from 'vue-cookie'
    Vue.prototype.$cookie = cookie;
    
    

    使用:在任何方法中

    export default {
      name: 'Home',
      components: {
        HelloWorld
      },
      created() {
        this.$axios.post('http://127.0.0.1:8000/data/', {username: 'zero', password: '0000', headers: {'Content-Type': 'urlencoded'}}).then(response => {
          console.log(response)
          // let token = response.data.token
    
          // 设置cookie
          // this.$cookie.set('token', token,  1)
    
          //取出cookie
          console.log(this.$cookie.get('token'))
    
          //删除cookie
          this.$cookie.delete('token')
        })
      }
    }
    
    

    element UI 使用

    https://element.eleme.cn/#/zh-CN

    1. 安装

    首先切换到项目目录下

    cnpm i element-ui -S
    
    

    2. 配置main.js

    import ElementUI from 'element-ui'
    import 'element-ui/lib/theme-chalk/index.css';
    
    
    Vue.use(ElementUI)  //全局用
    
    

    3. 使用element

    3.1.按钮

    <template>
      <div class="about">
        <h1>This is an about page</h1>
        <el-row>
          <el-button>默认按钮</el-button>
          <el-button type="primary">主要按钮</el-button>
          <el-button type="success">成功按钮</el-button>
          <el-button type="info">信息按钮</el-button>
          <el-button type="warning">警告按钮</el-button>
          <el-button type="danger">危险按钮</el-button>
        </el-row>
      </div>
    </template>
    
    


    3.2. 布局 (element布局为24等分)

      <el-row>
          <el-col :span="6">1</el-col>
          <el-col :span="12">2</el-col>
          <el-col :span="6">3</el-col>
        </el-row>
    
    


    3.3.消息提示

    <template>
      <div class="about">
        <h1>This is an about page</h1>
        <el-row>
          <el-button :plain="true" @click="open2">成功</el-button>
          <el-button :plain="true" @click="open3">警告</el-button>
          <el-button :plain="true" @click="open1">消息</el-button>
          <el-button :plain="true" @click="open4">错误</el-button>
        </el-row>
      </div>
    </template>
    
    <script>
    export default {
      methods: {
        open1() {
          this.$message('这是一条消息提示');
        },
        open2() {
          this.$message({
            message: '恭喜你,这是一条成功消息',
            type: 'success'
          });
        },
    
        open3() {
          this.$message({
            message: '警告哦,这是一条警告消息',
            type: 'warning'
          });
        },
    
        open4() {
          this.$message.error('错了哦,这是一条错误消息');
        }
      }
    }
    </script>
    
    

  • 相关阅读:
    写了一个好玩的小软件, 监视鼠标以及键盘的动作, 全局钩子. HowTired
    2005的五一计划
    给你的爱一直很安静
    沉重悼念蓝色理想经典论坛原Flash版主[手工感情][Handmade]
    一不小心就成就了一段姻缘,哈哈
    基于dotnet的代码统计工具新版发布
    四天三夜 刻骨铭心 颠峰战将 永不言败
    怎么回事?现在博客园极不稳定
    屋漏偏逢连夜雨, 船迟又遇打头风
    适用于IE浏览器及非IE浏览器的xmlhttp脚本
  • 原文地址:https://www.cnblogs.com/cjwnb/p/14046253.html
Copyright © 2011-2022 走看看