【在线OJ】01-Vue前端项目创建与页面开发

目录

一、项目展示

二、项目创建

三、Vue语法

安装

基础请求

token

携带参数

配置中携带参数

请求体携带参数(默认json)

请求体携带参数(不使用json)

multipart格式(上传头像可)

代码

if-else

代码

for

代码

创建组件

导入组件

使用组件

代码

子组件

父组件

四、Element-UI

静态页面

事件绑定

代码

五、Router

六、VueX

七、开发


一、项目展示

二、项目创建

创建文件夹使用VsCode打开后,新建终端输入以下命令

打开UI创建项目

npm install -g @vue/cli # 安装vue

vue -ui # 在浏览器创建项目

UI创建步骤

配置端口与代理

复制代码
const { defineConfig } = require('@vue/cli-service')
module.exports = defineConfig({
  transpileDependencies: true,
  devServer: {
    port: 9898,
    proxy: {
      '/api': {
        target: "http://localhost:9897",
        changeOrigin: true
      }
    }
  }
})

三、Vue语法

文本插值

复制代码
<template>
  <div id="app">
    {{problems[0].id + problems[1].id}} {{problems[0].title}} {{problems[0].level}}
    {{problems[0].level === "easy" ? "easy" : "other"}}
  </div>
</template>

<script>
  const options = {
    data: function () {
      return {
        problems: [
          {id: 1, title: "两数之和1", level: "easy"},
          {id: 2, title: "两数之和2", level: "easy"},
          {id: 3, title: "两数之和3", level: "easy"}
        ]
      };
    }
  };
  export default options;
</script>

<style>
#app {
  font-family: Avenir, Helvetica, Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-align: center;
  color: #2c3e50;
}

nav {
  padding: 30px;
}

nav a {
  font-weight: bold;
  color: #2c3e50;
}

nav a.router-link-exact-active {
  color: #42b983;
}
</style>

属性绑定

复制代码
<template>
  <div id="app">
    <input type="text" v-bind:value="name">
    <input type="text" :value="name">
  </div>
</template>

<script>
  const options = {
    data: function () {
      return {
        name: "王五"
      };
    }
  };
  export default options;
</script>

<style>
#app {
  font-family: Avenir, Helvetica, Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-align: center;
  color: #2c3e50;
}

nav {
  padding: 30px;
}

nav a {
  font-weight: bold;
  color: #2c3e50;
}

nav a.router-link-exact-active {
  color: #42b983;
}
</style>

事件绑定

复制代码
<template>
  <div id="app">
    <input type="button" v-bind:value="msg" v-on:click="login">
      <input type="button" v-bind:value="msg" @click="login">
      </div>
</template>

<script>
  const options = {
    data: function () {
      return {
        msg: "点我"
      };
    },
    methods: {
      login: function () {
        alert(options.data().msg)
      }
    }
  };
  export default options;
</script>

<style>
  #app {
    font-family: Avenir, Helvetica, Arial, sans-serif;
    -webkit-font-smoothing: antialiased;
    -moz-osx-font-smoothing: grayscale;
    text-align: center;
    color: #2c3e50;
  }

  nav {
    padding: 30px;
  }

  nav a {
    font-weight: bold;
    color: #2c3e50;
  }

  nav a.router-link-exact-active {
    color: #42b983;
  }
</style>

案例加法器实现

复制代码
<template>
  <div id="app">
    <input type="button" v-bind:value="addMessage" v-on:click="add">
      {{cnt}}
      <input type="button" v-bind:value="subMessage" @:click="sub">
      </div>
</template>

<script>
  const options = {
    data: function () {
      return {
        addMessage: "点我+1",
        subMessage: "点我-1",
        cnt: 1
      };
    },
    methods: {
      sub: function () {
        this.cnt = this.cnt - 1;
        alert(this.cnt);
      },

      add: function () {
        this.cnt = this.cnt + 1;
        alert(this.cnt);
      }
    }
  };
  export default options;
</script>

<style>
  #app {
    font-family: Avenir, Helvetica, Arial, sans-serif;
    -webkit-font-smoothing: antialiased;
    -moz-osx-font-smoothing: grayscale;
    text-align: center;
    color: #2c3e50;
  }

  nav {
    padding: 30px;
  }

  nav a {
    font-weight: bold;
    color: #2c3e50;
  }

  nav a.router-link-exact-active {
    color: #42b983;
  }
</style>

双向绑定

复制代码
<template>
  <div id="app">
    <input type="text" v-model="name">
      {{name}}
    </div>
</template>

<script>
  const options = {
    data: function () {
      return {
        name: "王五"
      };
    },
    methods: {
    }
  };
  export default options;
</script>

<style>
  #app {
    font-family: Avenir, Helvetica, Arial, sans-serif;
    -webkit-font-smoothing: antialiased;
    -moz-osx-font-smoothing: grayscale;
    text-align: center;
    color: #2c3e50;
  }

  nav {
    padding: 30px;
  }

  nav a {
    font-weight: bold;
    color: #2c3e50;
  }

  nav a.router-link-exact-active {
    color: #42b983;
  }
</style>

axios

安装

npm install axios -S

基础请求
token
携带参数
配置中携带参数
请求体携带参数(默认json)
请求体携带参数(不使用json)
multipart格式(上传头像可)
代码
复制代码
<template>
  <div id="app">
      <input type="button" value="简单get" @click="login">
    <input type="button" value="token" @click="token">
    <input type="button" value="查询字符串带参数" @click="params">
    <input type="button" value="配置携带参数" @click="configParams">
    <input type="button" value="请求体中的json格式" @click="bodyParams">
    <input type="button" value="请求体中的非json格式" @click="bodyParamsNoJson">
    <input type="button" value="使用multipart格式" @click="multipartParams">
    <input type="button" value="封装axios" @click="getAxios">
  </div>
</template>

<script>
import axios from "axios";
  const options = {
    data: function () {
      return {

      };
    },

    methods: {
      // 简单get
      login: async function () {
        const resp = await axios.get("http://localhost:8288/test/compile");
        alert(resp.data.data);
        localStorage.setItem("token", resp.data.data)
      },

      // 携带token
      token: async function () {
        const resp = await axios.post("http://localhost:8288/test/token", {}, {
          headers: {
            "token": localStorage.getItem("token")
          }
        })
        alert(resp.data.data);
      },

      // 携带参数在查询字符串中
      params: async function () {
        const name = encodeURIComponent("张三")
        const age = 12
        const resp = await axios.post(`http://localhost:8288/test/params?name=${name}&age=${age}`, {}, {})
        alert(resp.data.data);
      },

      // 携带参数在配置中
      configParams: async function () {
        const name = "张三"
        const age = 12
        const resp = await axios.post(`http://localhost:8288/test/params`, {}, {
          params:{
            name: name,
            age: age
          }
        })
        alert(resp.data.data);
      },

      // 请求体中传参,参数默认是json格式
      bodyParams: async function () {
        const name = "张三"
        const age = 12
        const resp = await axios.post(`http://localhost:8288/test/params`, {
          name: name,
          age: age
        }, {})
        alert(resp.data.data);
      },

      // 请求体中传参,不用json
      bodyParamsNoJson: async function () {
        const params = new URLSearchParams()
        params.append("name", "往往")
        params.append("age", 28)
        const resp = await axios.post(`http://localhost:8288/test/params`, params, {})
        alert(resp.data.data);
      },

      // 使用multipart格式---上传头像
      multipartParams: async function () {
        const params = new FormData()
        params.append("name", "lisi")
        params.append("age", 11)
        const resp = await axios.post(`http://localhost:8288/test/params`, params, {})
        alert(resp.data.data);
      },

      // 封装axios--不可用
      getAxios: async function () {
        const _axios = axios.create({
          baseURL: "http://localhost:8288",
          withCredentials: true,   // 允许携带token
        })
        const params = new URLSearchParams()
        params.append("name", "往往")
        params.append("age", 28)
        const resp = await _axios.post(`/test/paramsToken`, params, {
          headers: {
            "token":"111"
          }
        })
        alert(resp.data.data);
      },
    },

    computed: {

    }
  };
  export default options;
</script>

<style>
#app {
  font-family: Avenir, Helvetica, Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-align: center;
  color: #2c3e50;
}

nav {
  padding: 30px;
}

nav a {
  font-weight: bold;
  color: #2c3e50;
}

nav a.router-link-exact-active {
  color: #42b983;
}
</style>

响应数据

条件渲染

if-else
代码
复制代码
<template>
  <div id="app">
    <div v-if="problems.length > 0">显示数据</div>
    <div v-else>不显示</div>
  </div>
</template>

<script>
const options = {
  data: function () {
    return {
      problems: [
        {id: 1, title: "A+B1", level: "easy"},
        {id: 2, title: "A+B2", level: "easy"},
        {id: 3, title: "A+B3", level: "easy"},
        {id: 4, title: "A+B4", level: "easy"},
      ]
    };
  },

  methods: {

  },

  computed: {

  }
};
export default options;
</script>

<style>
#app {
  font-family: Avenir, Helvetica, Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-align: center;
  color: #2c3e50;
}

nav {
  padding: 30px;
}

nav a {
  font-weight: bold;
  color: #2c3e50;
}

nav a.router-link-exact-active {
  color: #42b983;
}
</style>

列表渲染

for
代码
复制代码
<template>
  <div id="app">
    <div v-if="problems.length > 0">
      <div class="row" v-for="problem of problems" :key="problem.id">
        <span>{{problem.id}} </span>
        <span>{{problem.title}} </span>
        <span>{{problem.level}} </span>
      </div>
    </div>
    <div v-else>不显示</div>
  </div>
</template>

<script>
const options = {
  data: function () {
    return {
      problems: [
        {id: 1, title: "A+B1", level: "easy"},
        {id: 2, title: "A+B2", level: "easy"},
        {id: 3, title: "A+B3", level: "easy"},
        {id: 4, title: "A+B4", level: "easy"},
      ]
    };
  },

  methods: {

  },

  computed: {

  }
};
export default options;
</script>

<style>
#app {
  font-family: Avenir, Helvetica, Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-align: center;
  color: #2c3e50;
}

nav {
  padding: 30px;
}

nav a {
  font-weight: bold;
  color: #2c3e50;
}

nav a.router-link-exact-active {
  color: #42b983;
}
</style>

页面加载就执行方法

组件复用

创建组件
导入组件
使用组件
代码
复制代码
<template>
  <div id="app">
    <my-button></my-button>
  </div>
</template>

<script>
  import MyButton from '@/components/ExamplyView.vue'
  const options = {
    data: function () {
      return {

      };
    },

    components: {
      MyButton,
    },

    mounted() {  // 组件加载就执行

    },

    methods: {

    },

    computed: {

    }
  };
  export default options;
</script>

<style>
  #app {
    font-family: Avenir, Helvetica, Arial, sans-serif;
    -webkit-font-smoothing: antialiased;
    -moz-osx-font-smoothing: grayscale;
    text-align: center;
    color: #2c3e50;
  }

  nav {
    padding: 30px;
  }

  nav a {
    font-weight: bold;
    color: #2c3e50;
  }

  nav a.router-link-exact-active {
    color: #42b983;
  }
</style>

组件插槽

自定义化组件

类似于参数传参

子组件
父组件

四、Element-UI

安装ElementUI

npm install element-ui -S

引入ElementUI

复制代码
import Vue from 'vue'
  import App from './App.vue'
  import router from './router'
  import store from './store'
  import Element from 'element-ui'
  import 'element-ui/lib/theme-chalk/index.css'

  Vue.use(Element)
  Vue.config.productionTip = false

  new Vue({
  router,
  store,
  render: h => h(App)
    }).$mount('#app')

表格

复制代码
<template>
  <div id="app">
    <el-table :data="problems">
      <el-table-column label="序号" prop="id"></el-table-column>
      <el-table-column label="题目" prop="title"></el-table-column>
      <el-table-column label="难点" prop="level"></el-table-column>
    </el-table>
  </div>
</template>

<script>
  import MyButton from '@/components/ExamplyView.vue'
  const options = {
    data: function () {
      return {
        problems: [
          {id: 1, title: "A+B1", level: "easy"},
          {id: 2, title: "A+B2", level: "easy"},
          {id: 3, title: "A+B3", level: "easy"},
          {id: 4, title: "A+B4", level: "easy"},
        ]
      };
    },

    components: {
      MyButton,
    },

    mounted() {  // 组件加载就执行

    },

    methods: {

    },

    computed: {

    }
  };
  export default options;
</script>

<style>
  #app {
    font-family: Avenir, Helvetica, Arial, sans-serif;
    -webkit-font-smoothing: antialiased;
    -moz-osx-font-smoothing: grayscale;
    text-align: center;
    color: #2c3e50;
  }

  nav {
    padding: 30px;
  }

  nav a {
    font-weight: bold;
    color: #2c3e50;
  }

  nav a.router-link-exact-active {
    color: #42b983;
  }
</style>

分页

静态页面
事件绑定
代码
复制代码
<template>
  <div id="app">
    <el-table :data="problems">
      <el-table-column label="序号" prop="id"></el-table-column>
      <el-table-column label="题目" prop="title"></el-table-column>
      <el-table-column label="难点" prop="level"></el-table-column>
    </el-table>
    <el-pagination
      :total="problems.length"
      :page-size="pageSize"
      :current-page="currentPage"
      layout="prev, pager, sizes, next, ->, total"
      :page-sizes="pageSizes"
      @current-change="currentChange"
      @size-change="sizeChange">
    </el-pagination>
  </div>
</template>

<script>
  import MyButton from '@/components/ExamplyView.vue'
  const options = {
    data: function () {
      return {
        problems: [
          {id: 1, title: "A+B1", level: "easy"},
          {id: 2, title: "A+B2", level: "easy"},
          {id: 3, title: "A+B3", level: "easy"},
          {id: 4, title: "A+B4", level: "easy"},
          {id: 5, title: "A+B4", level: "easy"},
          {id: 6, title: "A+B4", level: "easy"},
          {id: 7, title: "A+B4", level: "easy"},
        ],
        pageSize: 2,
        currentPage: 1,
        pageSizes: [2, 4]
      };
    },

    components: {
      MyButton,
    },

    mounted() {  // 组件加载就执行

    },

    methods: {
      currentChange: function (page) {
        // 页面改变 发起请求获取分页数据
        this.currentPage = page;
        alert(page + ":" + this.pageSize)
      },
      sizeChange: function(size) {
        // 页面展示数据条数改变 发起请求获取数据
        this.pageSize = size;
        alert(this.currentPage + ":" + size)
      }
    },

    computed: {

    }
  };
  export default options;
</script>

<style>
  #app {
    font-family: Avenir, Helvetica, Arial, sans-serif;
    -webkit-font-smoothing: antialiased;
    -moz-osx-font-smoothing: grayscale;
    text-align: center;
    color: #2c3e50;
  }

  nav {
    padding: 30px;
  }

  nav a {
    font-weight: bold;
    color: #2c3e50;
  }

  nav a.router-link-exact-active {
    color: #42b983;
  }
</style>

表格+分页+搜索小demo

复制代码
<template>
  <div id="app">
    <el-input size="mini" placeholder="请输入题目" style="width: 300px;" v-model="queryVo.title" clearable></el-input>
    <el-select placeholder="选择题号" size="mini" style="margin-left: 20px" v-model="queryVo.ids" clearable>
      <div v-for="problem in problems" :key="problem.id">
        <el-option :value="problem.id"></el-option>
      </div>
    </el-select>
    <el-button size="mini" type="primary" style="margin-left: 20px" @click="query">提交</el-button>
    <el-divider></el-divider>
    <el-table :data="problems">
      <el-table-column label="序号" prop="id"></el-table-column>
      <el-table-column label="题目" prop="title"></el-table-column>
      <el-table-column label="难点" prop="level"></el-table-column>
    </el-table>
    <el-pagination
      :total="problems.length"
      :page-size="pageSize"
      :current-page="currentPage"
      layout="prev, pager, sizes, next, ->, total"
      :page-sizes="pageSizes"
      @current-change="currentChange"
      @size-change="sizeChange">
    </el-pagination>
  </div>
</template>

<script>
  import MyButton from '@/components/ExamplyView.vue'
  const options = {
    data: function () {
      return {
        queryVo: {
          title: "",
          ids: []
        },
        problems: [
          {id: 1, title: "A+B1", level: "easy"},
          {id: 2, title: "A+B2", level: "easy"},
          {id: 3, title: "A+B3", level: "easy"},
          {id: 4, title: "A+B4", level: "easy"},
          {id: 5, title: "A+B4", level: "easy"},
          {id: 6, title: "A+B4", level: "easy"},
          {id: 7, title: "A+B4", level: "easy"},
        ],
        pageSize: 2,
        currentPage: 1,
        pageSizes: [2, 4]
      };
    },

    components: {
      MyButton,
    },

    mounted() {  // 组件加载就执行

    },

    methods: {
      currentChange: function (page) {
        // 页面改变 发起请求获取分页数据
        this.currentPage = page;
        alert(page + ":" + this.pageSize)
      },
      sizeChange: function(size) {
        // 页面展示数据条数改变 发起请求获取数据
        this.pageSize = size;
        alert(this.currentPage + ":" + size)
      },
      query: function () {
        // 根据条件进行查询
        alert(this.queryVo.title + ":" + this.queryVo.ids)
      }
    },

    computed: {

    }
  };
  export default options;
</script>

<style>
  .input1 {
    width: 50px;
  }

  #app {
    font-family: Avenir, Helvetica, Arial, sans-serif;
    -webkit-font-smoothing: antialiased;
    -moz-osx-font-smoothing: grayscale;
    text-align: center;
    color: #2c3e50;
  }

  nav {
    padding: 30px;
  }

  nav a {
    font-weight: bold;
    color: #2c3e50;
  }

  nav a.router-link-exact-active {
    color: #42b983;
  }
</style>

级联选择器

五、Router

路由配置

路由跳转

复制代码
<router-link to="target"></router-link> // 页面
this.$router.push(url)  // js

导航栏案例

六、VueX

vuex

没用到

七、开发

相关推荐
慧一居士19 分钟前
flex 布局完整功能介绍和示例演示
前端
DoraBigHead21 分钟前
小哆啦解题记——两数失踪事件
前端·算法·面试
一斤代码6 小时前
vue3 下载图片(标签内容可转图)
前端·javascript·vue
中微子6 小时前
React Router 源码深度剖析解决面试中的深层次问题
前端·react.js
光影少年6 小时前
从前端转go开发的学习路线
前端·学习·golang
中微子6 小时前
React Router 面试指南:从基础到实战
前端·react.js·前端框架
3Katrina6 小时前
深入理解 useLayoutEffect:解决 UI "闪烁"问题的利器
前端·javascript·面试
前端_学习之路7 小时前
React--Fiber 架构
前端·react.js·架构
coderlin_7 小时前
BI布局拖拽 (1) 深入react-gird-layout源码
android·javascript·react.js
伍哥的传说8 小时前
React 实现五子棋人机对战小游戏
前端·javascript·react.js·前端框架·node.js·ecmascript·js