Javaweb基础-前端工程化学习笔记

前端工程化:

一.ES6

变量与模版字符串

let 和var的差别:

<script>//1. let只有在当前代码块有效代码块. 代码块、函数、全局{let a = 1var b = 2}   console.log(a);  // a is not defined   花括号外面无法访问console.log(b);  // 可以正常输出//2. 不能重复声明let name = '天真'let name = '无邪'//3. 不存在变量提升(先声明,在使用)console.log(test) //可以     但是值为undefinedvar test = 'test'console.log(test1) //不可以  let命令改变了语法行为,它所声明的变量一定要在声明后使用,否则报错。let test1 = 'test1' //4、不会成为window的属性   var a = 100console.log(window.a) //100let b = 200console.log(window.b) //undefined</script>
  • const和var的差异

    1、新增const和let类似,只是const定义的变量不能修改

    2、并不是变量的值不得改动,而是变量指向的那个内存地址所保存的数据不得改动。

模板字符串(template string)是增强版的字符串,用反引号(`)标识

1、字符串中可以出现换行符

2、可以使用 ${xxx} 形式输出变量和拼接变量

解构表达式:解构赋值的语法使用花括号 {} 表示对象,方括号 [] 表示数组

let [a, b, c] = [1, 2, 3]; //新增变量名任意合法即可,本质是按照顺序进行初始化变量的值let {a, b} = {a: 1, b: 2};
//新增变量名必须和属性名相同,本质是初始化变量的值为对象中同名属性的值
//等价于 let a = 对象.a  let b = 对象.b
//使用 : 操作符指定新的变量名
let {a: x, b: y} = {a: 1, b: 2};//函数参数解构赋值
function add([x, y]) {return x + y;
}
add([1, 2]); // 3

箭头函数(类似Java中的Lambda表达式 )

    //ES6 允许使用“箭头”(=>)定义函数。//1. 函数声明let fn1 = function(){}let fn2 = ()=>{} //箭头函数,此处不需要书写function关键字let fn3 = x =>{} //单参数可以省略(),多参数无参数不可以!let fn4 = x => console.log(x) //只有一行方法体可以省略{};let fun5 = x => x + 1 //当函数体只有一句返回值时,可以省略花括号和 return 语句//2. 使用特点 箭头函数this关键字// 在 JavaScript 中,this 关键字通常用来引用函数所在的对象,// 或者在函数本身作为构造函数时,来引用新对象的实例。// 但是在箭头函数中,this 的含义与常规函数定义中的含义不同,// 并且是由箭头函数定义时的上下文来决定的,而不是由函数调用时的上下文来决定的。// 箭头函数没有自己的this,this指向的是外层上下文环境的thislet person ={name:"张三",showName:function (){console.log(this) //  这里的this是person},viewName: () =>{console.log(this) //  这里的this是window}}

rest参数,在形参上使用 和JAVA中的可变参数几乎一样 :let fun = function (...args){...}}

spread参数,在实参上使用rest:fun1(...arr)

应用:

//应用场景1 合并数组let arr=[1,2,3]let arr2=[4,5,6]let arr3=[...arr,...arr2]//应用场景2 合并对象属性let p1={name:"张三"}let p2={age:10}let p3={gender:"boy"}let person ={...p1,...p2,...p3}

对象的创建与拷贝(支持了class extends constructor等关键字 )

浅拷贝:let person2 = person;--指向统一内存

深拷贝:let person2 = JSON.parse(JSON.stringify(person));--通过JSON和字符串的转换形成一个新的对象

模块化处理:分别导出,统一导出,默认导出

分别导出-模块想对外导出,添加export关键字即可(导入-import * as m1 from './module.js';*代表module.js中的所有成员,m1代表所有成员所属的对象)

 导入JS文件 添加type='module' 属性,否则不支持ES6的模块化
<script src="./app.js" type="module" /> 

统一导出

// 统一对外导出(暴露)
export {PI,sum,Person
}

导入:

/* {}中导入要使用的来自于module.js中的成员{}中导入的名称要和module.js中导出的一致,也可以在此处起别名{}中如果定义了别名,那么在当前模块中就只能使用别名{}中导入成员的顺序可以不是暴露的顺序一个模块中可以同时有多个import多个import可以导入多个不同的模块,也可以是同一个模块
*/import {PI ,Person ,sum,PI as pi,Person as People,sum as add}  from './module.js'

默认导出:export default sum

导入:import {default as add} from './module.js'

npm常用命令:

1.项目初始化

  • npm init

    • 生成一个package.json 文件

  • npm init -y

    • 所有信息使用当前文件夹的默认值!

2.安装依赖 npm | Home

  • npm install 包名 或者 npm install 包名@版本号

    • 安装包或者指定版本的依赖包(安装到当前项目中)

  • npm install -g 包名

    • 安装全局依赖包

  • npm install

    • 安装package.json中的所有记录的依赖

3.升级依赖

  • npm update 包名

    • 将依赖升级到最新版

4.卸载依赖

  • npm uninstall 包名

5.查看依赖

  • npm ls

    • 查看项目依赖

  • npm list -g

    • 查看全局依赖

6.运行命令

  • npm run 命令是在执行 npm 脚本时使用的命令。npm 脚本是一组在 package.json 文件中定义的可执行命令。npm 脚本可用于启动应用程序,运行测试,生成文档等,还可以自定义命令以及配置需要运行的脚本。

  • 在 package.json 文件中,scripts 字段是一个对象,其中包含一组键值对,键是要运行的脚本的名称,值是要执行的命令。

    "scripts": {"start": "node index.js","test": "jest","build": "webpack"},
  • scripts 对象包含 start、test 和 build 三个脚本。当您运行 npm run start 时,将运行 node index.js,并启动应用程序。同样,运行 npm run test 时,将运行 Jest 测试套件,而 npm run build 将运行 webpack 命令以生成最终的构v建输出。

二.VUE3:

  • 声明式渲染:Vue 基于标准 HTML 拓展了一套模板语法,使得我们可以声明式地描述最终输出的 HTML 和 JavaScript 状态之间的关系。

  • 响应性:Vue 会自动跟踪 JavaScript 状态并在其发生变化时响应式地更新 DOM

Vite创建Vue3工程化项目(vscode)

  1. 创建工程:npm create vite@latest; 选择vue+JavaScript选项
  2. 安装依赖:npm i(安装package.json 中的依赖)
  3. 启动项目-研发模式:npm run dev
  4. 停止项目:ctrl+c

Vite+Vue3项目的目录结构:

Vite 项目的入口为 src/main.js 文件,这是 Vue.js 应用程序的启动文件,也是整个前端应用程序的入口文件。在该文件中,通常会引入 Vue.js 及其相关插件和组件,同时会创建 Vue 实例,挂载到 HTML 页面上指定的 DOM 元素中。

SFC:.vue文件对js/css/html统一封装, 该文件由三个部分组成 <script> <template> <style>

  • template标签 代表组件的html部分代码 代替传统的.html文件

  • script标签 代表组件的js代码 代替传统的.js文件

  • style标签 代表组件的css样式代码 代替传统的.css文件(存储的是css代码! <style scoped> 是 Vue.js 单文件组件中用于设置组件样式的一种方式,它的含义是将样式局限在当前组件中,不对全局样式造成影响。)

工程组织:

  • index.html是项目的入口,其中 <div id ='app'></div>是用于挂载所有组建的元素

  • index.html中的script标签引入了一个main.js文件,具体的挂载过程在main.js中执行

  • main.js是vue工程中非常重要的文件,他决定这项目使用哪些依赖,导入的第一个组件

  • App.vue是vue中的核心组件,所有的其他组件都要通过该组件进行导入,该组件通过路由可以控制页面的切换

Vite+Vue3响应式和setup函数:

响应数据:

<script type="module">//存储vue页面逻辑js代码import {ref} from 'vue'export default{setup(){//非响应式数据: 修改后VUE不会更新DOM//响应式数据:   修改后VUE会更新DOM//VUE2中数据默认是响应式的//VUE3中数据要经过ref或者reactive处理后才是响应式的//ref是VUE3框架提供的一个函数,需要导入//let counter = 1//ref处理的响应式数据在js编码修改的时候需要通过.value操作//ref响应式数据在绑定到html上时不需要.valuelet counter = ref(1)function increase(){// 通过.value修改响应式数据counter.value++}function decrease(){counter.value--}return {counter,increase,decrease}}}
</script>
<template><div><button @click="decrease()">-</button>{{ counter }}<button @click="increase()">+</button></div></template>

通过setup函数来省略语句:

<script type="module" setup>/* <script type="module" setup> 通过setup关键字
可以省略 export default {setup(){   return{}}}这些冗余的语法结构 */import {ref} from 'vue'// 定义响应式数据let counter = ref(1)// 定义函数function increase(){counter.value++}function decrease(){counter.value--}</script>

样式导入方式: 

  1. 全局引入main.js

    import './style/reset.css' 
  2. vue文件script代码引入

    import './style/reset.css'
  3. Vue文件style代码引入

    @import './style/reset.css'

Vue3视图渲染技术:

插值表达式:双大括号{{}}和文本表达式:v-xxxx

  • 插值表达式是将数据渲染到元素的指定位置的手段之一

  • 插值表达式不绝对依赖标签,其位置相对自由

  • 插值表达式中支持javascript的运算表达式

  • 插值表达式中也支持函数的调用

  • v-*** 这种写法的方式使用的是vue的命令

  • v-***的命令必须依赖元素,并且要写在元素的开始标签中

  • v-***指令支持ES6中的字符串模板:``

  • 插值表达式中支持javascript的运算表达式

  • 插值表达式中也支持函数的调用

  • v-text可以将数据渲染成双标签中间的文本,但是不识别html元素结构的文本

  • v-html可以将数据渲染成双标签中间的文本,识别html元素结构的文本

属性渲染:渲染元素的属性使用v-bind;语法为 v-bind:属性名='数据名'

事件绑定:v-on 来监听 DOM 事件,并在事件触发时执行对应的 Vue的JavaScript代码

  • 用法:v-on:click="handler" 或简写为 @click="handler"

  • vue中的事件名=原生事件名去掉on 前缀 如:onClick --> click

  • handler的值可以是方法事件处理器,也可以是内联事件处理器(直接对数据进行修改)

  •     <!-- 方法事件处理器 --><button v-on:click="addCount()">addCount</button> <br><!-- 内联事件处理器 --><button @click="count++">incrCount</button> <br>
  • 绑定事件时,可以通过一些绑定的修饰符,常见的事件修饰符如下

    • .once:只触发一次事件。[重点]

    • .prevent:阻止默认事件。[重点]

响应式数据:

ref 可以将一个基本类型的数据(如字符串,数字等)转换为一个响应式对象。 ref 只能包裹单一元素; reactive() 函数创建一个响应式对象或数组(toRef基于reactive响应式对象上的一个属性,创建一个对应的 ref响应式数据。这样创建的 ref 与其源属性保持同步:改变源属性的值将更新 ref 的值,反之亦然。toRefs将一个响应式对象多个属性转换为一个多个ref数据,这个普通对象的每个属性都是指向源对象相应属性的 ref。 )

条件渲染与列表渲染

  • v-if='表达式'只会在指令的表达式返回真值时才被渲染

  • 也可以使用 v-elsev-if 添加一个“else 区块”。

  • 一个 v-else 元素必须跟在一个 v-if 元素后面,否则它将不会被识别。

  • v-show 会在 DOM 渲染中保留该元素;v-show 仅切换了该元素上名为 display 的 CSS 属性。

  • 使用 v-for 指令基于一个数组来渲染一个列表

  • 使用 item in items 形式的特殊语法,其中 items 是源数据的数组,而 item 是迭代项的别名

  • 可选的第二个参数表示当前项的位置索引  v-for="(item, index) in items" 

计算属性computed

// 一个计算属性 refconst publishedBooksMessage = computed(() => {return author.books.length > 0 ? 'Yes' : 'No'})

数据监听器watch(watcheffect)

  • 当数据发生变化时需要执行相应的操作

  • 监听数据变化,当满足一定条件时触发相应操作

  • 在异步操作前或操作后需要执行相应的操作

<script type="module" setup>//引入模块import { ref,reactive,watch} from 'vue'let firstname=ref('')let lastname=reactive({name:''})let fullname=ref('')//监听一个ref响应式数据watch(firstname,(newValue,oldValue)=>{console.log(`${oldValue}变为${newValue}`)fullname.value=firstname.value+lastname.name})//监听reactive响应式数据的指定属性watch(()=>lastname.name,(newValue,oldValue)=>{console.log(`${oldValue}变为${newValue}`)fullname.value=firstname.value+lastname.name})//监听reactive响应式数据的所有属性(深度监视,一般不推荐)//deep:true 深度监视//immediate:true 深度监视在进入页面时立即执行一次watch(()=>lastname,(newValue,oldValue)=>{// 此时的newValue和oldValue一样,都是lastnameconsole.log(newValue)console.log(oldValue)fullname.value=firstname.value+lastname.name},{deep:true,immediate:false})//监听所有响应式数据watchEffect(()=>{//直接在内部使用监听属性即可!不用外部声明//也不需要,即时回调设置!默认初始化就加载!console.log(firstname.value)console.log(lastname.name)fullname.value=`${firstname.value}${lastname.name}`})
</script>

vue生命周期-Vue 组件实例在创建时都需要经历一系列的初始化步骤,比如设置好数据侦听,编译模板,挂载实例到 DOM,以及在数据改变时更新 DOM。在此过程中,它也会运行生命周期钩子的函数

  • onMounted() 注册一个回调函数,在组件挂载完成后执行。

  • onUpdated() 注册一个回调函数,在组件因为响应式状态变更而更新其 DOM 树之后调用。

  • onUnmounted() 注册一个回调函数,在组件实例被卸载之后调用。

  • onBeforeMount() 注册一个钩子,在组件被挂载之前被调用。

  • onBeforeUpdate() 注册一个钩子,在组件即将因为响应式状态变更而更新其 DOM 树之前调用。

  • onBeforeUnmount() 注册一个钩子,在组件实例被卸载之前调用。

组件之间传递数据:

父传子:

//父
<!-- 使用子组件,并且传递数据!通过设置属性传递数据 --><Son :message="message" :title="title"></Son>//子
import {defineProps} from 'vue'//声明父组件传递属性值,属性值要一致defineProps({message: String ,title: Number})

子传父:

//子
import {defineEmits} from 'vue'//1.定义要发送给父组件的方法,可以1或者多个let emites = defineEmits(['add','sub']);let data = ref(1);function sendMsgToParent(){//2.发父组件对应的方法,调用defineEmites对应的属性emites('add','add data!'+data.value)emites('sub','sub data!'+data. Value)}<button @click="sendMsgToParent">发送消息给父组件</button>//父//自定义接收,子组件传递数据方法! 参数为数据!const psub = (data) => {pdata.value = data;}<!-- 声明@事件名应该等于子模块对应事件名!调用方法可以是当前自定义!--><Son @add="padd" @sub="psub"></Son>

兄弟间传参:子传父-父传子

Vue3路由机制router-资源

promise-异步编程技术

(1)Promise对象代表一个异步操作,有三种状态:`Pending`(进行中)、`Resolved`(已完成,又称 Fulfilled)和`Rejected`(已失败)。只有异步操作的结果,可以决定当前是哪一种状态,任何其他操作都无法改变这个状态。

(2)一旦状态改变,就不会再变,任何时候都可以得到这个结果。Promise对象的状态改变,只有两种可能:从`Pending`变为`Resolved`和从`Pending`变为`Rejected`。

1.实例化promise对象,并且执行(类似Java创建线程对象,并且start)参数: resolve,reject随意命名,但是一般这么叫!参数: resolve,reject分别处理成功和失败的两个函数! 成功resolve(结果)  失败reject(结果)参数: 在function中调用这里两个方法,那么promise会处于两个不同的状态状态: promise有三个状态pending   正在运行resolved  内部调用了resolve方法rejected  内部调用了reject方法参数: 在第二步回调函数中就可以获取对应的结果 */let promise =new Promise(function(resolve,reject){//resolve("promise success")//reject("promise fail")// throw new Error("error message")})//2.获取回调函数结果  then在这里会等待promise中的运行结果,但是不会阻塞代码继续运行promise.then(function(value){console.log(`promise中执行了resolve:${value}`)},).catch(function(error){console.log(error)} )

async 标识异步函数

  1. async标识函数后,async函数的返回值会变成一个promise对象

  2. 如果函数内部返回的数据是一个非promise对象,async函数的结果会返回一个成功状态 promise对象

  3. 如果函数内部返回的是一个promise对象,则async函数返回的状态与结果由该对象决定

  4. 如果函数内部抛出的是一个异常,则async函数返回的是一个失败的promise对象

async function fun1(){...}let promise =fun1()promise.then(function(value){console.log("success:"+value)}).catch(function(value){console.log("fail:"+value)})

await-

  1. await右侧的表达式一般为一个promise对象,但是也可以是一个其他值

  2. 如果表达式是promise对象,await返回的是promise成功的值

  3. await会等右边的promise对象执行结束,然后再获取结果,后续代码也会等待await的执行

  4. 如果表达式是其他值,则直接返回该值

  5. await必须在async函数中

  6. 如果await右边的promise失败了,就会抛出异常,需要通过 try ... catch捕获处理

axios-资源

三.后端过滤器中设置跨域处理

@WebFilter("/*")
public class CrosFilter implements Filter {@Overridepublic void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {HttpServletRequest request = (HttpServletRequest) servletRequest;System.out.println(request.getMethod());HttpServletResponse response = (HttpServletResponse) servletResponse;response.setHeader("Access-Control-Allow-Origin", "*");response.setHeader("Access-Control-Allow-Methods", "POST, GET, PUT,OPTIONS, DELETE, HEAD");response.setHeader("Access-Control-Max-Age", "3600");response.setHeader("Access-Control-Allow-Headers", "access-control-allow-origin, authority, content-type, version-info, X-Requested-With");// 如果是跨域预检请求,则直接在此响应200业务码if(request.getMethod().equalsIgnoreCase("OPTIONS")){WebUtil.writeJson(response, Result.ok(null));}else{// 非预检请求,放行即可filterChain.doFilter(servletRequest, servletResponse);}}
}

通过pinia状态管理定义共享数据:

import {defineStore } from 'pinia'//定义数据并且对外暴露
// store就是定义共享状态的包装对象
// 内部包含四个属性: id 唯一标识 state 完整类型推理,推荐使用箭头函数 存放的数据 getters 类似属性计算,存储放对数据
// 操作的方法  actions 存储数据的复杂业务逻辑方法
// 理解: store类似Java中的实体类, id就是类名, state 就是装数据值的属性  getters就是get方法,actions就是对数据操作的其他方法
export const definedPerson = defineStore({id: 'personPinia', //必须唯一state:()=>{ // state中用于定义数据return {username:'张三',age:0,hobbies:['唱歌','跳舞']}},getters:{// 用于定义一些通过数据计算而得到结果的一些方法 一般在此处不做对数据的修改操作// getters中的方法可以当做属性值方式使用getHobbiesCount(){return this.hobbies.length},getAge(){return this.age}},actions:{ // 用于定义一些对数据修改的方法doubleAge(){this.age=this.age*2}}}
)----------------------------------------------------------------------import { createApp } from 'vue'
import App from './App.vue'
import router from './routers/router.js'
// 导pinia
import { createPinia } from 'pinia'
// 创建pinia对象
let pinia= createPinia()let app =createApp(App)
app.use(router)
// app中使用pinia功能
app.use(pinia) 
app.mount('#app')------------------------------------------------------------------------import { ref} from 'vue';import { definedPerson} from '../store/store';// 读取存储的数据let person= definedPerson()

四.element-plus:一个 Vue 3 UI 框架 | Element Plus  

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/471656.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

python工具方法 45 基于ffmpeg以面向对象多线程的方式实现实时推流

1、视频推流 参考基于ffmpeg模拟监控摄像头输出rtsp视频流并opencv播放 实现视频流的推流。 其基本操作就是,安装视频流推流服务器,ffmpeg,准备好要推流的视频。 命令如下所示:ffmpeg -re -stream_loop -1 -i 风景视频素材分享.flv -c copy -f rtsp rtsp://127.0.0.1:554/…

【matalab】基于Octave的信号处理与滤波分析案例

一、基于Octave的信号处理与滤波分析案例 GNU Octave是一款开源软件&#xff0c;类似于MATLAB&#xff0c;广泛用于数值计算和信号处理。 一个简单的信号处理与滤波分析案例&#xff0c;说明如何在Octave中生成一个有噪声的信号&#xff0c;并设计一个滤波器来去除噪声。 首…

【刷题记录】合并两个有序数组、移除元素

本系列博客为个人刷题思路分享&#xff0c;有需要借鉴即可。 1.题目链接&#xff1a; T1&#xff1a;LINK T2&#xff1a;LINK 2.详解思路&#xff1a; T1: 思路1&#xff1a;弄个新数组&#xff0c;比较两个数组中的值&#xff0c;哪个小就把哪个值放到新数组中。 分析1&a…

optee UTA加载

流程 动态TA按照存储位置的不同分为REE filesystem TA&#xff1a;存放在REE侧文件系统里的TA&#xff1b; Early TA&#xff1a;被嵌入到optee os里的在supplicant启动之前就可用了。 这里我们讲的是常规的存放在REE侧文件系统里的TA。 通过GP标准调用的与TA通信的命令(opens…

4.【Linux】进程控制(进程终止||进程等待||程序替换)

一.进程创建fork 见上篇文章 二.进程的终止 1.进程退出场景 1.代码运行完毕&#xff0c;结果正确&#xff0c;通过main函数退出码返回一般为0。 2.代码运行完毕&#xff0c;结果不正确&#xff0c;通过不同的退出码标识不同的错误原因。 3.代码异常终止&#xff08;信号&am…

模型 4R(关联、反应、关系、回报)理论

系列文章 分享 模型&#xff0c;了解更多&#x1f449; 模型_总纲目录。重在提升认知。以关系促营销。 1 4R(关联、反应、关系、回报)理论的应用 1.1 4R模型在小米客户关系管理中的应用 小米公司是一家以生产智能手机和消费电子产品而闻名的公司&#xff0c;它在客户关系管理…

2022年12月电子学会青少年软件编程 中小学生Python编程等级考试二级真题解析(判断题)

2022年12月Python编程等级考试二级真题解析 判断题(共10题,每题2分,共20分) 26、字典的元素可以通过键来访问,也可以通过索引(下标)来访问 答案:错 考点分析:考查字典相关知识,字典的元素只能通过键来访问,所以错误 27、Python中,可以通过索引来访问列表、字符串等…

常见的几种Web安全问题测试简介

Web项目比较常见的安全问题 1.XSS(CrossSite Script)跨站脚本攻击 XSS(CrossSite Script)跨站脚本攻击。它指的是恶意攻击者往Web 页面里插入恶意html代码&#xff0c;当用户浏览该页之时&#xff0c;嵌入其中Web 里面的html 代码会被执行&#xff0c;从而达到恶意用户的特殊…

现代化端口扫描工具RustScan

今天是大年初五&#xff0c;喜迎财神 &#xff0c;祝大家✔️顺风顺水 ✔️诸事如意 ✔️财源滚滚 ✔️大吉大利 顺便提一下&#xff0c;老苏的博客启用了新域名&#xff1a; https://laosu.tech 什么是 RustScan &#xff1f; RustScan 是一款现代化的端口扫描器。能快速找到端…

积分(一)——复化梯形积分(C++)

梯形积分 设f(x)在[a,b]上连续&#xff0c;若要计算其积分&#xff0c;则 ∫ a b f ( x ) d x F ( b ) − F ( a ) \int_a^b f(x)dx F(b) - F(a) ∫ab​f(x)dxF(b)−F(a) 其中F(x)为f(x)的原函数&#xff0c;但是计算机直接计算出该积分函数比较困难&#xff0c;因此需要近…

SolidWorks学习笔记——草图绘制的基本命令

目录 一、进入草图绘制 二、直线命令与删除命令 三、圆弧命令与矩形命令 四、槽口命令以及多边形命令 五、椭圆以及倒角命令 六、草图绘制中的剪裁命令 七、草图中的几何关系 八、草图绘制中的智能尺寸 九、从外部粘贴草图&#xff08;CAD&#xff09; 一、进入草图绘…

【蓝桥杯省赛真题23】python水仙花数 青少年组蓝桥杯比赛python编程省赛真题解析

目录 python水仙花数 一、题目要求 1、编程实现 2、输入输出